@cdc/chart 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 (87) hide show
  1. package/dist/cdcchart.js +44197 -38258
  2. package/examples/cases-year.json +13379 -0
  3. package/examples/feature/annotations/index.json +542 -0
  4. package/examples/gallery/bar-chart-vertical/combo-line-chart.json +76 -15
  5. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json +5 -5
  6. package/examples/xaxis.json +493 -0
  7. package/index.html +20 -10
  8. package/package.json +5 -4
  9. package/src/CdcChart.tsx +462 -172
  10. package/src/_stories/Chart.Legend.Gradient.tsx +19 -0
  11. package/src/_stories/Chart.stories.tsx +18 -171
  12. package/src/_stories/ChartAnnotation.stories.tsx +32 -0
  13. package/src/_stories/_mock/annotation_category_mock.json +473 -0
  14. package/src/_stories/_mock/annotation_date-linear_mock.json +530 -0
  15. package/{examples/feature/line/line-chart.json → src/_stories/_mock/annotation_date-time_mock.json} +150 -69
  16. package/src/_stories/_mock/legend.gradient_mock.json +236 -0
  17. package/src/_stories/_mock/line_chart_two_points_new_chart.json +128 -0
  18. package/src/_stories/_mock/line_chart_two_points_regression_test.json +127 -0
  19. package/src/_stories/_mock/lollipop.json +171 -0
  20. package/src/components/Annotations/components/AnnotationDraggable.styles.css +31 -0
  21. package/src/components/Annotations/components/AnnotationDraggable.tsx +207 -0
  22. package/src/components/Annotations/components/AnnotationDropdown.styles.css +14 -0
  23. package/src/components/Annotations/components/AnnotationDropdown.tsx +72 -0
  24. package/src/components/Annotations/components/AnnotationList.styles.css +45 -0
  25. package/src/components/Annotations/components/AnnotationList.tsx +42 -0
  26. package/src/components/Annotations/components/findNearestDatum.ts +138 -0
  27. package/src/components/Annotations/components/helpers/index.tsx +46 -0
  28. package/src/components/Annotations/index.tsx +13 -0
  29. package/src/components/AreaChart/components/AreaChart.Stacked.jsx +1 -1
  30. package/src/components/AreaChart/components/AreaChart.jsx +1 -1
  31. package/src/components/Axis/Categorical.Axis.tsx +145 -0
  32. package/src/components/BarChart/components/BarChart.Horizontal.tsx +47 -44
  33. package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +0 -1
  34. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +11 -14
  35. package/src/components/BarChart/components/BarChart.Vertical.tsx +67 -30
  36. package/src/components/BarChart/helpers/index.ts +91 -0
  37. package/src/components/BrushChart.tsx +205 -0
  38. package/src/components/EditorPanel/EditorPanel.tsx +1794 -403
  39. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +320 -0
  40. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +282 -18
  41. package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +43 -8
  42. package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +4 -4
  43. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +4 -13
  44. package/src/components/EditorPanel/components/Panels/index.tsx +3 -1
  45. package/src/components/EditorPanel/components/panels.scss +4 -0
  46. package/src/components/EditorPanel/editor-panel.scss +35 -3
  47. package/src/components/EditorPanel/{useEditorPermissions.js → useEditorPermissions.ts} +105 -17
  48. package/src/components/Legend/Legend.Component.tsx +185 -194
  49. package/src/components/Legend/Legend.Suppression.tsx +146 -0
  50. package/src/components/Legend/Legend.tsx +21 -5
  51. package/src/components/Legend/helpers/createFormatLabels.tsx +1 -1
  52. package/src/components/Legend/helpers/index.ts +35 -0
  53. package/src/components/LegendWrapper.tsx +26 -0
  54. package/src/components/LineChart/LineChartProps.ts +1 -15
  55. package/src/components/LineChart/components/LineChart.BumpCircle.tsx +103 -0
  56. package/src/components/LineChart/components/LineChart.Circle.tsx +47 -8
  57. package/src/components/LineChart/helpers.ts +72 -14
  58. package/src/components/LineChart/index.tsx +117 -42
  59. package/src/components/LinearChart.jsx +179 -136
  60. package/src/components/LinearChart.tsx +1366 -0
  61. package/src/components/PairedBarChart.jsx +9 -9
  62. package/src/components/PieChart/PieChart.tsx +75 -18
  63. package/src/components/Sankey/index.tsx +89 -30
  64. package/src/components/ScatterPlot/ScatterPlot.jsx +22 -8
  65. package/src/components/Sparkline/components/SparkLine.tsx +2 -2
  66. package/src/components/ZoomBrush.tsx +90 -44
  67. package/src/data/initial-state.js +25 -7
  68. package/src/helpers/handleChartTabbing.ts +8 -0
  69. package/src/helpers/isConvertLineToBarGraph.ts +4 -0
  70. package/src/hooks/{useBarChart.js → useBarChart.ts} +2 -40
  71. package/src/hooks/useColorScale.ts +1 -1
  72. package/src/hooks/useLegendClasses.ts +68 -0
  73. package/src/hooks/useMinMax.ts +12 -7
  74. package/src/hooks/useScales.ts +58 -26
  75. package/src/hooks/useTooltip.tsx +135 -25
  76. package/src/scss/DataTable.scss +2 -1
  77. package/src/scss/main.scss +128 -28
  78. package/src/types/ChartConfig.ts +83 -10
  79. package/src/types/ChartContext.ts +14 -4
  80. package/tests-examples/helpers/testZeroValue.test.ts +30 -0
  81. package/LICENSE +0 -201
  82. package/src/components/BrushHandle.jsx +0 -17
  83. package/src/components/LineChart/index.scss +0 -1
  84. package/src/helpers/filterData.ts +0 -18
  85. package/src/helpers/tests/computeMarginBottom.test.ts +0 -21
  86. package/src/hooks/useLegendClasses.js +0 -31
  87. /package/src/hooks/{useReduceData.js → useReduceData.ts} +0 -0
