@cdc/map 4.24.2 → 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.
Files changed (38) hide show
  1. package/dist/cdcmap.js +33089 -32197
  2. package/examples/508.json +548 -0
  3. package/examples/default-county.json +0 -28
  4. package/examples/default-hex.json +110 -13
  5. package/examples/default-usa.json +69 -28
  6. package/examples/example-city-state.json +51 -17
  7. package/examples/hex-colors.json +507 -0
  8. package/examples/usa-special-class-legend.json +501 -0
  9. package/index.html +10 -9
  10. package/package.json +3 -3
  11. package/src/CdcMap.tsx +200 -125
  12. package/src/components/BubbleList.jsx +16 -6
  13. package/src/components/CityList.jsx +64 -12
  14. package/src/components/DataTable.jsx +7 -7
  15. package/src/components/EditorPanel/components/EditorPanel.tsx +1457 -1367
  16. package/src/components/EditorPanel/components/Error.tsx +12 -0
  17. package/src/components/EditorPanel/components/HexShapeSettings.tsx +16 -1
  18. package/src/components/EditorPanel/components/Panel.PatternSettings-style.css +5 -0
  19. package/src/components/EditorPanel/components/Panel.PatternSettings.tsx +18 -1
  20. package/src/components/Legend/components/Legend.tsx +80 -15
  21. package/src/components/Legend/components/LegendItem.Hex.tsx +1 -1
  22. package/src/components/Legend/components/index.scss +31 -5
  23. package/src/components/UsaMap/components/HexIcon.tsx +41 -0
  24. package/src/components/UsaMap/components/Territory/Territory.Hexagon.tsx +38 -19
  25. package/src/components/UsaMap/components/Territory/Territory.Rectangle.tsx +11 -22
  26. package/src/components/UsaMap/components/UsaMap.County.tsx +7 -4
  27. package/src/components/UsaMap/components/UsaMap.Region.tsx +13 -38
  28. package/src/components/UsaMap/components/UsaMap.SingleState.tsx +5 -3
  29. package/src/components/UsaMap/components/UsaMap.State.tsx +77 -60
  30. package/src/components/UsaMap/helpers/patternSizes.tsx +5 -0
  31. package/src/components/WorldMap/components/WorldMap.jsx +20 -3
  32. package/src/data/initial-state.js +3 -0
  33. package/src/data/supported-geos.js +2 -1
  34. package/src/hooks/useMapLayers.tsx +2 -2
  35. package/src/scss/editor-panel.scss +4 -12
  36. package/src/scss/main.scss +3 -1
  37. package/src/scss/map.scss +1 -1
  38. package/src/types/MapConfig.ts +7 -0
@@ -3,8 +3,9 @@ import { useState, useEffect } from 'react'
3
3
  import { jsx } from '@emotion/react'
4
4
  import { supportedCities } from '../data/supported-geos'
5
5
  import { scaleLinear } from 'd3-scale'
6
+ import { GlyphStar, GlyphTriangle, GlyphDiamond, GlyphSquare, GlyphCircle } from '@visx/glyph'
6
7
 
