@cdc/map 4.22.10 → 4.23.1

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 (58) hide show
  1. package/dist/495.js +3 -0
  2. package/dist/703.js +1 -0
  3. package/dist/856.js +3 -0
  4. package/dist/cdcmap.js +724 -120
  5. package/examples/bubble-us.json +362 -362
  6. package/examples/bubble-world.json +426 -426
  7. package/examples/city-state.json +434 -0
  8. package/examples/example-city-state.json +202 -25
  9. package/package.json +3 -4
  10. package/src/CdcMap.js +249 -423
  11. package/src/components/BubbleList.js +198 -240
  12. package/src/components/CityList.js +50 -97
  13. package/src/components/CountyMap.js +511 -600
  14. package/src/components/DataTable.js +223 -230
  15. package/src/components/EditorPanel.js +2395 -2551
  16. package/src/components/Filters.js +114 -0
  17. package/src/components/Geo.js +4 -14
  18. package/src/components/Modal.js +13 -23
  19. package/src/components/NavigationMenu.js +43 -39
  20. package/src/components/Sidebar.js +77 -93
  21. package/src/components/SingleStateMap.js +95 -151
  22. package/src/components/UsaMap.js +165 -214
  23. package/src/components/UsaRegionMap.js +122 -160
  24. package/src/components/WorldMap.js +96 -179
  25. package/src/components/ZoomableGroup.js +6 -26
  26. package/src/context.js +5 -0
  27. package/src/data/initial-state.js +20 -15
  28. package/src/data/supported-geos.js +3201 -3175
  29. package/src/hooks/useActiveElement.js +13 -13
  30. package/src/hooks/useColorPalette.ts +66 -74
  31. package/src/hooks/useZoomPan.js +22 -23
  32. package/src/index.html +32 -29
  33. package/src/scss/datatable.scss +1 -2
  34. package/src/scss/filters.scss +42 -0
  35. package/src/scss/main.scss +4 -3
  36. package/src/scss/sidebar.scss +22 -0
  37. package/examples/private/atsdr.json +0 -439
  38. package/examples/private/atsdr_new.json +0 -436
  39. package/examples/private/bubble.json +0 -285
  40. package/examples/private/city-state.json +0 -428
  41. package/examples/private/cty-issue.json +0 -42768
  42. package/examples/private/default-usa.json +0 -460
  43. package/examples/private/default-world-data.json +0 -1444
  44. package/examples/private/default.json +0 -968
  45. package/examples/private/legend-issue.json +0 -1
  46. package/examples/private/map-rounding-error.json +0 -42759
  47. package/examples/private/map.csv +0 -60
  48. package/examples/private/mdx.json +0 -210
  49. package/examples/private/monkeypox.json +0 -376
  50. package/examples/private/regions.json +0 -52
  51. package/examples/private/valid-data-map.csv +0 -59
  52. package/examples/private/wcmsrd-13881-data.json +0 -2858
  53. package/examples/private/wcmsrd-13881.json +0 -5823
  54. package/examples/private/wcmsrd-14492-data.json +0 -292
  55. package/examples/private/wcmsrd-14492.json +0 -114
  56. package/examples/private/wcmsrd-test.json +0 -268
  57. package/examples/private/world.json +0 -1580
  58. package/examples/private/worldmap.json +0 -1490
