@cdc/map 4.24.5 → 4.24.9

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 (67) hide show
  1. package/dist/cdcmap.js +71853 -64936
  2. package/examples/annotation/index.json +552 -0
  3. package/examples/annotation/usa-map.json +900 -0
  4. package/examples/county-year.csv +10 -0
  5. package/examples/default-geocode.json +44 -10
  6. package/examples/default-patterns.json +0 -2
  7. package/examples/default-single-state.json +279 -108
  8. package/examples/map-issue-3.json +646 -0
  9. package/examples/single-state-filter.json +153 -0
  10. package/index.html +10 -6
  11. package/package.json +6 -5
  12. package/src/CdcMap.tsx +367 -199
  13. package/src/_stories/CdcMap.stories.tsx +14 -0
  14. package/src/_stories/_mock/DEV-7286.json +165 -0
  15. package/src/_stories/_mock/DEV-8942.json +270 -0
  16. package/src/components/Annotation/Annotation.Draggable.styles.css +18 -0
  17. package/src/components/Annotation/Annotation.Draggable.tsx +152 -0
  18. package/src/components/Annotation/AnnotationDropdown.styles.css +14 -0
  19. package/src/components/Annotation/AnnotationDropdown.tsx +70 -0
  20. package/src/components/Annotation/AnnotationList.styles.css +45 -0
  21. package/src/components/Annotation/AnnotationList.tsx +42 -0
  22. package/src/components/Annotation/index.tsx +11 -0
  23. package/src/components/{BubbleList.jsx → BubbleList.tsx} +1 -1
  24. package/src/components/{CityList.jsx → CityList.tsx} +28 -2
  25. package/src/components/{DataTable.jsx → DataTable.tsx} +2 -2
  26. package/src/components/EditorPanel/components/EditorPanel.tsx +650 -129
  27. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +336 -0
  28. package/src/components/EditorPanel/components/{Panel.PatternSettings.tsx → Panels/Panel.PatternSettings.tsx} +63 -13
  29. package/src/components/EditorPanel/components/{Panels.tsx → Panels/index.tsx} +3 -0
  30. package/src/components/Legend/components/Legend.tsx +125 -42
  31. package/src/components/Legend/components/index.scss +42 -42
  32. package/src/components/Modal.tsx +25 -0
  33. package/src/components/UsaMap/components/SingleState/SingleState.CountyOutput.tsx +74 -0
  34. package/src/components/UsaMap/components/SingleState/SingleState.StateOutput.tsx +29 -0
  35. package/src/components/UsaMap/components/SingleState/index.tsx +9 -0
  36. package/src/components/UsaMap/components/Territory/Territory.Rectangle.tsx +4 -3
  37. package/src/components/UsaMap/components/UsaMap.County.tsx +114 -36
  38. package/src/components/UsaMap/components/UsaMap.Region.tsx +2 -0
  39. package/src/components/UsaMap/components/UsaMap.SingleState.tsx +175 -206
  40. package/src/components/UsaMap/components/UsaMap.State.tsx +188 -44
  41. package/src/components/UsaMap/data/us-extended-geography.json +1 -0
  42. package/src/components/UsaMap/helpers/map.ts +111 -0
  43. package/src/components/WorldMap/WorldMap.tsx +17 -32
  44. package/src/components/ZoomControls.tsx +41 -0
  45. package/src/data/initial-state.js +11 -2
  46. package/src/data/supported-geos.js +15 -4
  47. package/src/helpers/generateColorsArray.ts +13 -0
  48. package/src/helpers/generateRuntimeLegendHash.ts +23 -0
  49. package/src/helpers/getUniqueValues.ts +19 -0
  50. package/src/helpers/hashObj.ts +25 -0
  51. package/src/helpers/tests/generateColorsArray.test.ts +18 -0
  52. package/src/helpers/tests/generateRuntimeLegendHash.test.ts +11 -0
  53. package/src/helpers/tests/hashObj.test.ts +10 -0
  54. package/src/hooks/useStateZoom.tsx +157 -0
  55. package/src/hooks/{useZoomPan.js → useZoomPan.ts} +6 -5
  56. package/src/scss/editor-panel.scss +0 -4
  57. package/src/scss/main.scss +23 -1
  58. package/src/scss/map.scss +14 -3
  59. package/src/types/MapConfig.ts +9 -1
  60. package/src/types/MapContext.ts +16 -2
  61. package/LICENSE +0 -201
  62. package/src/components/Modal.jsx +0 -22
  63. package/src/test/CdcMap.test.jsx +0 -19
  64. /package/src/components/EditorPanel/components/{Panel.PatternSettings-style.css → Panels/Panel.PatternSettings-style.css} +0 -0
  65. /package/src/components/{Geo.jsx → Geo.tsx} +0 -0
  66. /package/src/components/{NavigationMenu.jsx → NavigationMenu.tsx} +0 -0
  67. /package/src/components/{ZoomableGroup.jsx → ZoomableGroup.tsx} +0 -0
