@cdc/map 4.22.10-alpha.1 → 4.22.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/cdcmap.js +10 -10
  2. package/examples/private/atsdr.json +19 -29
  3. package/examples/private/atsdr_new.json +1 -1
  4. package/examples/private/bubble.json +282 -284
  5. package/examples/private/city-state.json +427 -427
  6. package/examples/private/city-state2.json +433 -433
  7. package/examples/private/cty-issue.json +42765 -42768
  8. package/examples/private/default-usa.json +2 -5
  9. package/examples/private/default-world-data.json +1443 -1443
  10. package/examples/private/default.json +965 -965
  11. package/examples/private/diff.json +226 -0
  12. package/examples/private/filters.json +1 -0
  13. package/examples/private/legend-issue.json +3271 -1
  14. package/examples/private/map-issue.json +166 -0
  15. package/examples/private/map-rounding-error.json +42756 -42759
  16. package/examples/private/mdx.json +209 -209
  17. package/examples/private/monkeypox.json +375 -375
  18. package/examples/private/regions.json +51 -51
  19. package/examples/private/wcmsrd-13881-data.json +2856 -2856
  20. package/examples/private/wcmsrd-13881.json +5818 -5822
  21. package/examples/private/wcmsrd-14492-data.json +291 -291
  22. package/examples/private/wcmsrd-14492.json +103 -113
  23. package/examples/private/wcmsrd-test.json +264 -267
  24. package/examples/private/world.json +1579 -1579
  25. package/examples/private/worldmap.json +1489 -1489
  26. package/package.json +3 -3
  27. package/src/CdcMap.js +231 -315
  28. package/src/components/BubbleList.js +199 -240
  29. package/src/components/CityList.js +50 -96
  30. package/src/components/CountyMap.js +511 -600
  31. package/src/components/DataTable.js +218 -253
  32. package/src/components/EditorPanel.js +2338 -2551
  33. package/src/components/Geo.js +4 -14
  34. package/src/components/Modal.js +13 -23
  35. package/src/components/NavigationMenu.js +43 -39
  36. package/src/components/Sidebar.js +83 -93
  37. package/src/components/SingleStateMap.js +95 -151
  38. package/src/components/UsaMap.js +165 -214
  39. package/src/components/UsaRegionMap.js +122 -160
  40. package/src/components/WorldMap.js +96 -179
  41. package/src/components/ZoomableGroup.js +6 -26
  42. package/src/data/initial-state.js +1 -0
  43. package/src/hooks/useActiveElement.js +13 -13
  44. package/src/hooks/useColorPalette.ts +66 -74
  45. package/src/hooks/useZoomPan.js +22 -23
  46. package/src/index.html +1 -2
  47. package/src/scss/sidebar.scss +22 -0
@@ -1,244 +1,203 @@
1
- import React, {memo, useState, useEffect} from 'react'
2
- import { scaleLinear } from 'd3-scale';
3
- import { countryCoordinates } from '../data/country-coordinates';
4
- import stateCoordinates from '../data/state-coordinates';
1
+ import React, { memo, useState, useEffect } from 'react'
2
+ import { scaleLinear } from 'd3-scale'
3
+ import { countryCoordinates } from '../data/country-coordinates'
4
+ import stateCoordinates from '../data/state-coordinates'
5
5
  import ReactTooltip from 'react-tooltip'
6
6
 