@@ -1,244 +1,202 @@
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
+ // Set bubble sizes
20
+ var size = scaleLinear().domain([hasBubblesWithZeroOnMap, maxDataValue]).range([state.visual.minBubbleSize, state.visual.maxBubbleSize])
21
+
22
+ // Start looping through the countries to create the bubbles.
23
+ if (state.general.geoType === 'world') {
24
+ const countries =
25
+ sortedRuntimeData &&
26
+ sortedRuntimeData.map((country, index) => {
27
+ let coordinates = countryCoordinates[country.uid]
28
+
29
+ if (!coordinates) return true
30
+
31
+ const countryName = displayGeoName(country[state.columns.geo.name])
32
+ const toolTip = applyTooltipsToGeo(countryName, country)
33
+ const legendColors = applyLegendToRow(country)
34
+
35
+ let primaryKey = state.columns.primary.name
36
+ if ((Math.floor(Number(country[primaryKey])) === 0 || country[primaryKey] === '') && !state.visual.showBubbleZeros) return
37
+
38
+ let transform = `translate(${projection([coordinates[1], coordinates[0]])})`
39
+
40
+ let pointerX, pointerY
41
+
42
+ if (!projection(coordinates)) return true
43
+
44
+ const circle = (
45
+ <>
46
+ <circle
47
+ key={`circle-${countryName.replace(' ', '')}`}
48
+ data-tip={toolTip}
49
+ data-for='tooltip'
50
+ className={`bubble country--${countryName}`}
51
+ cx={Number(projection(coordinates[1], coordinates[0])[0]) || 0} // || 0 handles error on loads where the data isn't ready
52
+ cy={Number(projection(coordinates[1], coordinates[0])[1]) || 0}
53
+ r={Number(size(country[primaryKey]))}
54
+ fill={legendColors[0]}
55
+ stroke={legendColors[0]}
56
+ strokeWidth={1.25}
57
+ fillOpacity={0.4}
58
+ onPointerDown={e => {
59
+ pointerX = e.clientX
60
+ pointerY = e.clientY
61
+ }}
62
+ onPointerUp={e => {
63
+ if (pointerX && pointerY && e.clientX > pointerX - clickTolerance && e.clientX < pointerX + clickTolerance && e.clientY > pointerY - clickTolerance && e.clientY < pointerY + clickTolerance) {
64
+ handleCircleClick(country)
65
+ pointerX = undefined
66
+ pointerY = undefined
67
+ }
68
+ }}
69
+ transform={transform}
70
+ style={{ transition: 'all .25s ease-in-out', cursor: 'pointer' }}
71
+ />
72
+
73
+ {state.visual.extraBubbleBorder && (
74
+ <circle
75
+ key={`circle-${countryName.replace(' ', '')}`}
76
+ data-tip={toolTip}
77
+ data-for='tooltip'
78
+ className='bubble'
79
+ cx={Number(projection(coordinates[1], coordinates[0])[0]) || 0} // || 0 handles error on loads where the data isn't ready
80
+ cy={Number(projection(coordinates[1], coordinates[0])[1]) || 0}
81
+ r={Number(size(country[primaryKey])) + 1}
82
+ fill={'transparent'}
83
+ stroke={'white'}
84
+ strokeWidth={0.5}
85
+ onPointerDown={e => {
86
+ pointerX = e.clientX
87
+ pointerY = e.clientY
88
+ }}
89
+ onPointerUp={e => {
90
+ if (pointerX && pointerY && e.clientX > pointerX - clickTolerance && e.clientX < pointerX + clickTolerance && e.clientY > pointerY - clickTolerance && e.clientY < pointerY + clickTolerance) {
91
+ handleCircleClick(country)
92
+ pointerX = undefined
93
+ pointerY = undefined
94
+ }
95
+ }}
96
+ transform={transform}
97
+ style={{ transition: 'all .25s ease-in-out', cursor: 'pointer' }}
98
+ />
99
+ )}
100
+ </>
101
+ )
102
+
103
+ return <g key={`group-${countryName.replace(' ', '')}`}>{circle}</g>
104
+ })
105
+ return countries
106
+ }
107
+
108
+ if (state.general.geoType === 'us') {
109
+ const bubbles =
110
+ sortedRuntimeData &&
111
+ sortedRuntimeData.map((item, index) => {
112
+ let stateData = stateCoordinates[item.uid]
113
+ let primaryKey = state?.columns?.primary?.name
114
+ if (Number(size(item[primaryKey])) === 0) return
115
+
116
+ if (item[primaryKey] === null) item[primaryKey] = ''
117
+
118
+ // Return if hiding zeros on the map
119
+ if ((Math.floor(Number(item[primaryKey])) === 0 || item[primaryKey] === '') && !state.visual.showBubbleZeros) return
120
+
121
+ if (!stateData) return true
122
+ let longitude = Number(stateData.Longitude)
123
+ let latitude = Number(stateData.Latitude)
124
+ let coordinates = [longitude, latitude]
125
+ //console.log('projection', projection([longitude, latitude]))
126
+ let stateName = stateData.Name
127
+ if (!coordinates) return true
128
+
129
+ stateName = displayGeoName(stateName)
130
+ const toolTip = applyTooltipsToGeo(stateName, item)
131
+ const legendColors = applyLegendToRow(item)
132
+
133
+ let transform = `translate(${projection([coordinates[1], coordinates[0]])})`
134
+
135
+ if (!projection(coordinates)) return true
136
+
137
+ let pointerX, pointerY
138
+ const circle = (
139
+ <>
140
+ <circle
141
+ key={`circle-${stateName.replace(' ', '')}`}
142
+ data-tip={toolTip}
143
+ data-for='tooltip'
144
+ className='bubble'
145
+ cx={projection(coordinates)[0] || 0} // || 0 handles error on loads where the data isn't ready
146
+ cy={projection(coordinates)[1] || 0}
147
+ r={Number(size(item[primaryKey]))}
148
+ fill={legendColors[0]}
149
+ stroke={legendColors[0]}
150
+ strokeWidth={1.25}
151
+ fillOpacity={0.4}
152
+ onPointerDown={e => {
153
+ pointerX = e.clientX
154
+ pointerY = e.clientY
155
+ }}
156
+ onPointerUp={e => {
157
+ if (pointerX && pointerY && e.clientX > pointerX - clickTolerance && e.clientX < pointerX + clickTolerance && e.clientY > pointerY - clickTolerance && e.clientY < pointerY + clickTolerance) {
158
+ handleCircleClick(state)
159
+ pointerX = undefined
160
+ pointerY = undefined
161
+ }
162
+ }}
163
+ transform={transform}
164
+ style={{ transition: 'all .25s ease-in-out', cursor: 'pointer' }}
165
+ />
166
+ {state.visual.extraBubbleBorder && (
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])) + 1}
175
+ fill={'transparent'}
176
+ stroke={'white'}
177
+ strokeWidth={0.5}
178
+ fillOpacity={0.4}
179
+ onPointerDown={e => {
180
+ pointerX = e.clientX
181
+ pointerY = e.clientY
182
+ }}
183
+ onPointerUp={e => {
184
+ if (pointerX && pointerY && e.clientX > pointerX - clickTolerance && e.clientX < pointerX + clickTolerance && e.clientY > pointerY - clickTolerance && e.clientY < pointerY + clickTolerance) {
185
+ handleCircleClick(state)
186
+ pointerX = undefined
187
+ pointerY = undefined
188
+ }
189
+ }}
190
+ transform={transform}
191
+ style={{ transition: 'all .25s ease-in-out', cursor: 'pointer' }}
192
+ />
193
+ )}
194
+ </>
195
+ )
196
+
197
+ return <g key={`group-${stateName.replace(' ', '')}`}>{circle}</g>
198
+ })
199
+ return bubbles
200
+ }
243
201
  }