@@ -0,0 +1,70 @@
1
+ import React, { useContext, useState } from 'react'
2
+ import ConfigContext from '../../context'
3
+ import './AnnotationDropdown.styles.css'
4
+ import Icon from '@cdc/core/components/ui/Icon'
5
+ import { fontSizes } from '@cdc/core/helpers/cove/fontSettings'
6
+ import AnnotationList from './AnnotationList'
7
+
8
+ const AnnotationDropdown = () => {
9
+ const { currentViewport: viewport, state: config } = useContext(ConfigContext)
10
+ const [expanded, setExpanded] = useState(false)
11
+
12
+ const titleFontSize = ['sm', 'xs', 'xxs'].includes(viewport) ? '13px' : `${fontSizes[config?.fontSize]}px`
13
+
14
+ const annotations = config?.annotations || []
15
+
16
+ const limitHeight = {
17
+ maxHeight: config.table.limitHeight && `${config.table.height}px`,
18
+ OverflowY: 'scroll'
19
+ }
20
+
21
+ const handleAccordionClassName = () => {
22
+ const classNames = ['data-table-heading', 'annotation__dropdown-list']
23
+ if (!expanded) {
24
+ classNames.push('collapsed')
25
+ }
26
+
27
+ return classNames.join(' ')
28
+ }
29
+
30
+ const handleSectionClasses = () => {
31
+ const classes = [`data-table-container`, viewport, `d-block`, `d-lg-none`]
32
+
33
+ if (config.general.showAnnotationDropdown) {
34
+ classes.push('d-lg-block')
35
+ classes.splice(classes.indexOf('d-lg-none'), 1)
36
+ }
37
+ return classes.join(' ')
38
+ }
39
+
40
+ return (
41
+ <>
42
+ <section className={handleSectionClasses()}>
43
+ <div
44
+ style={{ fontSize: titleFontSize }}
45
+ role='button'
46
+ className={handleAccordionClassName()}
47
+ onClick={() => {
48
+ setExpanded(!expanded)
49
+ }}
50
+ tabIndex={0}
51
+ onKeyDown={e => {
52
+ if (e.keyCode === 13) {
53
+ setExpanded(!expanded)
54
+ }
55
+ }}
56
+ >
57
+ <Icon display={expanded ? 'minus' : 'plus'} base />
58
+ {config.general.annotationDropdownText === '' ? 'Annotations' : config?.general?.annotationDropdownText}
59
+ </div>
60
+ {expanded && (
61
+ <div className='table-container annotation-dropdown__panel' style={limitHeight}>
62
+ <AnnotationList useBootstrapVisibilityClasses={false} />
63
+ </div>
64
+ )}
65
+ </section>
66
+ </>
67
+ )
68
+ }
69
+
70
+ export default AnnotationDropdown
@@ -0,0 +1,45 @@
1
+ .cdc-open-viz-module {
2
+ .annotation__title-circle {
3
+ display: flex;
4
+ justify-content: center;
5
+ align-items: center;
6
+ border-radius: 50%;
7
+ padding: 8px;
8
+ width: 16px;
9
+ height: 16px;
10
+ margin-right: 5px;
11
+ line-height: 1.5rem;
12
+
13
+ border: 2px solid #666;
14
+ text-align: center;
15
+ font-size: 14px;
16
+ }
17
+
18
+ .annotation__title-wrapper {
19
+ display: flex;
20
+ flex-wrap: nowrap;
21
+ align-items: center;
22
+ }
23
+
24
+ .annotation__title-wrapper .annotation__title-text {
25
+ margin-left: 5px;
26
+ font-size: 16px;
27
+ }
28
+
29
+ .annotation__subtext {
30
+ font-size: 12px;
31
+ }
32
+
33
+ .annotation-list {
34
+ list-style: none;
35
+ }
36
+
37
+ .annotation-list li {
38
+ margin-top: 5px;
39
+ }
40
+
41
+ .cove-component__content {
42
+ container-type: inline-size;
43
+ container-name: content;
44
+ }
45
+ }
@@ -0,0 +1,42 @@
1
+ import React, { useContext } from 'react'
2
+ import ConfigContext from './../../context'
3
+ import './AnnotationList.styles.css'
4
+ import DOMPurify from 'dompurify'
5
+
6
+ type AnnotationListProps = {
7
+ useBootstrapVisibilityClasses?: boolean
8
+ }
9
+
10
+ const AnnotationList: React.FC<AnnotationListProps> = ({ useBootstrapVisibilityClasses = true }) => {
11
+ const { state: config } = useContext(ConfigContext)
12
+ const annotations = config.annotations || []
13
+
14
+ const ulClasses = () => {
15
+ const classes = ['annotation-list']
16
+ if (useBootstrapVisibilityClasses) {
17
+ classes.push('d-block', 'd-md-none')
18
+ }
19
+ return classes.join(' ')
20
+ }
21
+
22
+ const annotationListItems = annotations.map((annotation, annotationIndex) => {
23
+ const text = annotation.text || ''
24
+
25
+ // sanitize the text for setting dangerouslySetInnerHTML
26
+ const sanitizedData = () => ({
27
+ __html: DOMPurify.sanitize(text)
28
+ })
29
+ return (
30
+ <li key={`annotation-li-item__annotationIndex`}>
31
+ <div className='annotation__title-wrapper'>
32
+ <div className='annotation__title-circle'>{annotationIndex + 1}</div>
33
+ <p className='annotation__subtext' dangerouslySetInnerHTML={sanitizedData()} />
34
+ </div>
35
+ </li>
36
+ )
37
+ })
38
+
39
+ return <ul className={ulClasses()}>{annotationListItems}</ul>
40
+ }
41
+
42
+ export default AnnotationList
@@ -0,0 +1,11 @@
1
+ import Draggable from './Annotation.Draggable'
2
+ import AnnotationDropdown from './AnnotationDropdown'
3
+ import AnnotationList from './AnnotationList'
4
+
5
+ const Annotation = {
6
+ Draggable,
7
+ Dropdown: AnnotationDropdown,
8
+ List: AnnotationList
9
+ }
10
+
11
+ export default Annotation
@@ -2,7 +2,7 @@ import React, { useContext, useEffect } from 'react'
2
2
  import { scaleLinear } from 'd3-scale'