7
- const CityList = ({ data, state, geoClickHandler, applyTooltipsToGeo, displayGeoName, applyLegendToRow, projection, titleCase, setSharedFilterValue, isFilterValueSupported }) => {
8
+ const CityList = ({ data, state, geoClickHandler, applyTooltipsToGeo, displayGeoName, applyLegendToRow, projection, titleCase, setSharedFilterValue, isFilterValueSupported, tooltipId }) => {
8
9
  const [citiesData, setCitiesData] = useState({})
9
10
 
10
11
  useEffect(() => {
@@ -60,18 +61,18 @@ const CityList = ({ data, state, geoClickHandler, applyTooltipsToGeo, displayGeo
60
61
  fillOpacity: state.general.type === 'bubble' ? 0.4 : 1
61
62
  }
62
63
 
63
- const circle = <circle 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)} data-tooltip-id='tooltip' data-tooltip-html={toolTip} {...additionalProps} />
64
-
65
64
  const pin = (
66
65
  <path
67
66
  className='marker'
68
67
  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'
69
- title='Click for more information'
68
+ title='Select for more information'
70
69
  onClick={() => geoClickHandler(cityDisplayName, geoData)}
71
- strokeWidth={2}
72
- stroke={'black'}
73
- data-tooltip-id='tooltip'
70
+ data-tooltip-id={`tooltip__${tooltipId}`}
74
71
  data-tooltip-html={toolTip}
72
+ transform={`scale(${radius / 9})`}
73
+ stroke={state.general.geoBorderColor === 'sameAsBackground' ? '#ffffff' : '#000000'}
74
+ strokeWidth={'2px'}
75
+ tabIndex='-1'
75
76
  {...additionalProps}
76
77
  />
77
78
  )
@@ -96,8 +97,8 @@ const CityList = ({ data, state, geoClickHandler, applyTooltipsToGeo, displayGeo
96
97
 
97
98
  const styles = {
98
99
  fill: legendColors[0],
99
- opacity: setSharedFilterValue && isFilterValueSupported && data[city][state.columns.geo.name] !== setSharedFilterValue ? 0.5 : 1,
100
- stroke: setSharedFilterValue && isFilterValueSupported && data[city][state.columns.geo.name] === setSharedFilterValue ? 'rgba(0, 0, 0, 1)' : 'rgba(0, 0, 0, 0.4)',
100
+ opacity: setSharedFilterValue && isFilterValueSupported && data[city] && data[city][state.columns.geo.name] !== setSharedFilterValue ? 0.5 : 1,
101
+ stroke: setSharedFilterValue && isFilterValueSupported && data[city] && data[city][state.columns.geo.name] === setSharedFilterValue ? 'rgba(0, 0, 0, 1)' : 'rgba(0, 0, 0, 0.4)',
101
102
  '&:hover': {
102
103
  fill: legendColors[1],
103
104
  outline: 0
@@ -114,10 +115,61 @@ const CityList = ({ data, state, geoClickHandler, applyTooltipsToGeo, displayGeo
114
115
  styles.cursor = 'pointer'
115
116
  }
116
117
 
118
+ const shapeProps = {
119
+ onClick: () => geoClickHandler(cityDisplayName, geoData),
120
+ size: state.general.type === 'bubble' ? size(geoData[state.columns.primary.name]) : radius * 30,
121
+ title: 'Select for more information',
122
+ 'data-tooltip-id': `tooltip__${tooltipId}`,
123
+ 'data-tooltip-html': toolTip,
124
+ stroke: state.general.geoBorderColor === 'sameAsBackground' ? '#ffffff' : '#000000',
125
+ strokeWidth: '2px',
126
+ tabIndex: -1,
127
+ ...additionalProps
128
+ }
129
+
130
+ const cityStyleShapes = {
131
+ circle: <GlyphCircle {...shapeProps} />,
132
+ pin: pin,
133
+ square: <GlyphSquare {...shapeProps} />,
134
+ diamond: <GlyphDiamond {...shapeProps} />,
135
+ star: <GlyphStar {...shapeProps} />,
136
+ triangle: <GlyphTriangle {...shapeProps} />
137
+ }
138
+
139
+ const { additionalCityStyles } = state.visual || []
140
+ const cityStyle = Object.values(data)
141
+ .filter(d => additionalCityStyles.some(style => String(d[style.column]) === String(style.value)))
142
+ .map(d => {
143
+ const conditionsMatched = additionalCityStyles.find(style => String(d[style.column]) === String(style.value))
144
+ return { ...conditionsMatched, ...d }
145
+ })
146
+ .find(item => {
147
+ return Object.keys(item).find(key => item[key] === city)
148
+ })
149
+
150
+ if (cityStyle !== undefined && cityStyle.shape) {
151
+ if (!geoData?.[state.columns.longitude.name] && !geoData?.[state.columns.latitude.name] && city && supportedCities[city.toUpperCase()]) {
152
+ let translate = `translate(${projection(supportedCities[city.toUpperCase()])})`
153
+ return (
154
+ <g key={i} transform={translate} style={styles} className='geo-point' tabIndex={-1}>
155
+ {cityStyleShapes[cityStyle.shape.toLowerCase()]}
156
+ </g>
157
+ )
158
+ }
159
+
160
+ if (geoData?.[state.columns.longitude.name] && geoData?.[state.columns.latitude.name]) {
161
+ const coords = [Number(geoData?.[state.columns.longitude.name]), Number(geoData?.[state.columns.latitude.name])]
162
+ let translate = `translate(${projection(coords)})`
163
+ return (
164
+ <g key={i} transform={translate} style={styles} className='geo-point' tabIndex={-1}>
165
+ {cityStyleShapes[cityStyle.shape.toLowerCase()]}
166
+ </g>
167
+ )
168
+ }
169
+ }
117
170
  return (
118
- <g key={i} transform={transform} style={styles} className='geo-point'>
119
- {state.visual.cityStyle === 'circle' && circle}
120
- {state.visual.cityStyle === 'pin' && pin}
171
+ <g key={i} transform={transform} style={styles} className='geo-point' tabIndex={-1}>
172
+ {cityStyleShapes[state.visual.cityStyle.toLowerCase()]}
121
173
  </g>
122
174
  )
123
175
  })
@@ -7,6 +7,7 @@ import Icon from '@cdc/core/components/ui/Icon'
7
7
  import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
8
8
  import LegendCircle from '@cdc/core/components/LegendCircle'
9
9
  import MediaControls from '@cdc/core/components/MediaControls'
10
+ import SkipTo from '@cdc/core/components/elements/SkipTo'
10
11
 
11
12
  import Loading from '@cdc/core/components/Loading'
12
13
 
@@ -193,9 +194,7 @@ const DataTable = props => {
193
194
  {state.general.showDownloadButton && <DownloadButton />}
194
195
  </MediaControls.Section>
195
196
  <section id={tabbingId.replace('#', '')} className={`data-table-container ${viewport}`} aria-label={accessibilityLabel}>
196
- <a id='skip-nav' className='cdcdataviz-sr-only-focusable' href={`#${skipId}`}>
197
- Skip Navigation or Skip to Content
198
- </a>
197
+ <SkipTo skipId={skipId} skipMessage='Skip Data Table' />
199
198
  <div
200
199
  className={expanded ? 'data-table-heading' : 'collapsed data-table-heading'}
201
200
  onClick={() => {
@@ -229,7 +228,7 @@ const DataTable = props => {
229
228
  return (
230
229
  <th
231
230
  key={`col-header-${column}`}
232
- tabIndex='0'
231
+ tabIndex={0}
233
232
  title={text}
234
233
  role='columnheader'
235
234
  scope='col'
@@ -245,9 +244,7 @@ const DataTable = props => {
245
244
  {...(sortBy.column === column ? (sortBy.asc ? { 'aria-sort': 'ascending' } : { 'aria-sort': 'descending' }) : null)}
246
245
  >
247
246
  {text}
248
- <button>
249
- <span className='cdcdataviz-sr-only'>{`Sort by ${text} in ${sortBy.column === column ? (!sortBy.asc ? 'descending' : 'ascending') : 'descending'} `} order</span>
250
- </button>
247
+ <span className='cdcdataviz-sr-only'>{`Sort by ${text} in ${sortBy.column === column ? (!sortBy.asc ? 'descending' : 'ascending') : 'descending'} order`}</span>
251
248
  </th>
252
249
  )
253
250
  })}
@@ -298,6 +295,9 @@ const DataTable = props => {
298
295
  </table>
299
296
  </div>
300
297
  </section>
298
+ <div id={skipId} className='cdcdataviz-sr-only'>
299
+ Skipped data table.
300
+ </div>
301
301
  </ErrorBoundary>
302
302
  )
303
303
  }