@cdc/map 4.23.6 → 4.23.8

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.
@@ -372,11 +372,18 @@ const UsaMap = props => {
372
372
  </AlbersUsa>
373
373
  )}
374
374
  </svg>
375
+
375
376
  {territories.length > 0 && (
376
- <section className='territories'>
377
- <span className='label'>{state.general.territoriesLabel}</span>
378
- {territories}
379
- </section>
377
+ <>
378
+ <div className='two-col'>
379
+ <div>
380
+ <span className='territories-label label'>{state.general.territoriesLabel}</span>
381
+ </div>
382
+ <div>
383
+ <span className={window.visualViewport.width < 500 ? 'territories--mobile' : 'territories'}>{territories}</span>
384
+ </div>
385
+ </div>
386
+ </>
380
387
  )}
381
388
  </ErrorBoundary>
382
389
  )
@@ -103,17 +103,7 @@ const UsaRegionMap = props => {
103
103
  }
104
104
  }
105
105
 
106
- return <Shape
107
- key={label}
108
- label={label}
109
- css={styles}
110
- text={styles.color}
111
- stroke={geoStrokeColor}
112
- strokeWidth={1.5}
113
- onClick={() => geoClickHandler(territory, territoryData)}
114
- data-tooltip-id="tooltip"
115
- data-tooltip-html={toolTip}
116
- />
106
+ return <Shape key={label} label={label} css={styles} text={styles.color} stroke={geoStrokeColor} strokeWidth={1.5} onClick={() => geoClickHandler(territory, territoryData)} data-tooltip-id='tooltip' data-tooltip-html={toolTip} />
117
107
  }
118
108
  })
119
109
 