3
3
  import { countryCoordinates } from '../data/country-coordinates'
4
4
  import stateCoordinates from '../data/state-coordinates'
5
- import ConfigContext from './../../src/context'
5
+ import ConfigContext from '../context'
6
6
 
7
7
  export const BubbleList = ({ data: dataImport, state, projection, applyLegendToRow, applyTooltipsToGeo, handleCircleClick, runtimeData, displayGeoName }) => {
8
8
  const maxDataValue = Math.max(...dataImport.map(d => d[state.columns.primary.name]))
@@ -1,12 +1,17 @@
1
- import { useState, useEffect } from 'react'
1
+ import { useState, useEffect, useContext } from 'react'
2
2
 
3
3
  import { jsx } from '@emotion/react'
4
4
  import { supportedCities } from '../data/supported-geos'
5
5
  import { scaleLinear } from 'd3-scale'
6
6
  import { GlyphStar, GlyphTriangle, GlyphDiamond, GlyphSquare, GlyphCircle } from '@visx/glyph'
7
+ import { getFilterControllingStatePicked } from './UsaMap/helpers/map'
7
8
 
8
- const CityList = ({ data, state, geoClickHandler, applyTooltipsToGeo, displayGeoName, applyLegendToRow, projection, titleCase, setSharedFilterValue, isFilterValueSupported, tooltipId }) => {
9
+ import ConfigContext from '../context'
10
+
11
+ const CityList = ({ data, geoClickHandler, applyTooltipsToGeo, displayGeoName, applyLegendToRow, titleCase, setSharedFilterValue, isFilterValueSupported, tooltipId, projection }) => {
9
12
  const [citiesData, setCitiesData] = useState({})
13
+ const { scale, state, topoData, runtimeData, position } = useContext(ConfigContext)
14
+ if (!projection) return
10
15
 
11
16
  useEffect(() => {
12
17
  const citiesDictionary = {}
@@ -91,6 +96,27 @@ const CityList = ({ data, state, geoClickHandler, applyTooltipsToGeo, displayGeo
91
96
  needsPointer = true
92
97
  }
93
98
 
99
+ if (geoData?.[state.columns.longitude.name] && geoData?.[state.columns.latitude.name] && state.general.geoType === 'single-state') {
100
+ const statePicked = getFilterControllingStatePicked(state, runtimeData)
101
+ const _statePickedData = topoData?.states?.find(s => s.properties.name === statePicked)
102
+ // SVG ITEMS
103
+ const WIDTH = 880
104
+ const HEIGHT = 500
105
+ const PADDING = 50
106
+
107
+ const newProjection = projection.fitExtent(
108
+ [
109
+ [PADDING, PADDING],
110
+ [WIDTH - PADDING, HEIGHT - PADDING]
111
+ ],
112
+ _statePickedData
113
+ )
114
+ let coords = [Number(geoData?.[state.columns.longitude.name]), Number(geoData?.[state.columns.latitude.name])]
115
+ console.log('COORDINATES', coords)
116
+ transform = `translate(${newProjection(coords)}) scale(${state.visual.geoCodeCircleSize / (position.zoom > 1 ? position.zoom : 1)})`
117
+ needsPointer = true
118
+ }
119
+
94
120
  if (!transform) {
95
121
  return
96
122
  }
@@ -5,7 +5,7 @@ import ExternalIcon from '../images/external-link.svg' // TODO: Move to Icon com
5
5
  import Icon from '@cdc/core/components/ui/Icon'
6
6
 
7
7
  import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
8
- import LegendCircle from '@cdc/core/components/LegendCircle'
8
+ import LegendShape from '@cdc/core/components/LegendShape'
9
9
  import MediaControls from '@cdc/core/components/MediaControls'
10
10
  import SkipTo from '@cdc/core/components/elements/SkipTo'
11
11
 
@@ -274,7 +274,7 @@ const DataTable = props => {
274
274
 
275
275
  cellValue = (
276
276
  <>
277
- <LegendCircle fill={legendColor[0]} />
277
+ <LegendShape fill={legendColor[0]} />
278
278
  {labelValue}
279
279
  </>
280
280
  )