@@ -0,0 +1,128 @@
1
+ {
2
+ "allowLineToBarGraph": true,
3
+ "type": "chart",
4
+ "visualizationType": "Line",
5
+ "xAxis": {
6
+ "dataKey": "STATE"
7
+ },
8
+ "series": [
9
+ {
10
+ "dataKey": "Rate"
11
+ }
12
+ ],
13
+ "filters": [
14
+ {
15
+ "values": ["Home", "School", "Vehicle", "Work"],
16
+ "active": "Home",
17
+ "order": "asc",
18
+ "columnName": "Location",
19
+ "setByQueryParameter": "location"
20
+ }
21
+ ],
22
+ "data": [
23
+ {
24
+ "STATE": "AL",
25
+ "Rate": "10",
26
+ "Location": "Home",
27
+ "URL": "https://www.cdc.gov/",
28
+ "Intensity Level": "Low",
29
+ "Trajectory": "Increasing"
30
+ },
31
+ {
32
+ "STATE": "AK",
33
+ "Rate": "12",
34
+ "Location": "Home",
35
+ "URL": "https://www.cdc.gov/",
36
+ "Intensity Level": "Low",
37
+ "Trajectory": "Increasing"
38
+ },
39
+ {
40
+ "STATE": "FL",
41
+ "Rate": "10",
42
+ "Location": "Work",
43
+ "URL": "https://www.cdc.gov/",
44
+ "Intensity Level": "Low",
45
+ "Trajectory": "Increasing"
46
+ },
47
+ {
48
+ "STATE": "GA",
49
+ "Rate": "12",
50
+ "Location": "Work",
51
+ "URL": "https://www.cdc.gov/",
52
+ "Intensity Level": "Low",
53
+ "Trajectory": "Increasing"
54
+ },
55
+ {
56
+ "STATE": "AL",
57
+ "Rate": "10",
58
+ "Location": "Work",
59
+ "URL": "https://www.cdc.gov/",
60
+ "Intensity Level": "Low",
61
+ "Trajectory": "Increasing"
62
+ },
63
+ {
64
+ "STATE": "AK",
65
+ "Rate": "12",
66
+ "Location": "Work",
67
+ "URL": "https://www.cdc.gov/",
68
+ "Intensity Level": "Low",
69
+ "Trajectory": "Increasing"
70
+ }
71
+ ],
72
+ "dataFileName": "hex-data.csv",
73
+ "dataFileSourceType": "file",
74
+ "formattedData": [
75
+ {
76
+ "STATE": "AL",
77
+ "Rate": "10",
78
+ "Location": "Home",
79
+ "URL": "https://www.cdc.gov/",
80
+ "Intensity Level": "Low",
81
+ "Trajectory": "Increasing"
82
+ },
83
+ {
84
+ "STATE": "AK",
85
+ "Rate": "12",
86
+ "Location": "Home",
87
+ "URL": "https://www.cdc.gov/",
88
+ "Intensity Level": "Low",
89
+ "Trajectory": "Increasing"
90
+ },
91
+ {
92
+ "STATE": "AL",
93
+ "Rate": "10",
94
+ "Location": "Work",
95
+ "URL": "https://www.cdc.gov/",
96
+ "Intensity Level": "Low",
97
+ "Trajectory": "Increasing"
98
+ },
99
+ {
100
+ "STATE": "AK",
101
+ "Rate": "12",
102
+ "Location": "Work",
103
+ "URL": "https://www.cdc.gov/",
104
+ "Intensity Level": "Low",
105
+ "Trajectory": "Increasing"
106
+ },
107
+ {
108
+ "STATE": "FL",
109
+ "Rate": "10",
110
+ "Location": "Work",
111
+ "URL": "https://www.cdc.gov/",
112
+ "Intensity Level": "Low",
113
+ "Trajectory": "Increasing"
114
+ },
115
+ {
116
+ "STATE": "GA",
117
+ "Rate": "12",
118
+ "Location": "Work",
119
+ "URL": "https://www.cdc.gov/",
120
+ "Intensity Level": "Low",
121
+ "Trajectory": "Increasing"
122
+ }
123
+ ],
124
+ "dataDescription": {
125
+ "horizontal": false,
126
+ "series": false
127
+ }
128
+ }
@@ -0,0 +1,127 @@
1
+ {
2
+ "type": "chart",
3
+ "visualizationType": "Line",
4
+ "xAxis": {
5
+ "dataKey": "STATE"
6
+ },
7
+ "series": [
8
+ {
9
+ "dataKey": "Rate"
10
+ }
11
+ ],
12
+ "filters": [
13
+ {
14
+ "values": ["Home", "School", "Vehicle", "Work"],
15
+ "active": "Home",
16
+ "order": "asc",
17
+ "columnName": "Location",
18
+ "setByQueryParameter": "location"
19
+ }
20
+ ],
21
+ "data": [
22
+ {
23
+ "STATE": "AL",
24
+ "Rate": "10",
25
+ "Location": "Home",
26
+ "URL": "https://www.cdc.gov/",
27
+ "Intensity Level": "Low",
28
+ "Trajectory": "Increasing"
29
+ },
30
+ {
31
+ "STATE": "AK",
32
+ "Rate": "12",
33
+ "Location": "Home",
34
+ "URL": "https://www.cdc.gov/",
35
+ "Intensity Level": "Low",
36
+ "Trajectory": "Increasing"
37
+ },
38
+ {
39
+ "STATE": "FL",
40
+ "Rate": "10",
41
+ "Location": "Work",
42
+ "URL": "https://www.cdc.gov/",
43
+ "Intensity Level": "Low",
44
+ "Trajectory": "Increasing"
45
+ },
46
+ {
47
+ "STATE": "GA",
48
+ "Rate": "12",
49
+ "Location": "Work",
50
+ "URL": "https://www.cdc.gov/",
51
+ "Intensity Level": "Low",
52
+ "Trajectory": "Increasing"
53
+ },
54
+ {
55
+ "STATE": "AL",
56
+ "Rate": "10",
57
+ "Location": "Work",
58
+ "URL": "https://www.cdc.gov/",
59
+ "Intensity Level": "Low",
60
+ "Trajectory": "Increasing"
61
+ },
62
+ {
63
+ "STATE": "AK",
64
+ "Rate": "12",
65
+ "Location": "Work",
66
+ "URL": "https://www.cdc.gov/",
67
+ "Intensity Level": "Low",
68
+ "Trajectory": "Increasing"
69
+ }
70
+ ],
71
+ "dataFileName": "hex-data.csv",
72
+ "dataFileSourceType": "file",
73
+ "formattedData": [
74
+ {
75
+ "STATE": "AL",
76
+ "Rate": "10",
77
+ "Location": "Home",
78
+ "URL": "https://www.cdc.gov/",
79
+ "Intensity Level": "Low",
80
+ "Trajectory": "Increasing"
81
+ },
82
+ {
83
+ "STATE": "AK",
84
+ "Rate": "12",
85
+ "Location": "Home",
86
+ "URL": "https://www.cdc.gov/",
87
+ "Intensity Level": "Low",
88
+ "Trajectory": "Increasing"
89
+ },
90
+ {
91
+ "STATE": "AL",
92
+ "Rate": "10",
93
+ "Location": "Work",
94
+ "URL": "https://www.cdc.gov/",
95
+ "Intensity Level": "Low",
96
+ "Trajectory": "Increasing"
97
+ },
98
+ {
99
+ "STATE": "AK",
100
+ "Rate": "12",
101
+ "Location": "Work",
102
+ "URL": "https://www.cdc.gov/",
103
+ "Intensity Level": "Low",
104
+ "Trajectory": "Increasing"
105
+ },
106
+ {
107
+ "STATE": "FL",
108
+ "Rate": "10",
109
+ "Location": "Work",
110
+ "URL": "https://www.cdc.gov/",
111
+ "Intensity Level": "Low",
112
+ "Trajectory": "Increasing"
113
+ },
114
+ {
115
+ "STATE": "GA",
116
+ "Rate": "12",
117
+ "Location": "Work",
118
+ "URL": "https://www.cdc.gov/",
119
+ "Intensity Level": "Low",
120
+ "Trajectory": "Increasing"
121
+ }
122
+ ],
123
+ "dataDescription": {
124
+ "horizontal": false,
125
+ "series": false
126
+ }
127
+ }
@@ -0,0 +1,171 @@
1
+ {
2
+ "type": "chart",
3
+ "title": "Lollipop Style Horizontal Bar Chart - Number of Spills Occurring in the Home",
4
+ "showTitle": true,
5
+ "showDownloadMediaButton": false,
6
+ "theme": "theme-blue",
7
+ "animate": true,
8
+ "fontSize": "medium",
9
+ "lineDatapointStyle": "hover",
10
+ "barHasBorder": "false",
11
+ "isLollipopChart": true,
12
+ "lollipopShape": "circle",
13
+ "lollipopColorStyle": "two-tone",
14
+ "visualizationSubType": "horizontal",
15
+ "barStyle": "",
16
+ "roundingStyle": "standard",
17
+ "tipRounding": "top",
18
+ "isResponsiveTicks": false,
19
+ "general": { "showDownloadButton": false },
20
+ "padding": { "left": 5, "right": 5 },
21
+ "yAxis": {
22
+ "hideAxis": true,
23
+ "displayNumbersOnBar": true,
24
+ "hideLabel": false,
25
+ "hideTicks": false,
26
+ "size": "13",
27
+ "gridLines": false,
28
+ "enablePadding": false,
29
+ "min": "",
30
+ "max": "",
31
+ "labelColor": "#333",
32
+ "tickLabelColor": "#333",
33
+ "tickColor": "#333",
34
+ "rightHideAxis": true,
35
+ "rightAxisSize": 50,
36
+ "rightLabel": "",
37
+ "rightLabelOffsetSize": 0,
38
+ "rightAxisLabelColor": "#333",
39
+ "rightAxisTickLabelColor": "#333",
40
+ "rightAxisTickColor": "#333",
41
+ "numTicks": "9",
42
+ "axisPadding": 0,
43
+ "tickRotation": 0,
44
+ "anchors": [],
45
+ "type": "chart",
46
+ "title": "Lollipop Style Horizontal Bar Chart",
47
+ "theme": "theme-blue",
48
+ "fontSize": "medium",
49
+ "lineDatapointStyle": "hover",
50
+ "barHasBorder": "false",
51
+ "isLollipopChart": false,
52
+ "lollipopShape": "circle",
53
+ "lollipopColorStyle": "two-tone",
54
+ "visualizationSubType": "horizontal",
55
+ "padding": { "left": 5, "right": 5 },
56
+ "yAxis": { "size": 50, "gridLines": false },
57
+ "barThickness": 0.35,
58
+ "height": 260,
59
+ "xAxis": { "type": "categorical", "size": 75, "tickRotation": 0, "dataKey": "Vehicle" },
60
+ "table": { "label": "Data Table", "expanded": true, "show": true },
61
+ "legend": { "behavior": "isolate", "position": "right" },
62
+ "exclusions": { "active": false, "keys": [] },
63
+ "palette": "qualitative-bold",
64
+ "labels": false,
65
+ "dataFormat": {},
66
+ "confidenceKeys": {},
67
+ "data": [
68
+ { "Group": "Combined Total of Group A", "Vehicle": "100", "Home": "120", "Work": "140", "Office": "120" },
69
+ { "Group": "Combined Total of Group B", "Vehicle": "150", "Home": "140", "Work": "100", "Office": "90" },
70
+ { "Group": "Combined Total of Group C", "Vehicle": "90", "Home": "90", "Work": "80", "Office": "80" },
71
+ { "Group": "Combined Total of Group D", "Vehicle": "70", "Home": "60", "Work": "50", "Office": "70" }
72
+ ],
73
+ "dataFileName": "CSV_Source_Example_for_Horizontal_Bar_viz-cdcwp1619811744363.csv",
74
+ "dataFileSourceType": "file",
75
+ "visualizationType": "Bar",
76
+ "runtime": {
77
+ "seriesLabels": { "Vehicle": "Vehicle" },
78
+ "seriesLabelsAll": ["Vehicle"],
79
+ "originalXAxis": { "type": "categorical", "size": 75, "tickRotation": 0, "dataKey": "Vehicle" },
80
+ "seriesKeys": ["Vehicle"],
81
+ "xAxis": { "size": 50, "gridLines": false },
82
+ "yAxis": { "type": "categorical", "size": 75, "tickRotation": 0, "dataKey": "Vehicle" },
83
+ "horizontal": true,
84
+ "uniqueId": 1651765968212,
85
+ "editorErrorMessage": ""
86
+ },
87
+ "description": "Subtext can be added here for options like citing data sources or insight into reading the bar chart.",
88
+ "series": [{ "dataKey": "Vehicle", "type": "Bar" }],
89
+ "barHeight": 25,
90
+ "barPadding": 40,
91
+ "labelPlacement": "Below Bar",
92
+ "label": "Number of Accidents"
93
+ },
94
+ "boxplot": [],
95
+ "topAxis": { "hasLine": false },
96
+ "isLegendValue": false,
97
+ "barThickness": 0.35,
98
+ "barHeight": 6,
99
+ "barSpace": 15,
100
+ "heights": { "vertical": 300, "horizontal": 170.39999999999998 },
101
+ "xAxis": {
102
+ "anchors": [],
103
+ "type": "categorical",
104
+ "showTargetLabel": true,
105
+ "targetLabel": "Target",
106
+ "hideAxis": true,
107
+ "hideLabel": true,
108
+ "hideTicks": true,
109
+ "size": "16",
110
+ "tickRotation": 0,
111
+ "min": "",
112
+ "max": "160",
113
+ "labelColor": "#333",
114
+ "tickLabelColor": "#333",
115
+ "tickColor": "#333",
116
+ "numTicks": "",
117
+ "labelOffset": 65,
118
+ "axisPadding": 0,
119
+ "target": 0,
120
+ "maxTickRotation": 0,
121
+ "dataKey": "Group"
122
+ },
123
+ "table": { "label": "Data Table", "expanded": false, "limitHeight": false, "height": "", "caption": "", "showDownloadUrl": false, "showDataTableLink": true, "indexLabel": "Group", "download": false, "showVertical": true, "show": true },
124
+ "orientation": "horizontal",
125
+ "color": "pinkpurple",
126
+ "columns": {},
127
+ "legend": {
128
+ "behavior": "isolate",
129
+ "singleRow": false,
130
+ "colorCode": "",
131
+ "reverseLabelOrder": false,
132
+ "description": "",
133
+ "dynamicLegend": false,
134
+ "dynamicLegendDefaultText": "Show All",
135
+ "dynamicLegendItemLimit": 5,
136
+ "dynamicLegendItemLimitMessage": "Dynamic Legend Item Limit Hit.",
137
+ "dynamicLegendChartMessage": "Select Options from the Legend",
138
+ "position": "right",
139
+ "hide": true,
140
+ "label": "Accident Location"
141
+ },
142
+ "exclusions": { "active": false, "keys": [] },
143
+ "palette": "qualitative-bold",
144
+ "isPaletteReversed": false,
145
+ "twoColor": { "palette": "monochrome-1", "isPaletteReversed": false },
146
+ "labels": false,
147
+ "dataFormat": { "commas": false, "prefix": "", "suffix": "", "abbreviated": false, "bottomSuffix": "", "bottomPrefix": "", "bottomAbbreviated": false },
148
+ "confidenceKeys": {},
149
+ "visual": { "border": true, "accent": true, "background": true, "verticalHoverLine": false, "horizontalHoverLine": false },
150
+ "useLogScale": false,
151
+ "filterBehavior": "Filter Change",
152
+ "highlightedBarValues": [],
153
+ "series": [{ "dataKey": "Home", "type": "Bar", "tooltip": true }],
154
+ "tooltips": { "opacity": 90 },
155
+ "height": 212,
156
+ "data": [
157
+ { "Group": "Combined Total of Group A", "Vehicle": "100", "Home": "120", "Work": "140", "Office": "120" },
158
+ { "Group": "Combined Total of Group B", "Vehicle": "150", "Home": "140", "Work": "100", "Office": "90" },
159
+ { "Group": "Combined Total of Group C", "Vehicle": "90", "Home": "90", "Work": "80", "Office": "80" },
160
+ { "Group": "Combined Total of Group D", "Vehicle": "70", "Home": "60", "Work": "50", "Office": "70" }
161
+ ],
162
+ "dataFileName": "CSV_Source_Example_for_Horizontal_Bar_viz-cdcwp1619811744363.csv",
163
+ "dataFileSourceType": "file",
164
+ "visualizationType": "Bar",
165
+ "description": "Subtext can be added here for options like citing data sources or insight into reading the bar chart.",
166
+ "barPadding": 47,
167
+ "filters": [],
168
+ "lollipopSize": "medium",
169
+ "validated": 4.23,
170
+ "dynamicMarginTop": 0
171
+ }
@@ -0,0 +1,31 @@
1
+ .cdc-open-viz-module .annotation__desktop-label {
2
+ display: none;
3
+ }
4
+
5
+ .cdc-open-viz-module {
6
+ .annotation__mobile-label-circle {
7
+ stroke-width: 2;
8
+ }
9
+
10
+ .annotation__has-dropdown-number {
11
+ display: flex;
12
+ justify-content: center;
13
+ align-items: center;
14
+ border-radius: 50%;
15
+ padding: 8px;
16
+ width: 16px;
17
+ height: 16px;
18
+ border: 2px solid #666;
19
+ text-align: center;
20
+ font-size: 14px;
21
+ }
22
+ }
23
+
24
+ @container content (min-width: 700px) {
25
+ .cdc-open-viz-module .annotation__mobile-label {
26
+ display: none;
27
+ }
28
+ .cdc-open-viz-module .annotation__desktop-label {
29
+ display: block;
30
+ }
31
+ }
@@ -0,0 +1,207 @@
1
+ import { useContext, useEffect, useRef, useState } from 'react'
2
+ import ConfigContext from '../../../ConfigContext'
3
+ import DOMPurify from 'dompurify'
4
+
5
+ // helpers
6
+ import { findNearestDatum } from './findNearestDatum'
7
+
8
+ // prettier-ignore
9
+ import {
10
+ applyBandScaleOffset,
11
+ handleConnectionHorizontalType,
12
+ handleConnectionVerticalType,
13
+ handleMobileXPosition,
14
+ handleMobileYPosition,
15
+ handleTextX,
16
+ handleTextY
17
+ } from './helpers'
18
+
19
+ import useColorScale from '../../../hooks/useColorScale'
20
+
21
+ // visx
22
+ import { HtmlLabel, CircleSubject, EditableAnnotation, Connector, Annotation as VisxAnnotation } from '@visx/annotation'
23
+ import { Drag } from '@visx/drag'
24
+ import { MarkerArrow } from '@visx/marker'
25
+ import { LinePath } from '@visx/shape'
26
+ import { fontSizes } from '@cdc/core/helpers/cove/fontSettings'
27
+
28
+ // styles
29
+ import './AnnotationDraggable.styles.css'
30
+
31
+ const Annotations = ({ xScale, yScale, xScaleAnnotation, xMax, svgRef, onDragStateChange }) => {
32
+ // prettier-ignore
33
+ const {
34
+ config,
35
+ currentViewport,
36
+ dimensions,
37
+ isDraggingAnnotation,
38
+ isEditor,
39
+ isLegendBottom,
40
+ updateConfig
41
+ } = useContext(ConfigContext)
42
+
43
+ // destructure config items here...
44
+ const { annotations } = config
45
+ const [height] = dimensions
46
+ const { colorScale } = useColorScale()
47
+ const AnnotationComponent = isEditor ? EditableAnnotation : VisxAnnotation
48
+
49
+ return (
50
+ annotations &&
51
+ annotations.map((annotation, index) => {
52
+ const text = annotation.text || ''
53
+
54
+ const annotationX = xScaleAnnotation(annotation.x)
55
+
56
+ // sanitize the text for setting dangerouslySetInnerHTML
57
+ const sanitizedData = () => ({
58
+ __html: DOMPurify.sanitize(text)
59
+ })
60
+
61
+ return (
62
+ <AnnotationComponent
63
+ width={200}
64
+ height={height}
65
+ dx={annotation.dx} // label position
66
+ dy={annotation.dy} // label postion
67
+ x={annotationX}
68
+ y={annotation.y}
69
+ canEditLabel={annotation.edit.label || false}
70
+ canEditSubject={(annotation.edit.subject && annotation.connectionType !== 'none') || false}
71
+ onDragStart={() => onDragStateChange(true)}
72
+ onDragEnd={props => {
73
+ onDragStateChange(false)
74
+
75
+ let updatedAnnotations = [...annotations]
76
+
77
+ if (annotation.x === xScaleAnnotation.invert(props.x) && annotation.y === props.y) {
78
+ updatedAnnotations[index] = { ...updatedAnnotations[index], dx: props.dx, dy: props.dy }
79
+ } else {
80
+ if (annotation.snapToNearestPoint) {
81
+ let nearestDatum = findNearestDatum(
82
+ {
83
+ data: config.data,
84
+ xScale,
85
+ yScale,
86
+ config,
87
+ xMax: xMax - config.yAxis.size / 2,
88
+ annotationSeriesKey: annotation.seriesKey
89
+ },
90
+ props.x
91
+ )
92
+
93
+ updatedAnnotations[index] = {
94
+ ...updatedAnnotations[index],
95
+ x: xScaleAnnotation.invert(xScale(nearestDatum.x)),
96
+ y: yScale(nearestDatum.y)
97
+ }
98
+ } else {
99
+ updatedAnnotations[index] = {
100
+ ...updatedAnnotations[index],
101
+ x: xScaleAnnotation.invert(props.x),
102
+ y: props.y
103
+ }
104
+ }
105
+ }
106
+
107
+ updateConfig({
108
+ ...config,
109
+ annotations: updatedAnnotations
110
+ })
111
+ }}
112
+ >
113
+ <HtmlLabel
114
+ className='annotation__desktop-label'
115
+ showAnchorLine={false}
116
+ horizontalAnchor={handleConnectionHorizontalType(annotation, xScale, config)}
117
+ verticalAnchor={handleConnectionVerticalType(annotation, xScale, config)}
118
+ >
119
+ <div
120
+ style={{
121
+ borderRadius: 5, // Optional: set border radius
122
+ backgroundColor: `rgba(255, 255, 255, ${annotation?.opacity ? Number(annotation?.opacity) / 100 : 1})`,
123
+ padding: '10px',
124
+ width: 'auto',
125
+ display: config.general.showAnnotationDropdown ? 'inline-flex' : 'flex',
126
+ justifyContent: 'start',
127
+ flexDirection: 'row'
128
+ }}
129
+ // role='presentation'
130
+ tabIndex={0}
131
+ aria-label={`Annotation text that reads: ${annotation.text}`}
132
+ >
133
+ {config?.general?.showAnnotationDropdown && (
134
+ <>
135
+ <p className='annotation__has-dropdown-number' style={{ margin: '2px 6px' }}>
136
+ {index + 1}
137
+ </p>
138
+ </>
139
+ )}
140
+ <div style={{ fontSize: fontSizes[config.fontSize] }} dangerouslySetInnerHTML={sanitizedData()} />
141
+ </div>
142
+ </HtmlLabel>
143
+ {annotation.connectionType === 'line' && (
144
+ <Connector type='line' pathProps={{ markerStart: `url(#marker-start--${index})` }} />
145
+ )}
146
+ {annotation.connectionType === 'elbow' && (
147
+ <Connector type='elbow' pathProps={{ markerStart: `url(#marker-start--${index})` }} />
148
+ )}
149
+ {annotation.connectionType === 'curve' && (
150
+ <LinePath
151
+ d={`M ${annotationX},${annotation.y}
152
+ Q ${annotationX + annotation.dx / 2}, ${
153
+ annotation.y + annotation.dy / 2 + Number(annotation?.bezier) || 0
154
+ } ${annotationX + annotation.dx},${annotation.y + annotation.dy}`}
155
+ stroke='black'
156
+ strokeWidth='2'
157
+ fill='none'
158
+ marker-start={`url(#marker-start--${index})`}
159
+ />
160
+ )}
161
+ {annotation.marker === 'circle' && (
162
+ <CircleSubject
163
+ id={`marker-start--${index}`}
164
+ className='circle-subject'
165
+ stroke={colorScale(annotation.seriesKey)}
166
+ radius={8}
167
+ />
168
+ )}
169
+ {annotation.marker === 'arrow' && (
170
+ <MarkerArrow
171
+ fill='black'
172
+ id={`marker-start--${index}`}
173
+ x={annotationX}
174
+ y={annotation.y}
175
+ stroke='#333'
176
+ markerWidth={10}
177
+ size={10}
178
+ strokeWidth={1}
179
+ orient='auto-start-reverse'
180
+ markerUnits='userSpaceOnUse'
181
+ />
182
+ )}
183
+ <circle
184
+ fill='white'
185
+ cx={annotationX + annotation.dx}
186
+ cy={annotation.y + annotation.dy}
187
+ r={16}
188
+ className='annotation__mobile-label annotation__mobile-label-circle'
189
+ stroke={colorScale(annotation.seriesKey)}
190
+ />
191
+ <text
192
+ height={16}
193
+ x={annotationX + annotation.dx}
194
+ y={annotation.y + annotation.dy}
195
+ className='annotation__mobile-label'
196
+ alignmentBaseline='middle'
197
+ textAnchor='middle'
198
+ >
199
+ {index + 1}
200
+ </text>
201
+ </AnnotationComponent>
202
+ )
203
+ })
204
+ )
205
+ }
206
+
207
+ export default Annotations
@@ -0,0 +1,14 @@
1
+ .cdc-open-viz-module {
2
+ .annotation__dropdown-list {
3
+ border: 1px solid red;
4
+ list-style: none;
5
+ }
6
+
7
+ .annotation-dropdown__panel {
8
+ padding: 10px;
9
+ }
10
+
11
+ .data-table-heading.annotation__dropdown-list {
12
+ margin-top: 10px;
13
+ }
14
+ }