244
202
  export default BubbleList
@@ -1,76 +1,58 @@
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]
45
+ const cityDisplayName = isGeoCodeMap ? city : titleCase(displayGeoName(city))
60
46
 
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) );
64
-
65
- const legendColors = (isGeoCodeMap && geoData) ? applyLegendToRow(geoData) : data[city] ? applyLegendToRow(data[city]) : false;
47
+ const legendColors = isGeoCodeMap && geoData ? applyLegendToRow(geoData) : data[city] ? applyLegendToRow(data[city]) : false
66
48
 
67
49
  if (legendColors === false) {
68
- return true;
50
+ return true
69
51
  }
70
52
 
71
53
  const styles = {
72
54
  fill: legendColors[0],
73
- opacity: setSharedFilterValue && isFilterValueSupported && data[city][state.columns.geo.name] !== setSharedFilterValue ? .5 : 1,
55
+ opacity: setSharedFilterValue && isFilterValueSupported && data[city][state.columns.geo.name] !== setSharedFilterValue ? 0.5 : 1,
74
56
  stroke: setSharedFilterValue && isFilterValueSupported && data[city][state.columns.geo.name] === setSharedFilterValue ? 'rgba(0, 0, 0, 1)' : 'rgba(0, 0, 0, 0.4)',
75
57
  '&:hover': {
76
58
  fill: legendColors[1],
@@ -80,54 +62,30 @@ const CityList = (({
80
62
  fill: legendColors[2],
81
63
  outline: 0
82
64
  }
83
- };
84
-
85
-
65
+ }
86
66
 
87
- const toolTip = applyTooltipsToGeo(cityDisplayName, data[city]);
67
+ const toolTip = applyTooltipsToGeo(cityDisplayName, data[city])
88
68
 
89
69
  // 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') {
70
+ if ((state.columns.navigate && geoData?.[state.columns.navigate.name] && geoData[state.columns.navigate.name]) || state.tooltips.appearanceType === 'click') {
91
71
  styles.cursor = 'pointer'
92
72
  }
93
73
 
94
- const radius = state.general.geoType === 'us' && !isGeoCodeMap ? 8 : isGeoCodeMap ? 2 : 4;
74
+ const radius = state.general.geoType === 'us' && !isGeoCodeMap ? 8 : isGeoCodeMap ? state.visual.geoCodeCircleSize : 4
95
75
 
96
76
  const additionalProps = {
97
- fillOpacity: state.general.type === 'bubble' ? .4 : 1
77
+ fillOpacity: state.general.type === 'bubble' ? 0.4 : 1
98
78
  }
99
79
 
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
- );
80
+ 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
81
 
113
82
  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) {
83
+ <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>
84
+ )
85
+
86
+ let transform = ''
87
+
88
+ if (!isGeoCodeMap) {
131
89
  transform = `translate(${projection(supportedCities[city])})`
132
90
  }
133
91
 
@@ -137,19 +95,14 @@ const CityList = (({
137
95
  }
138
96
 
139
97
  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 }
98
+ <g key={i} transform={transform} css={styles} className='geo-point'>
99
+ {state.visual.cityStyle === 'circle' && circle}
100
+ {state.visual.cityStyle === 'pin' && pin}
148
101
  </g>
149
- );
150
- });
102
+ )
103
+ })
151
104
 
152
- return cities;
153
- });
105
+ return cities
106
+ }
154
107
 
155
- export default CityList;
108
+ export default CityList