@@ -220,13 +210,7 @@ const UsaRegionMap = props => {
220
210
  // const barFill = barPositive ? "#fff" : "#fff";
221
211
 
222
212
  return (
223
- <g key={key}
224
- className='geo-group'
225
- css={styles}
226
- onClick={() => geoClickHandler(geoDisplayName, geoData)}
227
- data-tooltip-id="tooltip"
228
- data-tooltip-html={toolTip}
229
- >
213
+ <g key={key} className='geo-group' css={styles} onClick={() => geoClickHandler(geoDisplayName, geoData)} data-tooltip-id='tooltip' data-tooltip-html={toolTip}>
230
214
  <path tabIndex={-1} className='single-geo' stroke={geoStrokeColor} strokeWidth={1.3} d={path} />
231
215
  <g id={`region-${index + 1}-label`}>
232
216
  <circle fill='#fff' stroke='#999' cx={circleRadius} cy={circleRadius} r={circleRadius} />
@@ -16,21 +16,7 @@ const { features: world } = feature(topoJSON, topoJSON.objects.countries)
16
16
  let projection = geoMercator()
17
17
 
18
18
  const WorldMap = props => {
19
- const {
20
- state,
21
- applyTooltipsToGeo,
22
- data,
23
- geoClickHandler,
24
- applyLegendToRow,
25
- displayGeoName,
26
- supportedCountries,
27
- setState, setRuntimeData,
28
- generateRuntimeData,
29
- setFilteredCountryCode,
30
- position, setPosition,
31
- hasZoom,
32
- handleMapAriaLabels,
33
- titleCase } = props
19
+ const { state, applyTooltipsToGeo, data, geoClickHandler, applyLegendToRow, displayGeoName, supportedCountries, setState, setRuntimeData, generateRuntimeData, setFilteredCountryCode, position, setPosition, hasZoom, handleMapAriaLabels, titleCase } = props
34
20
 
35
21
  // TODO Refactor - state should be set together here to avoid rerenders
36
22
  // Resets to original data & zooms out
@@ -54,31 +40,34 @@ const WorldMap = props => {
54
40
  setPosition(pos => ({ ...pos, zoom: pos.zoom / 1.5 }))
55
41
  }
56
42
 
57
- const ZoomControls = ({ position, setPosition, state, setState, setRuntimeData, generateRuntimeData }) => (
58
- <div className='zoom-controls' data-html2canvas-ignore>
59
- <button onClick={() => handleZoomIn(position, setPosition)} aria-label='Zoom In'>
60
- <svg viewBox='0 0 24 24' stroke='currentColor' strokeWidth='3'>
61
- <line x1='12' y1='5' x2='12' y2='19' />
62
- <line x1='5' y1='12' x2='19' y2='12' />
63
- </svg>
64
- </button>
65
- <button onClick={() => handleZoomOut(position, setPosition)} aria-label='Zoom Out'>
66
- <svg viewBox='0 0 24 24' stroke='currentColor' strokeWidth='3'>
67
- <line x1='5' y1='12' x2='19' y2='12' />
68
- </svg>
69
- </button>
70
- {state.general.type === 'bubble' && (
71
- <button onClick={() => handleReset(state, setState, setRuntimeData, generateRuntimeData)} className='reset' aria-label='Reset Zoom and Map Filters'>
72
- Reset Filters
43
+ const ZoomControls = ({ position, setPosition, state, setState, setRuntimeData, generateRuntimeData }) => {
44
+ if (!state.general.allowMapZoom) return
45
+ return (
46
+ <div className='zoom-controls' data-html2canvas-ignore>
47
+ <button onClick={() => handleZoomIn(position, setPosition)} aria-label='Zoom In'>
48
+ <svg viewBox='0 0 24 24' stroke='currentColor' strokeWidth='3'>
49
+ <line x1='12' y1='5' x2='12' y2='19' />
50
+ <line x1='5' y1='12' x2='19' y2='12' />
51
+ </svg>
73
52
  </button>
74
- )}
75
- {state.general.type === 'world-geocode' && (
76
- <button onClick={() => handleReset(state, setState, setRuntimeData, generateRuntimeData)} className='reset' aria-label='Reset Zoom'>
77
- Reset Zoom
53
+ <button onClick={() => handleZoomOut(position, setPosition)} aria-label='Zoom Out'>
54
+ <svg viewBox='0 0 24 24' stroke='currentColor' strokeWidth='3'>
55
+ <line x1='5' y1='12' x2='19' y2='12' />
56
+ </svg>
78
57
  </button>
79
- )}
80
- </div>
81
- )
58
+ {state.general.type === 'bubble' && (
59
+ <button onClick={() => handleReset(state, setState, setRuntimeData, generateRuntimeData)} className='reset' aria-label='Reset Zoom and Map Filters'>
60
+ Reset Filters
61
+ </button>
62
+ )}
63
+ {state.general.type === 'world-geocode' && (
64
+ <button onClick={() => handleReset(state, setState, setRuntimeData, generateRuntimeData)} className='reset' aria-label='Reset Zoom'>
65
+ Reset Zoom
66
+ </button>
67
+ )}
68
+ </div>
69
+ )
70
+ }
82
71
 
83
72
  // TODO Refactor - state should be set together here to avoid rerenders
84
73
  const handleCircleClick = (country, state, setState, setRuntimeData, generateRuntimeData) => {
@@ -95,7 +84,7 @@ const WorldMap = props => {
95
84
  const geosJsx = geographies.map(({ feature: geo, path }, i) => {
96
85
  const geoKey = geo.properties.iso
97
86
 
98
- if (!geoKey) return null;
87
+ if (!geoKey) return null
99
88
 
100
89
  const geoData = data[geoKey]
101
90
 
@@ -138,16 +127,7 @@ const WorldMap = props => {
138
127
  styles.cursor = 'pointer'
139
128
  }
140
129
 
141
- return <Geo
142
- key={i + '-geo'}
143
- css={styles}
144
- path={path}
145
- stroke={geoStrokeColor}
146
- strokeWidth={strokeWidth}
147
- onClick={() => geoClickHandler(geoDisplayName, geoData)}
148
- data-tooltip-id="tooltip"
149
- data-tooltip-html={toolTip}
150
- />
130
+ return <Geo key={i + '-geo'} css={styles} path={path} stroke={geoStrokeColor} strokeWidth={strokeWidth} onClick={() => geoClickHandler(geoDisplayName, geoData)} data-tooltip-id='tooltip' data-tooltip-html={toolTip} />
151
131
  }
152
132
 
153
133
  // Default return state, just geo with no additional information
@@ -156,18 +136,7 @@ const WorldMap = props => {
156
136
 
157
137
  // Cities
158
138
  geosJsx.push(
159
- <CityList
160
- applyLegendToRow={applyLegendToRow}
161
- applyTooltipsToGeo={applyTooltipsToGeo}
162
- data={data}
163
- displayGeoName={displayGeoName}
164
- geoClickHandler={geoClickHandler}
165
- isGeoCodeMap={state.general.type === 'world-geocode'}
166
- key='cities'
167
- projection={projection}
168
- state={state}
169
- titleCase={titleCase}
170
- />
139
+ <CityList applyLegendToRow={applyLegendToRow} applyTooltipsToGeo={applyTooltipsToGeo} data={data} displayGeoName={displayGeoName} geoClickHandler={geoClickHandler} isGeoCodeMap={state.general.type === 'world-geocode'} key='cities' projection={projection} state={state} titleCase={titleCase} />
171
140
  )
172
141
 
173
142
  // Bubbles
@@ -206,7 +175,9 @@ const WorldMap = props => {
206
175
  </ZoomableGroup>
207
176
  </svg>
208
177
  )}
209
- {(state.general.type === 'data' || (state.general.type === 'world-geocode' && hasZoom) || (state.general.type === 'bubble' && hasZoom)) && <ZoomControls position={position} setPosition={setPosition} setRuntimeData={setRuntimeData} state={state} setState={setState} generateRuntimeData={generateRuntimeData} />}
178
+ {(state.general.type === 'data' || (state.general.type === 'world-geocode' && hasZoom) || (state.general.type === 'bubble' && hasZoom)) && (
179
+ <ZoomControls position={position} setPosition={setPosition} setRuntimeData={setRuntimeData} state={state} setState={setState} generateRuntimeData={generateRuntimeData} />
180
+ )}
210
181
  </ErrorBoundary>
211
182
  )
212
183
  }
@@ -22,7 +22,11 @@ export default {
22
22
  },
23
23
  allowMapZoom: true,
24
24
  hideGeoColumnInTooltip: false,
25
- hidePrimaryColumnInTooltip: false
25
+ hidePrimaryColumnInTooltip: false,
26
+ statePicked: {
27
+ fipsCode: '01',
28
+ stateName: 'Alabama'
29
+ }
26
30
  },
27
31
  type: 'map',
28
32
  color: 'pinkpurple',
@@ -77,7 +81,8 @@ export default {
77
81
  tooltips: {
78
82
  appearanceType: 'hover',
79
83
  linkLabel: 'Learn More',
80
- capitalizeLabels: true
84
+ capitalizeLabels: true,
85
+ opacity: 90
81
86
  },
82
87
  runtime: {
83
88
  editorErrorMessage: []
@@ -172,6 +172,9 @@ export const stateFipsToTwoDigit = {
172
172
  54: 'WV',
173
173
  55: 'WI',
174
174
  56: 'WY',
175
+ 60: 'AS',
176
+ 66: 'GU',
177
+ 69: 'MP',
175
178
  72: 'PR',
176
179
  78: 'VI'
177
180
  }
@@ -0,0 +1,135 @@
1
+ const useTooltip = props => {
2
+ const { state, displayGeoName, displayDataAsText, supportedStatesFipsCodes } = props
3
+
4
+ /**
5
+ * On county maps there's a need to append the state name
6
+ * @param {String} toolTipText - previous tooltip text to build upon
7
+ * @param {Object} row - row of data to lookup fips code with using the geo column.
8
+ * @returns {String} toolTipText - new toolTipText
9
+ */
10
+ const handleTooltipStateNameColumn = (toolTipText, row) => {
11
+ const { geoType, type, hideGeoColumnInTooltip } = state.general
12
+ if (geoType === 'us-county' && type !== 'us-geocode') {
13
+ let stateFipsCode = row[state.columns.geo.name].substring(0, 2)
14
+ const stateName = supportedStatesFipsCodes[stateFipsCode]
15
+ toolTipText += hideGeoColumnInTooltip ? `<strong>${stateName}</strong><br/>` : `<strong>Location: ${stateName}</strong><br/>`
16
+ }
17
+ return toolTipText
18
+ }
19
+
20
+ /**
21
+ * On county and state maps, adds the ability to hide the geo column name (prefix)
22
+ * @param {String} geoName - feature name
23
+ * @returns {String} text to be appended to toolTipText
24
+ */
25
+ const handleTooltipGeoColumn = geoName => {
26
+ const { hideGeoColumnInTooltip } = state.general
27
+
28
+ const handleTooltipPrefix = toolTipText => {
29
+ const { geoType, geoLabelOverride } = state.general
30
+ switch (geoType) {
31
+ case 'us':
32
+ toolTipText = 'State: '
33
+ break
34
+ case 'us-county':
35
+ toolTipText = 'County: '
36
+ break
37
+ case 'single-state':
38
+ toolTipText = 'County: '
39
+ break
40
+ default:
41
+ toolTipText = ''
42
+ break
43
+ }
44
+
45
+ if (geoLabelOverride) toolTipText = `${geoLabelOverride}: `
46
+
47
+ return toolTipText
48
+ }
49
+
50
+ const prefix = handleTooltipPrefix()
51
+
52
+ if (hideGeoColumnInTooltip) return `<strong>${displayGeoName(geoName)}</strong>`
53
+ return `<p class="tooltip-heading">${prefix}${displayGeoName(geoName)}</p>`
54
+ }
55
+
56
+ /**
57
+ * Handles special class descriptions in tooltips
58
+ */
59
+ const handleTooltipSpecialClassText = (specialClasses, column, row, value, columnKey) => {
60
+ if (specialClasses && specialClasses.length && typeof specialClasses[0] === 'object') {
61
+ for (const specialClass of specialClasses) {
62
+ if (column.name === specialClass.key && String(row[specialClass.key]) === specialClass.value) {
63
+ value = displayDataAsText(specialClass.label, columnKey)
64
+ break
65
+ }
66
+ }
67
+ }
68
+ return value
69
+ }
70
+
71
+ const handleTooltipPrimaryColumn = (tooltipValue, column) => {
72
+ const { hidePrimaryColumnInTooltip } = state.general
73
+ let tooltipPrefix = column.label?.length > 0 ? column.label : ''
74
+ if (hidePrimaryColumnInTooltip || !tooltipPrefix) return `<li class="tooltip-body">${tooltipValue}</li>`
75
+ return `<li class="tooltip-body">${tooltipPrefix}: ${tooltipValue}</li>`
76
+ }
77
+
78
+ /**
79
+ *
80
+ * @param {String} toolTipText - previous tooltipText to build upon
81
+ * @param {Object} row - row of data
82
+ * @returns {String} new tooltipText value
83
+ */
84
+ const handleTooltipColumns = (toolTipText, row) => {
85
+ const tooltipEnabledMaps = ['data', 'bubble', 'us-geocode', 'world-geocode', 'map']
86
+ const {
87
+ general: { type: currentMapType },
88
+ columns,
89
+ legend: { specialClasses }
90
+ } = state
91
+
92
+ if (tooltipEnabledMaps.includes(currentMapType) && undefined !== row) {
93
+ toolTipText += `<ul className="capitalize">`
94
+
95
+ // if tooltips are allowed, loop through each column
96
+ Object.keys(columns).forEach(columnKey => {
97
+ const column = state.columns[columnKey]
98
+
99
+ if (column.tooltip) {
100
+ let tooltipValue = handleTooltipSpecialClassText(specialClasses, column, row, '', columnKey)
101
+
102
+ if (!tooltipValue) {
103
+ tooltipValue = displayDataAsText(row[column.name], columnKey)
104
+ }
105
+
106
+ toolTipText += handleTooltipPrimaryColumn(tooltipValue, column)
107
+ }
108
+ })
109
+ toolTipText += `</ul>`
110
+ }
111
+
112
+ return toolTipText
113
+ }
114
+
115
+ const buildTooltip = (row, geoName, toolTipText = '') => {
116
+ if (!row) return
117
+
118
+ // Handle County Location Columns
119
+ toolTipText += handleTooltipStateNameColumn(toolTipText, row)
120
+
121
+ // Handle Data > Geo Column In tooltips
122
+ toolTipText += handleTooltipGeoColumn(geoName)
123
+
124
+ // Handle Data > Primary Column in tooltips
125
+ toolTipText = handleTooltipColumns(toolTipText, row)
126
+
127
+ return toolTipText
128
+ }
129
+
130
+ return {
131
+ buildTooltip
132
+ }
133
+ }
134
+
135
+ export default useTooltip
@@ -130,13 +130,7 @@
130
130
  .remove-column {
131
131
  font-size: 13px;
132
132
  }
133
- .__react_component_tooltip {
134
- padding: 5px;
135
- max-width: 300px;
136
- }
137
- .tooltip {
138
- position: relative;
139
- }
133
+
140
134
  .helper {
141
135
  position: relative;
142
136
  opacity: 0.7;
@@ -3,6 +3,7 @@
3
3
  @import 'variables';
4
4
  @import 'editor-panel';
5
5
  @import 'filters';
6
+ @import '@cdc/core/styles/v2/components/ui/tooltip';
6
7
 
7
8
  .cdc-map-outer-container {
8
9
  position: relative;
@@ -20,7 +21,6 @@
20
21
  }
21
22
 
22
23
  .cdc-map-inner-container {
23
- @import './tooltips';
24
24
  @import './map';
25
25
  @import './sidebar';
26
26
  @import './datatable';