7
- export const BubbleList = (
8
- {
9
- data: dataImport,
10
- state,
11
- projection,
12
- applyLegendToRow,
13
- applyTooltipsToGeo,
14
- handleCircleClick,
15
- runtimeData,
16
- displayGeoName
17
- }) => {
18
-
19
- useEffect(() => {
20
- ReactTooltip.hide()
21
- }, [runtimeData]);
22
-
23
- const maxDataValue = Math.max(...dataImport.map(d => d[state.columns.primary.name]))
24
- const hasBubblesWithZeroOnMap = state.visual.showBubbleZeros ? 0 : 1;
25
- // sort runtime data. Smaller bubbles should appear on top.
26
- const sortedRuntimeData = Object.values(runtimeData).sort((a, b) => a[state.columns.primary.name] < b[state.columns.primary.name] ? 1 : -1 )
27
- if(!sortedRuntimeData) return;
28
-
29
- const clickTolerance = 10;
30
-
31
- // Set bubble sizes
32
- var size = scaleLinear()
33
- .domain([hasBubblesWithZeroOnMap, maxDataValue])
34
- .range([state.visual.minBubbleSize, state.visual.maxBubbleSize])
35
-
36
- // Start looping through the countries to create the bubbles.
37
- if(state.general.geoType === 'world') {
38
- const countries = sortedRuntimeData && sortedRuntimeData.map( (country, index) => {
39
-
40
- let coordinates = countryCoordinates[country.uid]
41
-
42
- if(!coordinates) return true;
43
-
44
- const countryName = displayGeoName(country[state.columns.geo.name]);
45
- const toolTip = applyTooltipsToGeo(countryName, country);
46
- const legendColors = applyLegendToRow(country);
47
-
48
- let primaryKey = state.columns.primary.name
49
- if ((Math.floor(Number(size(country[primaryKey]))) === 0 || country[primaryKey] === "") && !state.visual.showBubbleZeros) return;
50
-
51
- let transform = `translate(${projection([coordinates[1], coordinates[0]])})`
52
-
53
- let pointerX, pointerY;
54
-
55
- if( !projection(coordinates) ) return true;
56
-
57
- const circle = (
58
- <>
59
- <circle
60
- key={`circle-${countryName.replace(' ', '')}`}
61
- data-tip={toolTip}
62
- data-for="tooltip"
63
- className={`bubble country--${countryName}`}
64
- cx={ Number(projection(coordinates[1], coordinates[0])[0]) || 0 } // || 0 handles error on loads where the data isn't ready
65
- cy={ Number(projection(coordinates[1], coordinates[0])[1]) || 0 }
66
- r={ Number(size(country[primaryKey])) }
67
- fill={legendColors[0] }
68
- stroke={legendColors[0]}
69
- strokeWidth={1.25}
70
- fillOpacity={.4}
71
- onPointerDown={(e) => {
72
- pointerX = e.clientX;
73
- pointerY = e.clientY;
74
- }}
75
- onPointerUp={(e) => {
76
- if(pointerX && pointerY &&
77
- e.clientX > (pointerX - clickTolerance) &&
78
- e.clientX < (pointerX + clickTolerance) &&
79
- e.clientY > (pointerY - clickTolerance) &&
80
- e.clientY < (pointerY + clickTolerance)
81
- ){
82
- handleCircleClick(country)
83
- pointerX = undefined;
84
- pointerY = undefined;
85
- }
86
- }}
87
- transform={transform}
88
- style={{ transition: 'all .25s ease-in-out', cursor: "pointer" }}
89
- />
90
-
91
- {state.visual.extraBubbleBorder &&
92
- <circle
93
- key={`circle-${countryName.replace(' ', '')}`}
94
- data-tip={toolTip}
95
- data-for="tooltip"
96
- className="bubble"
97
- cx={ Number(projection(coordinates[1], coordinates[0])[0]) || 0 } // || 0 handles error on loads where the data isn't ready
98
- cy={ Number(projection(coordinates[1], coordinates[0])[1]) || 0 }
99
- r={ Number(size(country[primaryKey])) + 1 }
100
- fill={ "transparent" }
101
- stroke={ "white" }
102
- strokeWidth={.5}
103
- onPointerDown={(e) => {
104
- pointerX = e.clientX;
105
- pointerY = e.clientY;
106
- }}
107
- onPointerUp={(e) => {
108
- if(pointerX && pointerY &&
109
- e.clientX > (pointerX - clickTolerance) &&
110
- e.clientX < (pointerX + clickTolerance) &&
111
- e.clientY > (pointerY - clickTolerance) &&
112
- e.clientY < (pointerY + clickTolerance)
113
- ){
114
- handleCircleClick(country)
115
- pointerX = undefined;
116
- pointerY = undefined;
117
- }
118
- }}
119
- transform={transform}
120
- style={{ transition: 'all .25s ease-in-out', cursor: "pointer" }}
121
- />
122
- }
123
- </>
124
- );
125
-
126
-
127
- return (
128
- <g key={`group-${countryName.replace(' ', '')}`}>
129
- {circle}
130
- </g>
131
- )
132
- })
133
- return countries;
134
- }
135
-
136
- if(state.general.geoType === 'us') {
137
- const bubbles = sortedRuntimeData && sortedRuntimeData.map( (item, index) => {
138
- let stateData = stateCoordinates[item.uid]
139
- let primaryKey = state?.columns?.primary?.name
140
- if ( Number(size(item[primaryKey])) === 0) return;
141
-
142
- if (item[primaryKey] === null) item[primaryKey] = ""
143
-
144
- // Return if hiding zeros on the map
145
- if( (Math.floor(Number(size(item[primaryKey]))) === 0 || item[primaryKey] === "" )&& !state.visual.showBubbleZeros ) return;
146
-
147
- if(!stateData) return true;
148
- let longitude = Number( stateData.Longitude);
149
- let latitude = Number( stateData.Latitude);
150
- let coordinates = [longitude, latitude]
151
- //console.log('projection', projection([longitude, latitude]))
152
- let stateName = stateData.Name;
153
- if (!coordinates) return true;
154
-
155
- stateName = displayGeoName(stateName);
156
- const toolTip = applyTooltipsToGeo(stateName, item);
157
- const legendColors = applyLegendToRow(item);
158
-
159
-
160
- let transform = `translate(${projection([coordinates[1], coordinates[0]])})`
161
-
162
- if ( !projection(coordinates) ) return true;
163
-
164
- let pointerX, pointerY;
165
- const circle = (
166
- <>
167
- <circle
168
- key={`circle-${stateName.replace(' ', '')}`}
169
- data-tip={toolTip}
170
- data-for="tooltip"
171
- className="bubble"
172
- cx={projection(coordinates)[0] || 0} // || 0 handles error on loads where the data isn't ready
173
- cy={projection(coordinates)[1] || 0}
174
- r={Number(size(item[primaryKey]))}
175
- fill={legendColors[0]}
176
- stroke={legendColors[0]}
177
- strokeWidth={1.25}
178
- fillOpacity={.4}
179
- onPointerDown={(e) => {
180
- pointerX = e.clientX;
181
- pointerY = e.clientY;
182
- }}
183
- onPointerUp={(e) => {
184
- if (pointerX && pointerY &&
185
- e.clientX > (pointerX - clickTolerance) &&
186
- e.clientX < (pointerX + clickTolerance) &&
187
- e.clientY > (pointerY - clickTolerance) &&
188
- e.clientY < (pointerY + clickTolerance)
189
- ) {
190
- handleCircleClick(state)
191
- pointerX = undefined;
192
- pointerY = undefined;
193
- }
194
- }}
195
- transform={transform}
196
- style={{ transition: 'all .25s ease-in-out', cursor: "pointer" }}
197
- />
198
- { state.visual.extraBubbleBorder &&
199
- <circle
200
- key={`circle-${stateName.replace(' ', '')}`}
201
- data-tip={toolTip}
202
- data-for="tooltip"
203
- className="bubble"
204
- cx={ projection(coordinates)[0] || 0 } // || 0 handles error on loads where the data isn't ready
205
- cy={ projection(coordinates)[1] || 0 }
206
- r={ Number(size(item[primaryKey])) + 1 }
207
- fill={"transparent"}
208
- stroke={"white"}
209
- strokeWidth={.5}
210
- fillOpacity={.4}
211
- onPointerDown={(e) => {
212
- pointerX = e.clientX;
213
- pointerY = e.clientY;
214
- }}
215
- onPointerUp={(e) => {
216
- if (pointerX && pointerY &&
217
- e.clientX > (pointerX - clickTolerance) &&
218
- e.clientX < (pointerX + clickTolerance) &&
219
- e.clientY > (pointerY - clickTolerance) &&
220
- e.clientY < (pointerY + clickTolerance)
221
- ) {
222
- handleCircleClick(state)
223
- pointerX = undefined;
224
- pointerY = undefined;
225
- }
226
- }}
227
- transform={transform}
228
- style={{ transition: 'all .25s ease-in-out', cursor: "pointer" }}
229
- />
230
- }
231
- </>
232
- );
233
-
234
-
235
- return (
236
- <g key={`group-${stateName.replace(' ', '')}`}>
237
- {circle}
238
- </g>
239
- )
240
- })
241
- return bubbles;
242
- }
7
+ export const BubbleList = ({ data: dataImport, state, projection, applyLegendToRow, applyTooltipsToGeo, handleCircleClick, runtimeData, displayGeoName }) => {
8
+ useEffect(() => {
9
+ ReactTooltip.hide()
10
+ }, [runtimeData])
11
+
12
+ const maxDataValue = Math.max(...dataImport.map(d => d[state.columns.primary.name]))
13
+ const hasBubblesWithZeroOnMap = state.visual.showBubbleZeros ? 0 : 1
14
+ // sort runtime data. Smaller bubbles should appear on top.
15
+ const sortedRuntimeData = Object.values(runtimeData).sort((a, b) => (a[state.columns.primary.name] < b[state.columns.primary.name] ? 1 : -1))
16
+ if (!sortedRuntimeData) return
17
+
18
+ const clickTolerance = 10
19
+
20
+ // Set bubble sizes
21
+ var size = scaleLinear().domain([hasBubblesWithZeroOnMap, maxDataValue]).range([state.visual.minBubbleSize, state.visual.maxBubbleSize])
22
+
23
+ // Start looping through the countries to create the bubbles.
24
+ if (state.general.geoType === 'world') {
25
+ const countries =
26
+ sortedRuntimeData &&
27
+ sortedRuntimeData.map((country, index) => {
28
+ let coordinates = countryCoordinates[country.uid]
29
+
30
+ if (!coordinates) return true
31
+
32
+ const countryName = displayGeoName(country[state.columns.geo.name])
33
+ const toolTip = applyTooltipsToGeo(countryName, country)
34
+ const legendColors = applyLegendToRow(country)
35
+
36
+ let primaryKey = state.columns.primary.name
37
+ if ((Math.floor(Number(size(country[primaryKey]))) === 0 || country[primaryKey] === '') && !state.visual.showBubbleZeros) return
38
+
39
+ let transform = `translate(${projection([coordinates[1], coordinates[0]])})`
40
+
41
+ let pointerX, pointerY
42
+
43
+ if (!projection(coordinates)) return true
44
+
45
+ const circle = (
46
+ <>
47
+ <circle
48
+ key={`circle-${countryName.replace(' ', '')}`}
49
+ data-tip={toolTip}
50
+ data-for='tooltip'
51
+ className={`bubble country--${countryName}`}
52
+ cx={Number(projection(coordinates[1], coordinates[0])[0]) || 0} // || 0 handles error on loads where the data isn't ready
53
+ cy={Number(projection(coordinates[1], coordinates[0])[1]) || 0}
54
+ r={Number(size(country[primaryKey]))}
55
+ fill={legendColors[0]}
56
+ stroke={legendColors[0]}
57
+ strokeWidth={1.25}
58
+ fillOpacity={0.4}
59
+ onPointerDown={e => {
60
+ pointerX = e.clientX
61
+ pointerY = e.clientY
62
+ }}
63
+ onPointerUp={e => {
64
+ if (pointerX && pointerY && e.clientX > pointerX - clickTolerance && e.clientX < pointerX + clickTolerance && e.clientY > pointerY - clickTolerance && e.clientY < pointerY + clickTolerance) {
65
+ handleCircleClick(country)
66
+ pointerX = undefined
67
+ pointerY = undefined
68
+ }
69
+ }}
70
+ transform={transform}
71
+ style={{ transition: 'all .25s ease-in-out', cursor: 'pointer' }}
72
+ />
73
+
74
+ {state.visual.extraBubbleBorder && (
75
+ <circle
76
+ key={`circle-${countryName.replace(' ', '')}`}
77
+ data-tip={toolTip}
78
+ data-for='tooltip'
79
+ className='bubble'
80
+ cx={Number(projection(coordinates[1], coordinates[0])[0]) || 0} // || 0 handles error on loads where the data isn't ready
81
+ cy={Number(projection(coordinates[1], coordinates[0])[1]) || 0}
82
+ r={Number(size(country[primaryKey])) + 1}
83
+ fill={'transparent'}
84
+ stroke={'white'}
85
+ strokeWidth={0.5}
86
+ onPointerDown={e => {
87
+ pointerX = e.clientX
88
+ pointerY = e.clientY
89
+ }}
90
+ onPointerUp={e => {
91
+ if (pointerX && pointerY && e.clientX > pointerX - clickTolerance && e.clientX < pointerX + clickTolerance && e.clientY > pointerY - clickTolerance && e.clientY < pointerY + clickTolerance) {
92
+ handleCircleClick(country)
93
+ pointerX = undefined
94
+ pointerY = undefined
95
+ }
96
+ }}
97
+ transform={transform}
98
+ style={{ transition: 'all .25s ease-in-out', cursor: 'pointer' }}
99
+ />
100
+ )}
101
+ </>
102
+ )
103
+
104
+ return <g key={`group-${countryName.replace(' ', '')}`}>{circle}</g>
105
+ })
106
+ return countries
107
+ }
108
+
109
+ if (state.general.geoType === 'us') {
110
+ const bubbles =
111
+ sortedRuntimeData &&
112
+ sortedRuntimeData.map((item, index) => {
113
+ let stateData = stateCoordinates[item.uid]
114
+ let primaryKey = state?.columns?.primary?.name
115
+ if (Number(size(item[primaryKey])) === 0) return
116
+
117
+ if (item[primaryKey] === null) item[primaryKey] = ''
118
+
119
+ // Return if hiding zeros on the map
120
+ if ((Math.floor(Number(size(item[primaryKey]))) === 0 || item[primaryKey] === '') && !state.visual.showBubbleZeros) return
121
+
122
+ if (!stateData) return true
123
+ let longitude = Number(stateData.Longitude)
124
+ let latitude = Number(stateData.Latitude)
125
+ let coordinates = [longitude, latitude]
126
+ //console.log('projection', projection([longitude, latitude]))
127
+ let stateName = stateData.Name
128
+ if (!coordinates) return true
129
+
130
+ stateName = displayGeoName(stateName)
131
+ const toolTip = applyTooltipsToGeo(stateName, item)
132
+ const legendColors = applyLegendToRow(item)
133
+
134
+ let transform = `translate(${projection([coordinates[1], coordinates[0]])})`
135
+
136
+ if (!projection(coordinates)) return true
137
+
138
+ let pointerX, pointerY
139
+ const circle = (
140
+ <>
141
+ <circle
142
+ key={`circle-${stateName.replace(' ', '')}`}
143
+ data-tip={toolTip}
144
+ data-for='tooltip'
145
+ className='bubble'
146
+ cx={projection(coordinates)[0] || 0} // || 0 handles error on loads where the data isn't ready
147
+ cy={projection(coordinates)[1] || 0}
148
+ r={Number(size(item[primaryKey]))}
149
+ fill={legendColors[0]}
150
+ stroke={legendColors[0]}
151
+ strokeWidth={1.25}
152
+ fillOpacity={0.4}
153
+ onPointerDown={e => {
154
+ pointerX = e.clientX
155
+ pointerY = e.clientY
156
+ }}
157
+ onPointerUp={e => {
158
+ if (pointerX && pointerY && e.clientX > pointerX - clickTolerance && e.clientX < pointerX + clickTolerance && e.clientY > pointerY - clickTolerance && e.clientY < pointerY + clickTolerance) {
159
+ handleCircleClick(state)
160
+ pointerX = undefined
161
+ pointerY = undefined
162
+ }
163
+ }}
164
+ transform={transform}
165
+ style={{ transition: 'all .25s ease-in-out', cursor: 'pointer' }}
166
+ />
167
+ {state.visual.extraBubbleBorder && (
168
+ <circle
169
+ key={`circle-${stateName.replace(' ', '')}`}
170
+ data-tip={toolTip}
171
+ data-for='tooltip'
172
+ className='bubble'
173
+ cx={projection(coordinates)[0] || 0} // || 0 handles error on loads where the data isn't ready
174
+ cy={projection(coordinates)[1] || 0}
175
+ r={Number(size(item[primaryKey])) + 1}
176
+ fill={'transparent'}
177
+ stroke={'white'}
178
+ strokeWidth={0.5}
179
+ fillOpacity={0.4}
180
+ onPointerDown={e => {
181
+ pointerX = e.clientX
182
+ pointerY = e.clientY
183
+ }}
184
+ onPointerUp={e => {
185
+ if (pointerX && pointerY && e.clientX > pointerX - clickTolerance && e.clientX < pointerX + clickTolerance && e.clientY > pointerY - clickTolerance && e.clientY < pointerY + clickTolerance) {
186
+ handleCircleClick(state)
187
+ pointerX = undefined
188
+ pointerY = undefined
189
+ }
190
+ }}
191
+ transform={transform}
192
+ style={{ transition: 'all .25s ease-in-out', cursor: 'pointer' }}
193
+ />
194
+ )}
195
+ </>
196
+ )
197
+
198
+ return <g key={`group-${stateName.replace(' ', '')}`}>{circle}</g>
199
+ })
200
+ return bubbles
201
+ }
243
202
  }
244
203
  export default BubbleList
@@ -1,76 +1,59 @@
1
- import React, { useState, useEffect, useContext } from 'react';
1
+ import React, { useState, useEffect, useContext } from 'react'
2
2
  /** @jsx jsx */
3
3
  import { jsx } from '@emotion/react'
4
- import { supportedCities } from '../data/supported-geos';
5
- import { scaleLinear } from 'd3-scale';
6
- import ReactTooltip from 'react-tooltip';
7
-
8
- const CityList = (({
9
- data,
10
- state,
11
- geoClickHandler,
12
- applyTooltipsToGeo,
13
- displayGeoName,
14
- applyLegendToRow,
15
- projection,
16
- titleCase,
17
- setSharedFilterValue,
18
- isFilterValueSupported,
19
- isGeoCodeMap
20
- }) => {
21
-
22
- const [citiesData, setCitiesData] = useState({});
4
+ import { supportedCities } from '../data/supported-geos'
5
+ import { scaleLinear } from 'd3-scale'
6
+ import ReactTooltip from 'react-tooltip'
7
+
8
+ const CityList = ({ data, state, geoClickHandler, applyTooltipsToGeo, displayGeoName, applyLegendToRow, projection, titleCase, setSharedFilterValue, isFilterValueSupported, isGeoCodeMap }) => {
9
+ const [citiesData, setCitiesData] = useState({})
23
10
 
24
11
  useEffect(() => {
25
12
  ReactTooltip.rebuild()
26
- });
13
+ })
27
14
 
28
15
  useEffect(() => {
29
- if(!isGeoCodeMap) {
30
- const citiesList = Object.keys(data).filter((item) => Object.keys(supportedCities).includes(item));
31
-
32
- const citiesDictionary = {};
33
-
34
- citiesList.map((city) => citiesDictionary[city] = data[city]);
35
-
36
- setCitiesData(citiesDictionary);
16
+ if (!isGeoCodeMap) {
17
+ const citiesList = Object.keys(data).filter(item => Object.keys(supportedCities).includes(item))
18
+
19
+ const citiesDictionary = {}
20
+
21
+ citiesList.map(city => (citiesDictionary[city] = data[city]))
22
+
23
+ setCitiesData(citiesDictionary)
37
24
  } else {
38
- const citiesDictionary = {};
39
- state.data.map(city => citiesDictionary[city[state.columns.geo.name]] = city)
40
- setCitiesData(citiesDictionary);
25
+ const citiesDictionary = {}
26
+ state.data.map(city => (citiesDictionary[city[state.columns.geo.name]] = city))
27
+ setCitiesData(citiesDictionary)
41
28
  }
42
- }, [data, state.data]);
29
+ }, [data, state.data])
43
30
 
44
31
  if (state.general.type === 'bubble') {
45
32
  const maxDataValue = Math.max(...state.data.map(d => d[state.columns.primary.name]))
46
- const sortedRuntimeData = Object.values(data).sort((a, b) => a[state.columns.primary.name] < b[state.columns.primary.name] ? 1 : -1)
47
- if (!sortedRuntimeData) return;
33
+ const sortedRuntimeData = Object.values(data).sort((a, b) => (a[state.columns.primary.name] < b[state.columns.primary.name] ? 1 : -1))
34
+ if (!sortedRuntimeData) return
48
35
 
49
36
  // Set bubble sizes
50
- var size = scaleLinear()
51
- .domain([1, maxDataValue])
52
- .range([state.visual.minBubbleSize, state.visual.maxBubbleSize])
53
-
37
+ var size = scaleLinear().domain([1, maxDataValue]).range([state.visual.minBubbleSize, state.visual.maxBubbleSize])
54
38
  }
55
- let cityList = isGeoCodeMap ? Object.keys(citiesData).filter((c) => undefined !== c) : Object.keys(citiesData).filter((c) => undefined !== data[c]);
56
- if(!cityList) return true;
39
+ let cityList = isGeoCodeMap ? Object.keys(citiesData).filter(c => undefined !== c) : Object.keys(citiesData).filter(c => undefined !== data[c])
40
+ if (!cityList) return true
57
41
 
58
42
  // Cities output
59
43
  const cities = cityList.map((city, i) => {
44
+ const geoData = isGeoCodeMap ? state.data.filter(item => city === item[state.columns.geo.name])[0] : data[city]
60
45
 
61
- const geoData = isGeoCodeMap ? state.data.filter(item => city === item[state.columns.geo.name])[0] : data[city];
62
-
63
- const cityDisplayName = isGeoCodeMap ? city : titleCase( displayGeoName(city) );
46
+ const cityDisplayName = isGeoCodeMap ? city : titleCase(displayGeoName(city))
64
47
 
65
- const legendColors = (isGeoCodeMap && geoData) ? applyLegendToRow(geoData) : data[city] ? applyLegendToRow(data[city]) : false;
48
+ const legendColors = isGeoCodeMap && geoData ? applyLegendToRow(geoData) : data[city] ? applyLegendToRow(data[city]) : false
66
49
 
67
50
  if (legendColors === false) {
68
- return true;
51
+ return true
69
52
  }
70
53
 
71
54
  const styles = {
72
55
  fill: legendColors[0],
73
- opacity: setSharedFilterValue && isFilterValueSupported && data[city][state.columns.geo.name] !== setSharedFilterValue ? .5 : 1,
56
+ opacity: setSharedFilterValue && isFilterValueSupported && data[city][state.columns.geo.name] !== setSharedFilterValue ? 0.5 : 1,
74
57
  stroke: setSharedFilterValue && isFilterValueSupported && data[city][state.columns.geo.name] === setSharedFilterValue ? 'rgba(0, 0, 0, 1)' : 'rgba(0, 0, 0, 0.4)',
75
58
  '&:hover': {
76
59
  fill: legendColors[1],
@@ -80,54 +63,30 @@ const CityList = (({
80
63
  fill: legendColors[2],
81
64
  outline: 0
82
65
  }
83
- };
84
-
85
-
66
+ }
86
67
 
87
- const toolTip = applyTooltipsToGeo(cityDisplayName, data[city]);
68
+ const toolTip = applyTooltipsToGeo(cityDisplayName, data[city])
88
69
 
89
70
  // If we need to add a cursor pointer
90
- if ((state.columns.navigate && (geoData?.[state.columns.navigate.name] && geoData[state.columns.navigate.name]) ) || state.tooltips.appearanceType === 'click') {
71
+ if ((state.columns.navigate && geoData?.[state.columns.navigate.name] && geoData[state.columns.navigate.name]) || state.tooltips.appearanceType === 'click') {
91
72
  styles.cursor = 'pointer'
92
73
  }
93
74
 
94
- const radius = state.general.geoType === 'us' && !isGeoCodeMap ? 8 : isGeoCodeMap ? 2 : 4;
75
+ const radius = state.general.geoType === 'us' && !isGeoCodeMap ? 8 : isGeoCodeMap ? 2 : 4
95
76
 
96
77
  const additionalProps = {
97
- fillOpacity: state.general.type === 'bubble' ? .4 : 1
78
+ fillOpacity: state.general.type === 'bubble' ? 0.4 : 1
98
79
  }
99
80
 
100
- const circle = (
101
- <circle
102
- data-tip={toolTip}
103
- data-for="tooltip"
104
- cx={0}
105
- cy={0}
106
- r={ state.general.type === 'bubble' ? size(geoData[state.columns.primary.name]) : radius}
107
- title="Click for more information"
108
- onClick={() => geoClickHandler(cityDisplayName, geoData)}
109
- {...additionalProps}
110
- />
111
- );
81
+ const circle = <circle data-tip={toolTip} data-for='tooltip' cx={0} cy={0} r={state.general.type === 'bubble' ? size(geoData[state.columns.primary.name]) : radius} title='Click for more information' onClick={() => geoClickHandler(cityDisplayName, geoData)} {...additionalProps} />
112
82
 
113
83
  const pin = (
114
- <path
115
- className="marker"
116
- d="M0,0l-8.8-17.7C-12.1-24.3-7.4-32,0-32h0c7.4,0,12.1,7.7,8.8,14.3L0,0z"
117
- title="Click for more information"
118
- onClick={() => geoClickHandler(cityDisplayName, geoData)}
119
- data-tip={toolTip}
120
- data-for="tooltip"
121
- strokeWidth={2}
122
- stroke={'black'}
123
- {...additionalProps}
124
- >
125
- </path>
126
- );
127
-
128
- let transform = '';
129
-
130
- if (!isGeoCodeMap) {
84
+ <path className='marker' d='M0,0l-8.8-17.7C-12.1-24.3-7.4-32,0-32h0c7.4,0,12.1,7.7,8.8,14.3L0,0z' title='Click for more information' onClick={() => geoClickHandler(cityDisplayName, geoData)} data-tip={toolTip} data-for='tooltip' strokeWidth={2} stroke={'black'} {...additionalProps}></path>
85
+ )
86
+
87
+ let transform = ''
88
+
89
+ if (!isGeoCodeMap) {
131
90
  transform = `translate(${projection(supportedCities[city])})`
132
91
  }
133
92
 
@@ -137,19 +96,14 @@ const CityList = (({
137
96
  }
138
97
 
139
98
  return (
140
- <g
141
- key={i}
142
- transform={transform}
143
- css={styles}
144
- className="geo-point"
145
- >
146
- {state.visual.cityStyle === 'circle' && circle }
147
- {state.visual.cityStyle === 'pin' && pin }
99
+ <g key={i} transform={transform} css={styles} className='geo-point'>
100
+ {state.visual.cityStyle === 'circle' && circle}
101
+ {state.visual.cityStyle === 'pin' && pin}
148
102
  </g>
149
- );
150
- });
103
+ )
104
+ })
151
105
 
152
- return cities;
153
- });
106
+ return cities
107
+ }
154
108
 
155
- export default CityList;
109
+ export default CityList