Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix discrepancies with legacy portal in station / history counts #83

Merged
merged 44 commits into from
Jan 5, 2022
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
536b98a
Modify date filtering
rod-glover Dec 20, 2021
ad9a349
Fix freq filtering
rod-glover Dec 21, 2021
9a2f805
Add logging to station-data-service
rod-glover Dec 21, 2021
f2b4c20
Add station counts to Station Filters tab
rod-glover Dec 21, 2021
c8ba910
Improve station metadata display
rod-glover Dec 21, 2021
c0da0aa
Improve station popup contents
rod-glover Dec 21, 2021
ceb479d
Add tooltip to station markers
rod-glover Dec 21, 2021
6d359d5
Factor out station-info functions
rod-glover Dec 22, 2021
29c7388
Improve station popup contents
rod-glover Dec 22, 2021
0487bcc
Draw a station marker for every history WIP
rod-glover Dec 22, 2021
fb3fc98
Extract more into station-info utils
rod-glover Dec 22, 2021
4d286a4
Refactor and improve StationTooltip
rod-glover Dec 22, 2021
767dc2c
Refactor and improve StationPopup
rod-glover Dec 22, 2021
c8b8d13
Refactor StationMarkers; add multi-location polygon
rod-glover Dec 22, 2021
902b9f0
Refactor StationMarkers; add multi-location polygon
rod-glover Dec 22, 2021
99879e7
Add local backend to .env
rod-glover Dec 22, 2021
a3066e8
Make station tooltip sticky
rod-glover Dec 22, 2021
3bdfee6
Curry some station-info fns
rod-glover Dec 22, 2021
dc00504
Fix sorting on StationMetadata table
rod-glover Dec 22, 2021
4ee1204
Fix layout of StationPopup
rod-glover Dec 23, 2021
7068d51
Add unionAll to utils/fp
rod-glover Dec 23, 2021
fc0ea55
Refactor station filtering; handle histories everywhere
rod-glover Dec 23, 2021
28a0776
Add timing module
rod-glover Dec 24, 2021
3ab6890
Apply timing to filtering fns; optimize some
rod-glover Dec 24, 2021
d83ca51
Apply timing to StationMap (not helpful)
rod-glover Dec 24, 2021
d4b886e
Comment out debug code
rod-glover Jan 4, 2022
2a252f9
Factor out StationData component
rod-glover Jan 4, 2022
cf18cb1
Make marker keys unique
rod-glover Jan 4, 2022
9ef1bf9
Don't hide unselected stations in map
rod-glover Jan 4, 2022
8cc447c
Tweak station marker code
rod-glover Jan 4, 2022
3ba06a5
Adjust VersionA portal for changes above
rod-glover Jan 4, 2022
781a98f
Add timing to ObservationCounts
rod-glover Jan 4, 2022
2701c30
Improve timing util
rod-glover Jan 4, 2022
1184f53
Fix map display of filtered vs selected stations
rod-glover Jan 5, 2022
0acbc97
Fix map display of filtered vs selected stations
rod-glover Jan 5, 2022
c36ee1e
Fix data download urls
rod-glover Jan 5, 2022
76299b0
Update component template to functional style
rod-glover Jan 5, 2022
7f63908
Add component SelectionCounts
rod-glover Jan 5, 2022
3484475
Add component SelectionCriteria
rod-glover Jan 5, 2022
db1a860
Use components SelectionCounts, SelectionCriteria
rod-glover Jan 5, 2022
a1b6252
Code cleanup: StationMetadata
rod-glover Jan 5, 2022
06fe051
Code cleanup: StationMap
rod-glover Jan 5, 2022
e4ed68f
Code cleanup: Separate utilities
rod-glover Jan 5, 2022
579adc9
Doc tweak
rod-glover Jan 5, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .env
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ REACT_APP_BASE_MAP=BC
#REACT_APP_BASE_MAP=YNWT
REACT_APP_BC_BASE_MAP_TILES_URL=https://services.pacificclimate.org/tiles/bc-albers-lite/{z}/{x}/{y}.png
REACT_APP_YNWT_BASE_MAP_TILES_URL=https://services.pacificclimate.org/tiles/yukon-albers-lite/{z}/{x}/{y}.png
REACT_APP_SDS_URL=http://docker-dev02.pcic.uvic.ca:30512
REACT_APP_SDS_URL=http://localhost:5000
#REACT_APP_SDS_URL=http://docker-dev02.pcic.uvic.ca:30512
REACT_APP_PDP_DATA_URL=https://services.pacificclimate.org/data
REACT_APP_DEFAULT_NETWORK_COLOR=#000000
# Values must be single-quoted to prevent errors created by processing dbl quotes.
Expand Down
11 changes: 11 additions & 0 deletions src/components/info/StationMetadata/StationMetadata.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,15 @@

