@cdc/map 4.24.3 → 4.24.4

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.
@@ -0,0 +1,12 @@
1
+ const Error = ({ state }) => {
2
+ return (
3
+ <section className='waiting'>
4
+ <section className='waiting-container'>
5
+ <h3>Error With Configuration</h3>
6
+ <p>{state.runtime.editorErrorMessage}</p>
7
+ </section>
8
+ </section>
9
+ )
10
+ }
11
+
12
+ export default Error
@@ -0,0 +1,5 @@
1
+ .cdc-open-viz-module {
2
+ .pattern-input__color {
3
+ margin-top: 1rem;
4
+ }
5
+ }
@@ -3,6 +3,9 @@ import { Accordion, AccordionItem, AccordionItemHeading, AccordionItemPanel, Acc
3
3
  import ConfigContext from '../../../context'
4
4
  import { type MapContext } from '../../../types/MapContext'
5
5
  import Button from '@cdc/core/components/elements/Button'
6
+ import Tooltip from '@cdc/core/components/ui/Tooltip'
7
+ import Icon from '@cdc/core/components/ui/Icon'
8
+ import './Panel.PatternSettings-style.css'
6
9
 
7
10
  type PanelProps = {
8
11
  name: string
@@ -32,7 +35,7 @@ const PatternSettings = ({ name }: PanelProps) => {
32
35
  }
33
36
 
34
37
  /** Updates the map pattern at a given index */
35
- const handleUpdateGeoPattern = (value: string, index: number, keyToUpdate: 'dataKey' | 'pattern' | 'dataValue' | 'size' | 'label') => {
38
+ const handleUpdateGeoPattern = (value: string, index: number, keyToUpdate: 'dataKey' | 'pattern' | 'dataValue' | 'size' | 'label' | 'color') => {
36
39
  const updatedPatterns = [...state.map.patterns]
37
40
  updatedPatterns[index] = { ...updatedPatterns[index], [keyToUpdate]: value }
38
41
 
@@ -120,6 +123,20 @@ const PatternSettings = ({ name }: PanelProps) => {
120
123
  </option>
121
124
  ))}
122
125
  </select>
126
+ <div className='pattern-input__color'>
127
+ <label htmlFor='patternColor'>
128
+ Pattern Color
129
+ <Tooltip style={{ textTransform: 'none' }}>
130
+ <Tooltip.Target>
131
+ <Icon display='question' style={{ marginLeft: '0.5rem', display: 'inline-block', whiteSpace: 'nowrap' }} />
132
+ </Tooltip.Target>
133
+ <Tooltip.Content>
134
+ <p>{`If this setting is used, it is the reponsibility of the visualization author to verify the visualization colors meet WCAG 3:1 contrast ratios.`}</p>
135
+ </Tooltip.Content>
136
+ </Tooltip>
137
+ <input type='text' value={pattern.color || ''} id='patternColor' name='patternColor' onChange={e => handleUpdateGeoPattern(e.target.value, patternIndex, 'color')} />
138
+ </label>
139
+ </div>
123
140
  <Button onClick={e => handleRemovePattern(patternIndex)} className='btn btn--remove warn'>
124
141
  Remove Pattern
125
142
  </Button>
@@ -14,7 +14,13 @@ import { GlyphStar, GlyphTriangle, GlyphDiamond, GlyphSquare, GlyphCircle } from
14
14
  import { Group } from '@visx/group'
15
15
  import './index.scss'
16
16
 
17
+ type LegendProps = {
18
+ skipId: string
19
+ }
20
+
17
21
  const Legend = forwardRef((props, ref) => {
22
+ const { skipId } = props
23
+
18
24
  // prettier-ignore
19
25
  const {
20
26
  displayDataAsText,
@@ -28,6 +34,7 @@ const Legend = forwardRef((props, ref) => {
28
34
  } = useContext(ConfigContext)
29
35
 
30
36
  const { legend } = state
37
+ const fontSize = ['sm', 'xs', 'xxs'].includes(viewport) ? { fontSize: '11px' } : null
31
38
 
32
39
  // Toggles if a legend is active and being applied to the map and data table.
33
40
  const toggleLegendActive = (i, legendLabel) => {
@@ -89,6 +96,7 @@ const Legend = forwardRef((props, ref) => {
89
96
  return (
90
97
  // eslint-disable-next-line jsx-a11y/click-events-have-key-events,jsx-a11y/no-noninteractive-element-interactions
91
98
  <li
99
+ style={fontSize}
92
100
  className={handleListItemClass().join(' ')}
93
101
  key={idx}
94
102
  title={`Legend item ${legendLabel} - Click to disable`}
@@ -101,10 +109,9 @@ const Legend = forwardRef((props, ref) => {
101
109
  toggleLegendActive(idx, legendLabel)
102
110
  }
103
111
  }}
104
- role='button'
105
112
  tabIndex={0}
106
113
  >
107
- <LegendCircle fill={entry.color} /> <span>{legendLabel}</span>
114
+ <LegendCircle viewport={viewport} fill={entry.color} /> <span>{legendLabel}</span>
108
115
  </li>
109
116
  )
110
117
  })
@@ -171,10 +178,14 @@ const Legend = forwardRef((props, ref) => {
171
178
  return (
172
179
  <ErrorBoundary component='Sidebar'>
173
180
  <div className='legends'>
174
- <aside id='legend' className={legendClasses.aside.join(' ') || ''} role='region' aria-label='Legend' tabIndex={0} ref={ref}>
181
+ <aside id={skipId || 'legend'} className={legendClasses.aside.join(' ') || ''} role='region' aria-label='Legend' tabIndex={0} ref={ref}>
175
182
  <section className={legendClasses.section.join(' ') || ''} aria-label='Map Legend'>
176
- {legend.title && <span className={legendClasses.title.join(' ') || ''}>{parse(legend.title)}</span>}
177
- {legend.dynamicDescription === false && legend.description && <p className={legendClasses.description.join(' ') || ''}>{parse(legend.description)}</p>}
183
+ {legend.title && <h3 className={legendClasses.title.join(' ') || ''}>{parse(legend.title)}</h3>}
184
+ {legend.dynamicDescription === false && legend.description && (
185
+ <p style={fontSize} className={legendClasses.description.join(' ') || ''}>
186
+ {parse(legend.description)}
187
+ </p>
188
+ )}
178
189
  {legend.dynamicDescription === true &&
179
190
  runtimeFilters.map((filter, idx) => {
180
191
  const lookupStr = `${idx},${filter.values.indexOf(String(filter.active))}`
@@ -184,7 +195,7 @@ const Legend = forwardRef((props, ref) => {
184
195
 
185
196
  if (desc.length > 0) {
186
197
  return (
187
- <p key={`dynamic-description-${lookupStr}`} className={`dynamic-legend-description-${lookupStr}`}>
198
+ <p style={fontSize} key={`dynamic-description-${lookupStr}`} className={`dynamic-legend-description-${lookupStr}`}>
188
199
  {desc}
189
200
  </p>
190
201
  )
@@ -218,7 +229,7 @@ const Legend = forwardRef((props, ref) => {
218
229
  {cityStyleShapes[shape.toLowerCase()]}
219
230
  </Group>
220
231
  </svg>
221
- <p>{label}</p>
232
+ <p style={fontSize}>{label}</p>
222
233
  </div>
223
234
  )
224
235
  )}
@@ -27,7 +27,7 @@ const LegendItemHex = props => {
27
27
  return (
28
28
  <aside id='legend' className={legendClasses.aside.join(' ')} role='region' aria-label='Legend' tabIndex={0}>
29
29
  <section className={legendClasses.section.join(' ')} aria-label='Map Legend'>
30
- {shapeGroup.legendTitle && <span className={legendClasses.title.join(' ')}>{parse(shapeGroup.legendTitle)}</span>}
30
+ {shapeGroup.legendTitle && <h3 className={legendClasses.title.join(' ')}>{parse(shapeGroup.legendTitle)}</h3>}
31
31
  {shapeGroup.legendDescription && <p className={legendClasses.description.join(' ')}>{parse(shapeGroup.legendDescription)}</p>}
32
32
 
33
33
  <ul className={legendClasses.ul.join(' ')} aria-label='Legend items' style={{ listStyle: 'none' }}>
@@ -16,12 +16,12 @@ type HexIconProps = {
16
16
  }
17
17
 
18
18
  const HexIcon: React.FC<HexIconProps> = props => {
19
- const { item, index, centroid, iconSize, textColor, isTerritory } = props
19
+ const { item, index, centroid, iconSize, textColor = '#000', isTerritory } = props
20
20
  if (!centroid) return
21
21
 
22
22
  if (isTerritory) {
23
23
  return (
24
- <Group style={{ transform: `translate(36%, 50%)`, fill: 'currentColor' }} key={`territory-hex--${index}`}>
24
+ <Group style={{ transform: `translate(36%, 50%)` }} key={`territory-hex--${index}`}>
25
25
  {item.shape === 'Arrow Down' && <AiOutlineArrowDown size={12} stroke='none' fontWeight={100} />}
26
26
  {item.shape === 'Arrow Up' && <AiOutlineArrowUp size={12} stroke='none' fontWeight={100} />}
27
27
  {item.shape === 'Arrow Right' && <AiOutlineArrowRight size={12} stroke='none' fontWeight={100} />}
@@ -17,7 +17,7 @@ const TerritoryRectangle = ({ label, text, stroke, strokeWidth, textColor, hasPa
17
17
  d='M40,0.5 C41.2426407,0.5 42.3676407,1.00367966 43.1819805,1.81801948 C43.9963203,2.63235931 44.5,3.75735931 44.5,5 L44.5,5 L44.5,23 C44.5,24.2426407 43.9963203,25.3676407 43.1819805,26.1819805 C42.3676407,26.9963203 41.2426407,27.5 40,27.5 L40,27.5 L5,27.5 C3.75735931,27.5 2.63235931,26.9963203 1.81801948,26.1819805 C1.00367966,25.3676407 0.5,24.2426407 0.5,23 L0.5,23 L0.5,5 C0.5,3.75735931 1.00367966,2.63235931 1.81801948,1.81801948 C2.63235931,1.00367966 3.75735931,0.5 5,0.5 L5,0.5 Z'
18
18
  {...props}
19
19
  />
20
- <text textAnchor='middle' dominantBaseline='middle' x='50%' y='54%' fill={text} style={{ stroke: textColor, strokeWidth: 1 }} className='territory-text' paint-order='stroke'>
20
+ <text textAnchor='middle' dominantBaseline='middle' x='50%' y='54%' fill={text} style={{ stroke: textColor, strokeWidth: 1 }} className='territory-text' paintOrder='stroke'>
21
21
  {label}
22
22
  </text>
23
23
 
@@ -127,7 +127,9 @@ const CountyMap = props => {
127
127
  handleMapAriaLabels,
128
128
  runtimeLegend,
129
129
  state,
130
- runtimeFilters
130
+ runtimeFilters,
131
+ tooltipId,
132
+ isEditor
131
133
  } = useContext(ConfigContext)
132
134
 
133
135
  // CREATE STATE LINES
@@ -138,7 +140,7 @@ const CountyMap = props => {
138
140
 
139
141
  const pathGenerator = geoPath().projection(geoAlbersUsaTerritories())
140
142
 
141
- const { featureArray } = useMapLayers(state, '', pathGenerator, false)
143
+ const { featureArray } = useMapLayers(state, '', pathGenerator, tooltipId)
142
144
 
143
145
  useEffect(() => {
144
146
  if (containerEl) {
@@ -322,7 +324,7 @@ const CountyMap = props => {
322
324
 
323
325
  tooltipRef.current.style.display = 'block'
324
326
  tooltipRef.current.style.top = e.clientY + 'px'
325
- tooltipRef.current.style.left = e.clientX + 'px'
327
+ tooltipRef.current.style.left = isEditor ? Number(e.clientX - 350) + 'px' : e.clientX + 'px'
326
328
  tooltipRef.current.innerHTML = applyTooltipsToGeo(displayGeoName(county.id), data[county.id])
327
329
  tooltipRef.current.setAttribute('data-index', countyIndex)
328
330
  } else {
@@ -520,8 +522,9 @@ const CountyMap = props => {
520
522
  tooltipRef.current.setAttribute('data-index', null)
521
523
  }}
522
524
  onClick={canvasClick}
525
+ className='county-map-canvas'
523
526
  ></canvas>
524
- <div ref={tooltipRef} id='canvas-tooltip' className='tooltip' style={{ background: `rgba(255,255,255,${state.tooltips.opacity / 100})` }}></div>
527
+ <div ref={tooltipRef} id={`tooltip__${tooltipId}`} className='tooltip' style={{ background: `rgba(255,255,255,${state.tooltips.opacity / 100})` }}></div>
525
528
  <button className={`btn btn--reset`} onClick={onReset} ref={resetButton} tabIndex='0'>
526
529
  Reset Zoom
527
530
  </button>
@@ -41,6 +41,7 @@ const UsaRegionMap = props => {
41
41
  handleMapAriaLabels,
42
42
  state,
43
43
  supportedTerritories,
44
+ tooltipId
44
45
  } = useContext(ConfigContext)
45
46
 
46
47
  // "Choose State" options
@@ -111,7 +112,7 @@ const UsaRegionMap = props => {
111
112
  }
112
113
  }
113
114
 
114
- 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} />
115
+ return <Shape key={label} label={label} css={styles} text={styles.color} stroke={geoStrokeColor} strokeWidth={1.5} onClick={() => geoClickHandler(territory, territoryData)} data-tooltip-id={`tooltip__${tooltipId}`} data-tooltip-html={toolTip} />
115
116
  }
116
117
  })
117
118
 
@@ -201,7 +202,7 @@ const UsaRegionMap = props => {
201
202
  const circleRadius = 15
202
203
 
203
204
  return (
204
- <g key={key} className='geo-group' style={styles} onClick={() => geoClickHandler(geoDisplayName, geoData)} data-tooltip-id='tooltip' data-tooltip-html={toolTip} tabIndex={-1}>
205
+ <g key={key} className='geo-group' style={styles} onClick={() => geoClickHandler(geoDisplayName, geoData)} data-tooltip-id={`tooltip__${tooltipId}`} data-tooltip-html={toolTip} tabIndex={-1}>
205
206
  <path tabIndex={-1} className='single-geo' stroke={geoStrokeColor} strokeWidth={1.3} d={path} />
206
207
  <g id={`region-${index + 1}-label`}>
207
208
  <circle fill='#fff' stroke='#999' cx={circleRadius} cy={circleRadius} r={circleRadius} />
@@ -112,7 +112,8 @@ const SingleStateMap = props => {
112
112
  titleCase,
113
113
  setSharedFilterValue,
114
114
  isFilterValueSupported,
115
- runtimeFilters
115
+ runtimeFilters,
116
+ tooltipId
116
117
  } = useContext(ConfigContext)
117
118
 
118
119
  const projection = geoAlbersUsaTerritories().translate([WIDTH / 2, HEIGHT / 2])
@@ -236,13 +237,13 @@ const SingleStateMap = props => {
236
237
  }
237
238
 
238
239
  return (
239
- <g key={`key--${county.id}`} className={`county county--${geoDisplayName.split(' ').join('')} county--${geoData[state.columns.geo.name]}`} style={styles} onClick={() => geoClickHandler(geoDisplayName, geoData)} data-tooltip-id='tooltip' data-tooltip-html={toolTip}>
240
+ <g key={`key--${county.id}`} className={`county county--${geoDisplayName.split(' ').join('')} county--${geoData[state.columns.geo.name]}`} style={styles} onClick={() => geoClickHandler(geoDisplayName, geoData)} data-tooltip-id={`tooltip__${tooltipId}`} data-tooltip-html={toolTip}>
240
241
  <path tabIndex={-1} className={`county`} stroke={geoStrokeColor} d={countyPath} strokeWidth={0.75 / scale} />
241
242
  </g>
242
243
  )
243
244
  } else {
244
245
  return (
245
- <g key={`key--${county.id}`} className={`county county--${geoDisplayName.split(' ').join('')}`} style={{ fill: '#e6e6e6' }} data-tooltip-id='tooltip' data-tooltip-html={toolTip}>
246
+ <g key={`key--${county.id}`} className={`county county--${geoDisplayName.split(' ').join('')}`} style={{ fill: '#e6e6e6' }} data-tooltip-id={`tooltip__${tooltipId}`} data-tooltip-html={toolTip}>
246
247
  <path tabIndex={-1} className={`county`} stroke={geoStrokeColor} d={countyPath} strokeWidth={0.75 / scale} />
247
248
  </g>
248
249
  )
@@ -264,6 +265,7 @@ const SingleStateMap = props => {
264
265
  titleCase={titleCase}
265
266
  setSharedFilterValue={setSharedFilterValue}
266
267
  isFilterValueSupported={isFilterValueSupported}
268
+ tooltipId={tooltipId}
267
269
  />
268
270
  )
269
271
 
@@ -64,6 +64,7 @@ const UsaMap = () => {
64
64
  state,
65
65
  supportedTerritories,
66
66
  titleCase,
67
+ tooltipId
67
68
  } = useContext<MapContext>(ConfigContext)
68
69
 
69
70
  let isFilterValueSupported = false
@@ -163,7 +164,20 @@ const UsaMap = () => {
163
164
 
164
165
  return (
165
166
  <>
166
- <Shape key={label} label={label} style={styles} text={styles.color} strokeWidth={1.5} textColor={textColor} onClick={() => geoClickHandler(territory, territoryData)} data-tooltip-id='tooltip' data-tooltip-html={toolTip} territory={territory} territoryData={territoryData} tabIndex={-1} />
167
+ <Shape
168
+ key={label}
169
+ label={label}
170
+ style={styles}
171
+ text={styles.color}
172
+ strokeWidth={1.5}
173
+ textColor={textColor}
174
+ onClick={() => geoClickHandler(territory, territoryData)}
175
+ data-tooltip-id={`tooltip__${tooltipId}`}
176
+ data-tooltip-html={toolTip}
177
+ territory={territory}
178
+ territoryData={territoryData}
179
+ tabIndex={-1}
180
+ />
167
181
  </>
168
182
  )
169
183
  }
@@ -172,7 +186,7 @@ const UsaMap = () => {
172
186
  let pathGenerator = geoPath().projection(geoAlbersUsa().translate(translate))
173
187
 
174
188
  // Note: Layers are different than patterns
175
- const { pathArray } = useMapLayers(state, '', pathGenerator)
189
+ const { pathArray } = useMapLayers(state, '', pathGenerator, tooltipId)
176
190
 
177
191
  // Constructs and displays markup for all geos on the map (except territories right now)
178
192
  const constructGeoJsx = (geographies, projection) => {
@@ -261,33 +275,33 @@ const UsaMap = () => {
261
275
  switch (item.operator) {
262
276
  case '=':
263
277
  if (geoData[item.key] === item.value || Number(geoData[item.key]) === Number(item.value)) {
264
- return <HexIcon item={item} index={itemIndex} centroid={centroid} iconSize={iconSize} />
278
+ return <HexIcon textColor={textColor} item={item} index={itemIndex} centroid={centroid} iconSize={iconSize} />
265
279
  }
266
280
  break
267
281
  case '≠':
268
282
  if (geoData[item.key] !== item.value && Number(geoData[item.key]) !== Number(item.value)) {
269
- return <HexIcon item={item} index={itemIndex} centroid={centroid} iconSize={iconSize} />
283
+ return <HexIcon textColor={textColor} item={item} index={itemIndex} centroid={centroid} iconSize={iconSize} />
270
284
  }
271
285
  break
272
286
  case '<':
273
287
  if (Number(geoData[item.key]) < Number(item.value)) {
274
- return <HexIcon item={item} index={itemIndex} centroid={centroid} iconSize={iconSize} />
288
+ return <HexIcon textColor={textColor} item={item} index={itemIndex} centroid={centroid} iconSize={iconSize} />
275
289
  }
276
290
  break
277
291
  case '>':
278
292
  if (Number(geoData[item.key]) > Number(item.value)) {
279
- return <HexIcon item={item} index={itemIndex} centroid={centroid} iconSize={iconSize} />
293
+ return <HexIcon textColor={textColor} item={item} index={itemIndex} centroid={centroid} iconSize={iconSize} />
280
294
  }
281
295
  break
282
296
  case '<=':
283
297
  if (Number(geoData[item.key]) <= Number(item.value)) {
284
- return <HexIcon item={item} index={itemIndex} centroid={centroid} iconSize={iconSize} />
298
+ return <HexIcon textColor={textColor} item={item} index={itemIndex} centroid={centroid} iconSize={iconSize} />
285
299
  }
286
300
  break
287
301
  case '>=':
288
302
  if (item.operator === '>=') {
289
303
  if (Number(geoData[item.key]) >= Number(item.value)) {
290
- return <HexIcon item={item} index={itemIndex} centroid={centroid} iconSize={iconSize} />
304
+ return <HexIcon textColor={textColor} item={item} index={itemIndex} centroid={centroid} iconSize={iconSize} />
291
305
  }
292
306
  }
293
307
  break
@@ -302,7 +316,7 @@ const UsaMap = () => {
302
316
 
303
317
  return (
304
318
  <g data-name={geoName} key={key} tabIndex={-1}>
305
- <g className='geo-group' style={styles} onClick={() => geoClickHandler(geoDisplayName, geoData)} id={geoName} data-tooltip-id='tooltip' data-tooltip-html={tooltip} tabIndex={-1}>
319
+ <g className='geo-group' style={styles} onClick={() => geoClickHandler(geoDisplayName, geoData)} id={geoName} data-tooltip-id={`tooltip__${tooltipId}`} data-tooltip-html={tooltip} tabIndex={-1}>
306
320
  {/* state path */}
307
321
  <path tabIndex={-1} className='single-geo' strokeWidth={1.3} d={path} />
308
322
 
@@ -311,7 +325,7 @@ const UsaMap = () => {
311
325
  const { pattern, dataKey, size } = patternData
312
326
  const currentFill = styles.fill
313
327
  const hasMatchingValues = patternData.dataValue === geoData[patternData.dataKey]
314
- const patternColor = getContrastColor('#000', currentFill)
328
+ const patternColor = patternData.color || getContrastColor('#000', currentFill)
315
329
 
316
330
  return (
317
331
  hasMatchingValues && (
@@ -358,6 +372,7 @@ const UsaMap = () => {
358
372
  setSharedFilterValue={setSharedFilterValue}
359
373
  state={state}
360
374
  titleCase={titleCase}
375
+ tooltipId={tooltipId}
361
376
  />
362
377
  )
363
378
 
@@ -34,7 +34,8 @@ const WorldMap = props => {
34
34
  setState,
35
35
  state,
36
36
  supportedCountries,
37
- titleCase
37
+ titleCase,
38
+ tooltipId
38
39
  } = useContext(ConfigContext)
39
40
 
40
41
  // TODO Refactor - state should be set together here to avoid rerenders
@@ -155,7 +156,20 @@ const WorldMap = props => {
155
156
  }
156
157
 
157
158
  return (
158
- <Geo additionalData={additionalData} geoData={geoData} state={state} key={i + '-geo'} style={styles} path={path} stroke={geoStrokeColor} strokeWidth={strokeWidth} onClick={() => geoClickHandler(geoDisplayName, geoData)} data-tooltip-id='tooltip' data-tooltip-html={toolTip} tabIndex={-1} />
159
+ <Geo
160
+ additionalData={additionalData}
161
+ geoData={geoData}
162
+ state={state}
163
+ key={i + '-geo'}
164
+ style={styles}
165
+ path={path}
166
+ stroke={geoStrokeColor}
167
+ strokeWidth={strokeWidth}
168
+ onClick={() => geoClickHandler(geoDisplayName, geoData)}
169
+ data-tooltip-id={`tooltip__${tooltipId}`}
170
+ data-tooltip-html={toolTip}
171
+ tabIndex={-1}
172
+ />
159
173
  )
160
174
  }
161
175
 
@@ -164,7 +178,7 @@ const WorldMap = props => {
164
178
  })
165
179
 
166
180
  // Cities
167
- geosJsx.push(<CityList applyLegendToRow={applyLegendToRow} applyTooltipsToGeo={applyTooltipsToGeo} data={data} displayGeoName={displayGeoName} geoClickHandler={geoClickHandler} key='cities' projection={projection} state={state} titleCase={titleCase} />)
181
+ geosJsx.push(<CityList applyLegendToRow={applyLegendToRow} applyTooltipsToGeo={applyTooltipsToGeo} data={data} displayGeoName={displayGeoName} geoClickHandler={geoClickHandler} key='cities' projection={projection} state={state} titleCase={titleCase} tooltipId={tooltipId} />)
168
182
 
169
183
  // Bubbles
170
184
  if (state.general.type === 'bubble') {
@@ -178,6 +192,7 @@ const WorldMap = props => {
178
192
  applyLegendToRow={applyLegendToRow}
179
193
  applyTooltipsToGeo={applyTooltipsToGeo}
180
194
  displayGeoName={displayGeoName}
195
+ tooltipId={tooltipId}
181
196
  handleCircleClick={country => handleCircleClick(country, state, setState, setRuntimeData, generateRuntimeData)}
182
197
  />
183
198
  )
@@ -684,6 +684,7 @@ export const supportedCities = {
684
684
  'VIRGINIA BEACH': [-75.977982, 36.852924],
685
685
  'WARREN': [-80.8184, 41.2376],
686
686
  'WASHINGTON D.C.': [-77.036873, 38.907192],
687
+ 'DC': [-77.036873, 38.907192],
687
688
  'WASHINGTON DC.': [-77.036873, 38.907192],
688
689
  'WASHINGTON DC': [-77.036873, 38.907192],
689
690
  'WICHITA': [-97.330055, 37.687176],
@@ -16,7 +16,7 @@ import { MapConfig } from '../types/MapConfig'
16
16
  * 3) Clean (ie. mapshaper -clean) and edit the shape as needed and export the new layer as geoJSON
17
17
  * 4) Save the geoJSON somewhere external.
18
18
  */
19
- export default function useMapLayers(config: MapConfig, setConfig, pathGenerator) {
19
+ export default function useMapLayers(config: MapConfig, setConfig, pathGenerator, tooltipId) {
20
20
  const [fetchedTopoJSON, setFetchedTopoJSON] = useState([])
21
21
  const geoId = useId()
22
22
 
@@ -158,7 +158,7 @@ export default function useMapLayers(config: MapConfig, setConfig, pathGenerator
158
158
  key={geoId} data-id={geoId}
159
159
  stroke={config.map.layers[index].stroke ? config.map.layers[index].stroke : item.properties.stroke ? item.properties.stroke : 'transparent'}
160
160
  strokeWidth={config.map.layers[index].strokeWidth ? config.map.layers[index].strokeWidth : item.properties['stroke-width']}
161
- data-tooltip-id='tooltip'
161
+ data-tooltip-id={`tooltip__${tooltipId}`}
162
162
  data-tooltip-html={config.map.layers[index].tooltip ? config.map.layers[index].tooltip : ''}
163
163
  />
164
164
  </Group>
@@ -82,7 +82,7 @@
82
82
  color: #000;
83
83
  font-size: 1em;
84
84
  border: 0;
85
- position: absolute;
85
+ position: fixed;
86
86
  z-index: 100;
87
87
  transition: 0.1s background;
88
88
  cursor: pointer;
@@ -110,17 +110,6 @@
110
110
  }
111
111
 
112
112
  .editor-panel {
113
- background: #fff;
114
- width: $editorWidth;
115
- overflow-y: overlay;
116
- position: absolute;
117
- z-index: 7;
118
- display: flex;
119
- flex-direction: column;
120
- left: 0;
121
- top: 0;
122
- bottom: 0;
123
-
124
113
  //TODO: Remove after COVE refactor
125
114
  &.cove {
126
115
  @import '@cdc/core/styles/v2/layout/tooltip.scss';
@@ -40,6 +40,7 @@
40
40
  border: 0;
41
41
  text-align: left;
42
42
  max-width: 100%;
43
+ background-color: white;
43
44
  .btn {
44
45
  padding: 0.375em 0.75em;
45
46
  border-radius: 0.3em;
@@ -129,7 +130,7 @@
129
130
  svg {
130
131
  display: inline-block;
131
132
  max-width: 13px;
132
- margin-left: .5em;
133
+ margin-left: 0.5em;
133
134
  }
134
135
  }
135
136
  &.capitalize p {
package/src/scss/map.scss CHANGED
@@ -365,7 +365,7 @@ canvas {
365
365
  width: 100%;
366
366
  }
367
367
 
368
- #canvas-tooltip {
368
+ .county-map-canvas + .tooltip {
369
369
  position: fixed;
370
370
  background-color: white;
371
371
  pointer-events: none;