Skip to content

Commit 12d2bab

Browse files
authored
Merge pull request #655 from plotly/location-mode
location or lat/lon, not both
2 parents 9e8b3e0 + ade10aa commit 12d2bab

File tree

6 files changed

+164
-21
lines changed

6 files changed

+164
-21
lines changed

dev/App.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ const dataSources = {
3131
months: ['January', 'February', 'March', 'April', 'May', 'June'],
3232
colors: ['red', 'orange', 'yellow', 'green', 'blue', 'indigo'],
3333
'blue and red': ['blue', 'red'],
34+
countries: [
35+
'Angola',
36+
'Albania',
37+
'United Arab Emirates',
38+
'Argentina',
39+
'Armenia',
40+
'Australia',
41+
'Austria',
42+
'Azerbaijan',
43+
],
44+
'countries iso': ['AGO', 'ALB', 'ARE', 'ARG', 'ARM', 'AUS', 'AUT', 'AZE'],
45+
states: ['AL', 'AK', 'AZ', 'AR', 'CA', 'CO', 'CT', 'DE', 'FL', 'GA'],
3446
...tips,
3547
};
3648
const dataSourceOptions = Object.keys(dataSources).map(name => ({
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import React, {Fragment, Component} from 'react';
2+
import PropTypes from 'prop-types';
3+
import {connectToContainer} from 'lib';
4+
import Field from './Field';
5+
import Radio from './Radio';
6+
import {UnconnectedDropdown} from './Dropdown';
7+
import DataSelector from './DataSelector';
8+
9+
const LocationmodeVisible = connectToContainer(UnconnectedDropdown, {
10+
modifyPlotProps: (props, context, plotProps) => {
11+
if (!plotProps.fullValue) {
12+
plotProps.isVisible = true;
13+
plotProps.fullValue = plotProps.container.locationmode;
14+
return;
15+
}
16+
},
17+
});
18+
19+
class UnconnectedLocation extends Component {
20+
render() {
21+
const {localize: _} = this.context;
22+
23+
return (
24+
<Fragment>
25+
<DataSelector label={_('Locations')} attr="locations" />
26+
<LocationmodeVisible
27+
label={_('Location Format')}
28+
attr="locationmode"
29+
clearable={false}
30+
options={[
31+
{label: _('Country Names'), value: 'country names'},
32+
{label: _('Country Abbreviations (ISO-3)'), value: 'ISO-3'},
33+
{
34+
label: _('USA State Abbreviations (e.g. NY)'),
35+
value: 'USA-states',
36+
},
37+
]}
38+
/>
39+
</Fragment>
40+
);
41+
}
42+
}
43+
44+
UnconnectedLocation.propTypes = {
45+
attr: PropTypes.string,
46+
...Field.propTypes,
47+
};
48+
49+
UnconnectedLocation.contextTypes = {
50+
localize: PropTypes.func,
51+
updateContainer: PropTypes.func,
52+
};
53+
54+
const Location = connectToContainer(UnconnectedLocation);
55+
56+
class UnconnectedLocationSelector extends Component {
57+
constructor(props, context) {
58+
super(props, context);
59+
60+
this.state = {
61+
mode: props.container.locations ? 'location' : 'latlon',
62+
};
63+
64+
this.setMode = this.setMode.bind(this);
65+
}
66+
67+
componentWillMount() {
68+
this.setState({
69+
mode: this.props.container.locations ? 'location' : 'latlon',
70+
});
71+
}
72+
73+
setMode(mode) {
74+
this.setState({mode: mode});
75+
this.props.updateContainer(
76+
mode === 'latlon'
77+
? {
78+
locations: null,
79+
locationmode: null,
80+
locationssrc: null,
81+
locationmodesrc: null,
82+
}
83+
: {lat: null, lon: null, latsrc: null, lonsrc: null}
84+
);
85+
}
86+
87+
render() {
88+
const {mode} = this.state;
89+
const {
90+
localize: _,
91+
container: {type: type},
92+
} = this.context;
93+
94+
return type === 'scattergeo' ? (
95+
<Fragment>
96+
<Field {...this.props} attr={this.props.attr}>
97+
<Radio
98+
options={[
99+
{value: 'latlon', label: _('Lat/Lon')},
100+
{value: 'location', label: _('Location')},
101+
]}
102+
fullValue={mode}
103+
updatePlot={this.setMode}
104+
attr={this.props.attr}
105+
/>
106+
</Field>
107+
{mode === 'latlon' ? (
108+
<Fragment>
109+
<DataSelector label={_('Latitude')} attr="lat" />
110+
<DataSelector label={_('Longitude')} attr="lon" />
111+
</Fragment>
112+
) : (
113+
<Location attr="type" />
114+
)}
115+
</Fragment>
116+
) : type === 'choropleth' ? (
117+
<Location attr="type" />
118+
) : (
119+
''
120+
);
121+
}
122+
}
123+
124+
UnconnectedLocationSelector.propTypes = {
125+
fullValue: PropTypes.any,
126+
updatePlot: PropTypes.func,
127+
attr: PropTypes.string,
128+
...Field.propTypes,
129+
};
130+
131+
UnconnectedLocationSelector.contextTypes = {
132+
container: PropTypes.object,
133+
localize: PropTypes.func,
134+
updateContainer: PropTypes.func,
135+
};
136+
137+
export default connectToContainer(UnconnectedLocationSelector);

src/components/fields/derived.js

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -528,11 +528,14 @@ export const HoverInfo = connectToContainer(UnconnectedFlaglist, {
528528
}
529529

530530
if (container.type === 'scattergeo') {
531-
options = [
532-
{label: _('Longitude'), value: 'loc'},
533-
{label: _('Latitude'), value: 'lat'},
534-
{label: _('Location'), value: 'location'},
535-
];
531+
if (container.locations) {
532+
options = [{label: _('Location'), value: 'location'}];
533+
} else if (container.lat || container.lon) {
534+
options = [
535+
{label: _('Longitude'), value: 'lon'},
536+
{label: _('Latitude'), value: 'lat'},
537+
];
538+
}
536539
}
537540

538541
if (container.type === 'scattermapbox') {

src/components/fields/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import MarkerColor from './MarkerColor';
2626
import VisibilitySelect from './VisibilitySelect';
2727
import MultiColorPicker from './MultiColorPicker';
2828
import RectanglePositioner from './RectanglePositioner';
29+
import LocationSelector from './LocationSelector';
2930
import {
3031
AnnotationArrowRef,
3132
AnnotationRef,
@@ -102,4 +103,5 @@ export {
102103
MultiColorPicker,
103104
VisibilitySelect,
104105
RectanglePositioner,
106+
LocationSelector,
105107
};

src/components/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import {
4949
MultiColorPicker,
5050
VisibilitySelect,
5151
RectanglePositioner,
52+
LocationSelector,
5253
} from './fields';
5354

5455
import {
@@ -155,4 +156,5 @@ export {
155156
MultiColorPicker,
156157
VisibilitySelect,
157158
RectanglePositioner,
159+
LocationSelector,
158160
};

src/default_panels/GraphCreatePanel.js

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
TraceSelector,
1212
Numeric,
1313
TraceTypeSection,
14+
LocationSelector,
1415
} from '../components';
1516
import {
1617
HistogramInfoVertical,
@@ -22,11 +23,10 @@ const GraphCreatePanel = (props, {localize: _}) => {
2223
<TraceAccordion canAdd excludeFits>
2324
<TraceSelector label={_('Type')} attr="type" show />
2425

25-
<DataSelector label={_('Latitude')} attr="lat" />
26-
<DataSelector label={_('Longitude')} attr="lon" />
26+
<LocationSelector attr="type" />
27+
2728
<DataSelector label={_('Values')} attr="values" />
2829
<DataSelector label={_('Labels')} attr="labels" />
29-
<DataSelector label={_('Locations')} attr="locations" />
3030

3131
<DataSelector
3232
label={{
@@ -125,19 +125,6 @@ const GraphCreatePanel = (props, {localize: _}) => {
125125
<DataSelector label={_('Intensity')} attr="intensity" />
126126
<DataSelector label={_('Facecolor')} attr="facecolor" />
127127
<DataSelector label={_('Vertexcolor')} attr="vertexcolor" />
128-
<Dropdown
129-
label={_('Location Format')}
130-
attr="locationmode"
131-
clearable={false}
132-
options={[
133-
{label: _('Country Names'), value: 'country names'},
134-
{label: _('Country Abbreviations (ISO-3)'), value: 'ISO-3'},
135-
{
136-
label: _('USA State Abbreviations (e.g. NY)'),
137-
value: 'USA-states',
138-
},
139-
]}
140-
/>
141128
<Numeric label={_('Sum')} step={10} attr="sum" />
142129
<Radio
143130
label={_('Transpose')}

0 commit comments

Comments
 (0)