.ReactTable .rt-thead {
overflow-y: scroll;
}

ul.compact {
padding-top: 0;
padding-bottom: 0;
padding-left: 15px;
padding-right: 0;
}

ul.compact li {
margin-left: 0;
}
232 changes: 150 additions & 82 deletions src/components/info/StationMetadata/StationMetadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,102 +3,170 @@
// passed into React Table.

import PropTypes from 'prop-types';
import React, { Component } from 'react';
import React from 'react';
import ReactTable from 'react-table';
import find from 'lodash/fp/find';

import flow from 'lodash/fp/flow';
import map from 'lodash/fp/map';

import FrequencySelector from '../../selectors/FrequencySelector';
import logger from '../../../logger';
import {
stationNetwork,
uniqStationFreqs,
uniqStationLocations,
uniqStationNames,
uniqStationObsPeriods,
uniqStationVariableNames
} from '../../../utils/station-info';

import 'react-table/react-table.css';
import './StationMetadata.css';


logger.configure({ active: true });

// TODO: Put these in a util module
const formatDate = d => d ? d.toISOString().substr(0,10) : 'unknown';

const lexCompare = (a, b) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for sorting in the metadata table?

Copy link
Contributor Author

@rod-glover rod-glover Dec 24, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is for sorting lists of things, e.g., lists of names, obs freqs. These arise because a station can have many histories, hence many names, obs freqs, etc. (These lists are reduced to their unique elements.) lexCompare implements standard lexicographic ordering for lists.

I plan to document all this in the code / README before I merge.

const n = Math.min(a.length, b.length);
for (let i = 0; i < n; i += 1) {
if (a[i] < b[i]) {
return -1;
}
if (a[i] > b[i]) {
return 1;
}
}
return a.length - b.length;
}

export default class StationMetadata extends Component {
static propTypes = {
stations: PropTypes.array,
allNetworks: PropTypes.array.isRequired,
};

render() {
const { stations, allNetworks, ...restProps } = this.props;

const columns = [
{
id: 'Network',
Header: 'Network',
minWidth: 80,
maxWidth: 100,
accessor: station => {
const network = find({ uri: station.network_uri })(allNetworks);
return network ? network.name : '?';
},
},
{
id: 'Native ID',
Header: 'Native ID',
minWidth: 80,
maxWidth: 100,
accessor: 'native_id'
},
{
id: 'Station Name',
Header: 'Station Name',
minWidth: 120,
maxWidth: 200,
accessor: station => station.histories[0].station_name,
function StationMetadata({
stations, allNetworks, allVariables, ...restProps
}) {
const columns = [
{
id: 'Network',
Header: 'Network',
minWidth: 80,
maxWidth: 100,
accessor: station => {
const network = stationNetwork(allNetworks, station);
return network ? network.name : '?';
},
{
id: 'Location',
Header: 'Location',
minWidth: 120,
maxWidth: 200,
accessor: station => {
const hx = station.histories[0];
return (
<div>
{-hx.lon} W <br/>
{hx.lat} N <br/>
Elev. {hx.elevation} m
</div>
);
}
},
{
id: 'Record',
Header: 'Record',
minWidth: 100,
maxWidth: 200,
// accessor: station => 'record',
accessor: station => {
return (
<div>
{formatDate(station.min_obs_time)} to <br/>
{formatDate(station.max_obs_time)}
</div>
)}
},
{
minWidth: 80,
maxWidth: 100,
id: 'Obs Freq',
Header: 'Obs Freq',
accessor: station =>
FrequencySelector.valueToLabel(station.histories[0].freq),
},
];
},
{
id: 'Native ID',
Header: 'Native ID',
minWidth: 80,
maxWidth: 100,
accessor: 'native_id'
},
{
id: 'Unique Names',
Header: 'Unique Names',
minWidth: 120,
maxWidth: 200,
accessor: uniqStationNames,
sortMethod: lexCompare,
Cell: row => (
<ul className={"compact"}>
{map(name => (<li>{name}</li>), row.value)}
</ul>
),
},
{
id: 'Unique Locations',
Header: 'Unique Locations',
minWidth: 120,
maxWidth: 200,
sortable: false,
accessor: uniqStationLocations,
Cell: row => (
<ul className={"compact"}>
{
map(loc => (
<li>
{-loc.lon} W <br/>
{loc.lat} N <br/>
Elev. {loc.elevation} m
</li>
), row.value)
}
</ul>
),
},
{
id: 'Unique Records',
Header: 'Unique Records',
minWidth: 100,
maxWidth: 100,
sortable: false,
accessor: uniqStationObsPeriods,
Cell: row => (
<ul className={"compact"}>
{
map(period => (
<li>
{formatDate(period.min_obs_time)} to <br/>
{formatDate(period.max_obs_time)}
</li>
), row.value)
}
</ul>
),
},
{
minWidth: 80,
maxWidth: 100,
id: 'Uniq Obs Freqs',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exactly does the "Uniq" in this label refer to?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stations can have multiple histories, hence multiple freqs; these are reduced to their unique elements (see also comment above).

Header: 'Uniq Obs Freqs',
accessor: flow(uniqStationFreqs, map(FrequencySelector.valueToLabel)),
sortMethod: lexCompare,
Cell: row => (
<ul className={"compact"}>
{map(freq => (<li>{freq}</li>), row.value)}
</ul>
),
},
{
minWidth: 100,
maxWidth: 250,
id: 'Variables',
Header: 'Variables',
accessor: uniqStationVariableNames(allVariables),
sortable: false,
Cell: row => (
<ul className={"compact"}>
{map(name => (<li>{name}</li>), row.value)}
</ul>
),
},
{
id: '# Hx',
Header: '# Hx',
minWidth: 30,
maxWidth: 30,
accessor: station => station.histories.length,
},
];

return (
<ReactTable
data={stations}
columns={columns}
defaultPageSize={100}
{...restProps}
/>
);
}
return (
<ReactTable
data={stations}
columns={columns}
defaultPageSize={100}
{...restProps}
/>
);
}

StationMetadata.propTypes = {
stations: PropTypes.array,
allNetworks: PropTypes.array.isRequired,
allVariables: PropTypes.array.isRequired,
};

export default StationMetadata;
12 changes: 11 additions & 1 deletion src/components/main/VersionA/VersionA.js
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,15 @@ class Portal extends Component {
<Panel.Body>
<Tabs defaultActiveKey={'Filters'} className={css.mainTabs}>
<Tab eventKey={'Filters'} title={'Station Filters'}>
<Row>
<Col lg={12} md={12} sm={12}>
<p>
<b>{filteredStations?.length}</b> stations selected
of <b>{this.state.allStations?.length}</b> (see
Station Data tab for details)
</p>
</Col>
</Row>
<Row>
<Col lg={6} md={6} sm={6}>
{/*<Button bsSize={'small'} onClick={this.handleClickAll}>Select all criteria</Button>*/}
Expand All @@ -241,7 +250,7 @@ class Portal extends Component {
label={'Start Date'}
/>
</Col>
<Col lg={6} md={6} sm={6}>
<Col lg={6} md={6} sm={6}>
<DateSelector
value={this.state.endDate}
onChange={this.handleChangeEndDate}
Expand Down Expand Up @@ -307,6 +316,7 @@ class Portal extends Component {
<StationMetadata
stations={filteredStations}
allNetworks={this.state.allNetworks}
allVariables={this.state.allVariables}
/>

</Tab>
Expand Down
Loading