@cdc/chart 4.26.1 → 4.26.3

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 (173) hide show
  1. package/CLAUDE.local.md +79 -0
  2. package/LICENSE +201 -0
  3. package/dist/{cdcchart-dgT_1dIT.es.js → cdcchart-DQ00cQCm.es.js} +1 -20
  4. package/dist/cdcchart.js +54742 -49796
  5. package/examples/data/data-with-metadata.json +10 -0
  6. package/examples/default.json +378 -0
  7. package/examples/feature/__data__/horizon-chart-data.json +373 -0
  8. package/examples/feature/annotations/index.json +3 -6
  9. package/examples/feature/horizon/horizon-chart.json +395 -0
  10. package/examples/feature/pie/planet-pie-example-config.json +2 -1
  11. package/examples/line-chart-states.json +1085 -0
  12. package/examples/metadata-variables.json +58 -0
  13. package/examples/private/123.json +694 -0
  14. package/examples/private/anchor-issue.json +4094 -0
  15. package/examples/private/backwards-slider.json +10430 -0
  16. package/examples/private/georgia.csv +160 -0
  17. package/examples/private/timeline-data.json +1 -0
  18. package/examples/private/timeline.json +389 -0
  19. package/examples/radar-chart-simple.json +133 -0
  20. package/examples/radar-chart.json +148 -0
  21. package/index.html +1 -31
  22. package/package.json +57 -59
  23. package/src/CdcChart.tsx +8 -4
  24. package/src/CdcChartComponent.tsx +398 -284
  25. package/src/_stories/Chart.Anchors.stories.tsx +10 -0
  26. package/src/_stories/Chart.BoxPlot.stories.tsx +7 -0
  27. package/src/_stories/Chart.CI.stories.tsx +13 -0
  28. package/src/_stories/Chart.Combo.stories.tsx +17 -0
  29. package/src/_stories/Chart.CustomColors.stories.tsx +78 -0
  30. package/src/_stories/Chart.Defaults.stories.tsx +95 -0
  31. package/src/_stories/Chart.DynamicSeries.stories.tsx +19 -0
  32. package/src/_stories/Chart.Filters.stories.tsx +4 -0
  33. package/src/_stories/Chart.Forecast.stories.tsx +4 -0
  34. package/src/_stories/Chart.HTMLInDataTable.stories.tsx +22 -0
  35. package/src/_stories/Chart.Legend.Gradient.stories.tsx +28 -0
  36. package/src/_stories/Chart.Patterns.stories.tsx +4 -0
  37. package/src/_stories/Chart.PreserveDecimals.stories.tsx +25 -0
  38. package/src/_stories/Chart.Regions.Categorical.stories.tsx +13 -0
  39. package/src/_stories/Chart.Regions.DateScale.stories.tsx +19 -0
  40. package/src/_stories/Chart.Regions.DateTimeScale.stories.tsx +25 -10
  41. package/src/_stories/Chart.ScatterPlot.stories.tsx +4 -0
  42. package/src/_stories/Chart.SmallMultiples.stories.tsx +16 -0
  43. package/src/_stories/Chart.SmallestLeftAxisMax.stories.tsx +64 -0
  44. package/src/_stories/Chart.stories.tsx +72 -1
  45. package/src/_stories/Chart.tooltip.stories.tsx +7 -0
  46. package/src/_stories/ChartAnnotation.stories.tsx +10 -0
  47. package/src/_stories/ChartAxisLabels.stories.tsx +4 -0
  48. package/src/_stories/ChartAxisTitles.stories.tsx +10 -0
  49. package/src/_stories/ChartBar.Editor.stories.tsx +97 -38
  50. package/src/_stories/ChartBrush.Editor.stories.tsx +11 -25
  51. package/src/_stories/ChartBrush.Matrix.Continuous.stories.tsx +41 -0
  52. package/src/_stories/ChartBrush.Matrix.Date.stories.tsx +114 -0
  53. package/src/_stories/ChartBrush.Matrix.DateTime.stories.tsx +78 -0
  54. package/src/_stories/ChartBrush.stories.tsx +7 -0
  55. package/src/_stories/ChartEditor.Editor.stories.tsx +1 -1
  56. package/src/_stories/ChartEditor.stories.tsx +7 -0
  57. package/src/_stories/ChartLine.QuadrantAngles.stories.tsx +89 -0
  58. package/src/_stories/ChartLine.Suppression.stories.tsx +7 -0
  59. package/src/_stories/ChartLine.Symbols.stories.tsx +4 -0
  60. package/src/_stories/ChartPrefixSuffix.stories.tsx +46 -1
  61. package/src/_stories/TechAdoptionWithLinks.stories.tsx +7 -0
  62. package/src/_stories/_mock/brush_continuous.json +86 -0
  63. package/src/_stories/_mock/brush_date_large.json +176 -0
  64. package/src/_stories/_mock/line_chart_angle_near_zero_fall.json +195 -0
  65. package/src/_stories/_mock/line_chart_angle_near_zero_rise.json +195 -0
  66. package/src/_stories/_mock/line_chart_angle_q1_steep_upward.json +195 -0
  67. package/src/_stories/_mock/line_chart_angle_q2_gentle_downward.json +195 -0
  68. package/src/_stories/_mock/line_chart_angle_q3_steep_downward.json +195 -0
  69. package/src/_stories/_mock/line_chart_angle_q4_gentle_upward.json +195 -0
  70. package/src/_stories/_mock/line_chart_quadrant_angles.json +264 -0
  71. package/src/_stories/_mock/paired-bar-abbr.json +421 -0
  72. package/src/_stories/_mock/pie_custom_colors.json +268 -0
  73. package/src/_stories/_mock/smallest_left_axis_max.json +104 -0
  74. package/src/components/Annotations/components/AnnotationDraggable.styles.css +14 -20
  75. package/src/components/Annotations/components/AnnotationDraggable.tsx +240 -116
  76. package/src/components/Annotations/components/AnnotationDropdown.styles.css +1 -2
  77. package/src/components/Annotations/components/AnnotationDropdown.tsx +8 -12
  78. package/src/components/Annotations/components/AnnotationList.styles.css +12 -18
  79. package/src/components/Annotations/components/AnnotationList.tsx +5 -4
  80. package/src/components/Annotations/components/findNearestDatum.ts +75 -85
  81. package/src/components/Annotations/helpers/getVisibleAnnotations.ts +38 -0
  82. package/src/components/Axis/BottomAxis.tsx +277 -0
  83. package/src/components/Axis/LeftAxis.tsx +404 -0
  84. package/src/components/Axis/LeftAxisGridlines.tsx +77 -0
  85. package/src/components/Axis/PairedBarAxis.tsx +192 -0
  86. package/src/components/Axis/README.md +94 -0
  87. package/src/components/Axis/RightAxis.tsx +108 -0
  88. package/src/components/Axis/axis.constants.ts +21 -0
  89. package/src/components/Axis/index.ts +7 -0
  90. package/src/components/BarChart/components/BarChart.Horizontal.tsx +12 -28
  91. package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +12 -30
  92. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +12 -31
  93. package/src/components/BarChart/components/BarChart.Vertical.tsx +12 -28
  94. package/src/components/BarChart/components/BarChart.tsx +7 -1
  95. package/src/components/BarChart/helpers/getPatternUrl.ts +94 -0
  96. package/src/components/BarChart/helpers/tests/getPatternUrl.test.ts +134 -0
  97. package/src/components/BarChart/helpers/useBarChart.ts +3 -0
  98. package/src/components/Brush/BrushSelector.tsx +155 -22
  99. package/src/components/Brush/MiniChartPreview.tsx +133 -21
  100. package/src/components/EditorPanel/EditorPanel.tsx +81 -54
  101. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +67 -29
  102. package/src/components/EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx +0 -78
  103. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +120 -2
  104. package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +25 -43
  105. package/src/components/EditorPanel/components/Panels/Panel.Radar.tsx +353 -0
  106. package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +83 -3
  107. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +66 -43
  108. package/src/components/EditorPanel/components/Panels/index.tsx +2 -0
  109. package/src/components/EditorPanel/editor-panel.scss +1 -1
  110. package/src/components/EditorPanel/useEditorPermissions.ts +55 -26
  111. package/src/components/ForestPlot/ForestPlot.tsx +26 -22
  112. package/src/components/HorizonChart/HorizonChart.tsx +131 -0
  113. package/src/components/HorizonChart/components/HorizonBand.tsx +160 -0
  114. package/src/components/HorizonChart/helpers/calculateHorizonBands.ts +27 -0
  115. package/src/components/HorizonChart/helpers/getHorizonLayerColors.ts +40 -0
  116. package/src/components/HorizonChart/index.tsx +3 -0
  117. package/src/components/Legend/Legend.Component.tsx +52 -4
  118. package/src/components/Legend/Legend.tsx +1 -1
  119. package/src/components/Legend/LegendGroup/LegendGroup.styles.css +4 -4
  120. package/src/components/Legend/LegendValueRange.tsx +77 -0
  121. package/src/components/Legend/helpers/createFormatLabels.tsx +16 -2
  122. package/src/components/Legend/helpers/generateValueRanges.ts +92 -0
  123. package/src/components/LineChart/helpers/README.md +292 -0
  124. package/src/components/LineChart/helpers/labelPositioning.test.ts +245 -0
  125. package/src/components/LineChart/helpers/labelPositioning.ts +304 -0
  126. package/src/components/LineChart/index.tsx +44 -8
  127. package/src/components/LinearChart/README.md +109 -0
  128. package/src/components/LinearChart/VisualizationRenderer.tsx +267 -0
  129. package/src/components/LinearChart/linearChart.constants.ts +84 -0
  130. package/src/components/LinearChart/tests/LinearChart.test.tsx +278 -0
  131. package/src/components/LinearChart/tests/mockConfigContext.ts +131 -0
  132. package/src/components/LinearChart/utils/tickFormatting.ts +146 -0
  133. package/src/components/LinearChart.tsx +268 -1057
  134. package/src/components/PieChart/PieChart.tsx +20 -5
  135. package/src/components/RadarChart/RadarAxis.tsx +78 -0
  136. package/src/components/RadarChart/RadarChart.tsx +298 -0
  137. package/src/components/RadarChart/RadarGrid.tsx +64 -0
  138. package/src/components/RadarChart/RadarPolygon.tsx +91 -0
  139. package/src/components/RadarChart/helpers.ts +83 -0
  140. package/src/components/RadarChart/index.tsx +3 -0
  141. package/src/components/Regions/components/Regions.tsx +6 -6
  142. package/src/components/Sankey/components/Sankey.tsx +3 -3
  143. package/src/components/Sankey/sankey.scss +1 -1
  144. package/src/components/SmallMultiples/SmallMultiples.css +5 -5
  145. package/src/components/Sparkline/index.scss +4 -2
  146. package/src/components/WarmingStripes/WarmingStripes.tsx +95 -25
  147. package/src/components/WarmingStripes/WarmingStripesGradientLegend.css +8 -8
  148. package/src/data/initial-state.js +37 -15
  149. package/src/data/legacy-defaults.ts +18 -0
  150. package/src/helpers/abbreviateNumber.ts +24 -17
  151. package/src/helpers/getChartPatternId.ts +17 -0
  152. package/src/helpers/getExcludedData.ts +4 -0
  153. package/src/helpers/getMinMax.ts +16 -2
  154. package/src/helpers/handleChartAriaLabels.ts +19 -19
  155. package/src/helpers/handleLineType.ts +22 -18
  156. package/src/helpers/seriesColumnSettings.ts +114 -0
  157. package/src/helpers/tests/countNumOfTicks.test.ts +77 -0
  158. package/src/helpers/tests/seriesColumnSettings.test.ts +84 -0
  159. package/src/hooks/useProgrammaticTooltip.ts +23 -2
  160. package/src/hooks/useRightAxis.ts +14 -0
  161. package/src/hooks/useScales.ts +99 -56
  162. package/src/hooks/useTooltip.tsx +23 -3
  163. package/src/scss/main.scss +157 -79
  164. package/src/selectors/README.md +68 -0
  165. package/src/store/chart.reducer.ts +2 -0
  166. package/src/test/CdcChart.test.jsx +2 -2
  167. package/src/types/ChartConfig.ts +22 -0
  168. package/src/types/ChartContext.ts +1 -0
  169. package/src/types/Horizon.ts +64 -0
  170. package/tests/fixtures/chart-config-with-metadata.json +29 -0
  171. package/tests/fixtures/data-with-metadata.json +10 -0
  172. package/preview.html +0 -1616
  173. package/src/components/Annotations/components/helpers/index.tsx +0 -46
@@ -1,25 +1,76 @@
1
- @import '@cdc/core/styles/v2/utils/breakpoints';
1
+ @import '@cdc/core/styles/utils/breakpoints';
2
+ @import '@cdc/core/styles/layout/wrapper-padding';
2
3
 
3
4
  .form-container {
4
5
  overflow-y: auto;
5
6
  }
6
7
 
7
- .cdc-open-viz-module.type-dashboard {
8
- .cdc-open-viz-module.type-chart.isEditor {
9
- .cdc-chart-inner-container {
8
+ .cove-visualization.type-dashboard {
9
+ .cove-visualization.type-chart.is-editor {
10
+ .cove-visualization__body {
10
11
  background: white;
11
12
  }
12
13
  }
13
14
  }
14
15
 
15
- .cdc-open-viz-module.type-chart {
16
+ .cove-visualization.type-chart {
16
17
  @import 'DataTable';
17
18
 
19
+ .cove-visualization__body {
20
+ @include cove-visualization-body-padding;
21
+ }
22
+
23
+ .cove-visualization__body.component--tp5-treatment {
24
+ background: transparent;
25
+
26
+ .cdc-callout {
27
+ box-shadow: 0 2px 4px rgb(159 159 159 / 10%);
28
+ border: 1px solid #dff2f6;
29
+ margin: 0;
30
+ padding: 1.25rem;
31
+ border-radius: 0.25rem;
32
+ position: relative;
33
+ background: transparent;
34
+
35
+ .cdc-callout__flag {
36
+ position: absolute;
37
+ top: -0.36rem;
38
+ right: 1.08rem;
39
+ width: 1.84rem;
40
+ height: auto;
41
+ }
42
+
43
+ .cove-visualization__title,
44
+ .cove-visualization__header {
45
+ background: transparent;
46
+ border: 0;
47
+ color: var(--cool-gray-90, #1f2937);
48
+ margin: 0 0 1rem;
49
+ padding: 0;
50
+ border-radius: 0;
51
+
52
+ h2 {
53
+ color: var(--cool-gray-90, #1f2937);
54
+ font-family: var(--fonts-nunito, var(--app-font-secondary));
55
+ font-size: 1.1rem;
56
+ font-weight: 700;
57
+ }
58
+ }
59
+ }
60
+ }
61
+
62
+ .cove-visualization__title,
63
+ .cove-visualization__header {
64
+ margin-bottom: 0 !important;
65
+ }
66
+
18
67
  .legend-top {
19
68
  .legend-wrapper .tooltip-boundary {
20
69
  display: flex;
21
70
  flex-wrap: wrap;
71
+ row-gap: var(--cove-visualization-section-gap, 1.5rem);
22
72
  order: 2;
73
+
23
74
  aside {
24
75
  width: 100%;
25
76
  order: 1;
@@ -31,13 +82,16 @@
31
82
  .legend-wrapper {
32
83
  display: flex;
33
84
  flex-wrap: wrap;
85
+ row-gap: var(--cove-visualization-section-gap, 1.5rem);
86
+
34
87
  aside {
35
88
  width: 100%;
89
+ margin-top: var(--cove-visualization-section-gap, 1.5rem) !important;
36
90
  }
37
91
  }
38
92
  }
39
93
 
40
- &.isEditor .cdc-chart-inner-container {
94
+ &.is-editor .cove-visualization__body {
41
95
  background: white;
42
96
  }
43
97
 
@@ -47,11 +101,6 @@
47
101
  margin-bottom: 20px;
48
102
  }
49
103
 
50
- .subtext,
51
- .subtext--responsive-ticks,
52
- .section-subtext {
53
- }
54
-
55
104
  .type-pie {
56
105
  svg.animated-pie {
57
106
  width: auto !important;
@@ -60,7 +109,6 @@
60
109
 
61
110
  .legend-container {
62
111
  #supression-tooltip {
63
- font-family: 'Nunito', sans-serif;
64
112
  font-size: 0.8337rem;
65
113
  font-weight: 400;
66
114
  max-width: 16.7rem;
@@ -70,6 +118,7 @@
70
118
  white-space: normal;
71
119
  line-height: 1.4;
72
120
  }
121
+
73
122
  background: #fff;
74
123
  width: 100%;
75
124
  vertical-align: top;
@@ -101,6 +150,7 @@
101
150
  flex-direction: column;
102
151
  row-gap: var(--space-between-legend-item-rows);
103
152
  column-gap: var(--space-between-legend-item-columns);
153
+
104
154
  &.double-column,
105
155
  &.single-row {
106
156
  display: grid;
@@ -126,6 +176,7 @@
126
176
  text-align: left;
127
177
  user-select: none;
128
178
  line-height: var(--legend-item-font-size);
179
+
129
180
  .visx-legend-label {
130
181
  word-wrap: break-word;
131
182
  white-space: pre-wrap;
@@ -137,7 +188,7 @@
137
188
  white-space: nowrap;
138
189
  }
139
190
 
140
- .legend-item > .legend-item {
191
+ .legend-item>.legend-item {
141
192
  display: inline-block;
142
193
  flex: 0 0 auto;
143
194
  }
@@ -146,10 +197,16 @@
146
197
  cursor: pointer;
147
198
  transition: 0.2s all;
148
199
 
200
+ &.not-clickable,
201
+ &.not-clickable .legend-item {
202
+ cursor: default;
203
+ }
204
+
149
205
  &.inactive {
150
206
  opacity: 0.5;
151
207
  transition: 0.2s all;
152
208
  }
209
+
153
210
  &.highlighted {
154
211
  outline: 1px solid #005ea2;
155
212
  outline-offset: 5px;
@@ -165,10 +222,11 @@
165
222
  left: 0%;
166
223
  top: 108%;
167
224
 
168
- & > * {
225
+ &>* {
169
226
  margin: 0;
170
227
  }
171
- & > p,
228
+
229
+ &>p,
172
230
  a {
173
231
  margin-left: 5px;
174
232
  }
@@ -177,6 +235,7 @@
177
235
  }
178
236
 
179
237
  .dynamic-legend-list {
238
+
180
239
  // overide traditional legend item that uses !important
181
240
  .legend-item {
182
241
  align-items: flex-end !important;
@@ -209,7 +268,7 @@
209
268
  font-size: 1em;
210
269
  vertical-align: middle;
211
270
 
212
- & > span {
271
+ &>span {
213
272
  display: flex;
214
273
  justify-items: center;
215
274
  align-items: center;
@@ -219,23 +278,25 @@
219
278
  max-height: 1px;
220
279
  }
221
280
 
222
- & > span[class*='Asterisk'] {
281
+ &>span[class*='Asterisk'] {
223
282
  transform: scale(1.8);
224
283
  margin-top: 15px;
225
284
  }
226
- & > span[class*='Dagger'] {
285
+
286
+ &>span[class*='Dagger'] {
227
287
  margin-top: 2px;
228
288
  }
229
- & > span[class*='Sign'] {
289
+
290
+ &>span[class*='Sign'] {
230
291
  margin-top: 1px;
231
292
  }
232
293
 
233
- & > svg {
294
+ &>svg {
234
295
  width: 50px;
235
296
  height: 23px;
236
297
  }
237
298
 
238
- & > p {
299
+ &>p {
239
300
  margin: 0;
240
301
  }
241
302
  }
@@ -252,18 +313,37 @@
252
313
  position: relative;
253
314
  }
254
315
 
255
- .chart-container {
316
+ .visualization-container {
256
317
  display: flex;
257
318
  align-items: flex-start;
258
319
  flex-wrap: wrap;
259
320
  justify-content: space-between;
321
+ min-width: 0;
322
+ max-width: 100%;
323
+
324
+ .legend-wrapper {
325
+ min-width: 0;
326
+ max-width: 100%;
327
+
328
+ >div,
329
+ >aside {
330
+ min-width: 0;
331
+ max-width: 100%;
332
+ }
333
+ }
334
+
335
+ .tooltip-boundary {
336
+ min-width: 0;
337
+ max-width: 100%;
338
+ }
260
339
 
261
340
  &.legend-top:not(.legend-hidden) {
262
341
  .legend-wrapper {
263
- & > div {
342
+ &>div {
264
343
  order: 2;
265
344
  width: 100%;
266
345
  }
346
+
267
347
  aside {
268
348
  width: 100%;
269
349
  order: 1;
@@ -274,10 +354,11 @@
274
354
 
275
355
  &.legend-left:not(.legend-hidden) {
276
356
  .legend-wrapper {
277
- & > div {
357
+ &>div {
278
358
  order: 2;
279
359
  width: 75%;
280
360
  }
361
+
281
362
  aside {
282
363
  width: 25%;
283
364
  order: 1;
@@ -288,10 +369,11 @@
288
369
 
289
370
  &.legend-right:not(.legend-hidden) {
290
371
  .legend-wrapper {
291
- & > div {
372
+ &>div {
292
373
  order: 1;
293
374
  width: 75%;
294
375
  }
376
+
295
377
  aside {
296
378
  width: 25%;
297
379
  height: fit-content;
@@ -304,20 +386,25 @@
304
386
  display: flex;
305
387
  flex-direction: row-reverse;
306
388
  }
389
+
307
390
  &.top {
308
391
  flex-wrap: nowrap;
309
392
  flex-direction: column-reverse;
310
- & > div.tooltip-boundary {
393
+
394
+ &>div.tooltip-boundary {
311
395
  margin-top: 1.5em;
312
396
  }
313
397
  }
398
+
314
399
  &.bottom {
315
400
  flex-wrap: nowrap;
316
401
  flex-direction: column;
317
402
  }
318
- &.legend-hidden > svg {
403
+
404
+ &.legend-hidden>svg {
319
405
  width: 100% !important;
320
406
  }
407
+
321
408
  &.dashboard-brush {
322
409
  margin-bottom: 2.5em;
323
410
  }
@@ -347,7 +434,7 @@
347
434
  pointer-events: none;
348
435
  }
349
436
 
350
- > svg {
437
+ >svg {
351
438
  overflow: visible;
352
439
  font-size: 14px;
353
440
  margin: 1rem 0 2rem;
@@ -362,7 +449,7 @@
362
449
  }
363
450
 
364
451
  &.chart-line--hover {
365
- > svg circle {
452
+ >svg circle {
366
453
  opacity: 0;
367
454
 
368
455
  &:hover {
@@ -372,12 +459,12 @@
372
459
  }
373
460
 
374
461
  &.chart-line--always {
375
- > svg circle {
462
+ >svg circle {
376
463
  opacity: 1;
377
464
  }
378
465
 
379
466
  // Animations for line chart and data points
380
- > svg.animated {
467
+ >svg.animated {
381
468
  circle {
382
469
  opacity: 0;
383
470
  animation: revealLolly 0.25s linear forwards;
@@ -411,7 +498,7 @@
411
498
  }
412
499
 
413
500
  @include breakpointClass(sm) {
414
- .chart-container {
501
+ .visualization-container {
415
502
  .no-wrap {
416
503
  flex-wrap: nowrap;
417
504
  }
@@ -426,6 +513,7 @@
426
513
  margin-right: 1em;
427
514
  order: 0;
428
515
  }
516
+
429
517
  &.bottom,
430
518
  &.top {
431
519
  width: 100%;
@@ -436,8 +524,8 @@
436
524
  }
437
525
 
438
526
  @include breakpointClass(md) {
439
- .chart-container {
440
- > svg {
527
+ .visualization-container {
528
+ >svg {
441
529
  font-size: 16px;
442
530
  width: 75%;
443
531
  order: 1;
@@ -453,7 +541,6 @@
453
541
  // ANIMATIONS
454
542
  // Pie Chart Animations
455
543
  .animated-pie {
456
- margin: auto !important;
457
544
  transition: all 0.4s ease-in-out;
458
545
  opacity: 0;
459
546
  transform-origin: center;
@@ -494,6 +581,7 @@
494
581
  &.animated path.animation {
495
582
  opacity: 0;
496
583
  }
584
+
497
585
  &.animate {
498
586
  path.animation {
499
587
  opacity: 1;
@@ -501,6 +589,7 @@
501
589
  stroke-dashoffset: 4000;
502
590
  animation: dash 2s ease-in-out forwards;
503
591
  }
592
+
504
593
  @keyframes dash {
505
594
  to {
506
595
  stroke-dashoffset: 0;
@@ -519,6 +608,7 @@
519
608
  }
520
609
 
521
610
  &.animated {
611
+
522
612
  .vertical path,
523
613
  .vertical rect,
524
614
  .vertical foreignObject div {
@@ -536,6 +626,7 @@
536
626
  }
537
627
 
538
628
  &.animate {
629
+
539
630
  path,
540
631
  rect,
541
632
  foreignObject div {
@@ -593,7 +684,8 @@
593
684
  .cdc-visualization__paired-bar-chart {
594
685
  text-align: center;
595
686
  transform: scale(1);
596
- > .visx-group[style] {
687
+
688
+ >.visx-group[style] {
597
689
  transform: scale(1);
598
690
  }
599
691
  }
@@ -614,36 +706,39 @@
614
706
  }
615
707
  }
616
708
 
617
- .cdc-open-viz-module .is-editor .cdc-chart-inner-container {
618
- overflow: hidden;
619
- background-color: var(--white);
620
- }
709
+ .cove-visualization.type-chart.type-sparkline {
710
+ &.lg .visualization-container>svg {
711
+ width: 100%;
712
+ }
621
713
 
622
- .isEditor.type-sparkline .cdc-chart-inner-container {
623
- margin: 3em auto 0;
624
- max-width: 60%;
625
- }
714
+ .visualization-container.sparkline {
715
+ display: flex !important;
716
+ flex-wrap: wrap !important;
717
+ }
626
718
 
627
- .cdc-open-viz-module.type-chart.lg.type-sparkline .chart-container > svg {
628
- width: 100%;
629
- }
719
+ .cove-visualization__body {
720
+ &:not(.component--has-background):not(.component--hide-background-color) {
721
+ background: #f2f2f2;
722
+ }
630
723
 
631
- .chart-container.sparkline {
632
- display: flex !important;
633
- flex-wrap: wrap !important;
634
- }
724
+ &.component--hide-background-color {
725
+ background: transparent;
726
+ }
635
727
 
636
- .cdc-open-viz-module.type-chart.type-sparkline {
637
- .cove-component__content {
638
- background: #f2f2f2;
639
- }
728
+ &.sparkline {
729
+ padding: 1em;
730
+ border-bottom-left-radius: 3px;
731
+ border-bottom-right-radius: 3px;
640
732
 
641
- .cove-component__content.component--hideBackgroundColor {
642
- background: transparent;
643
- }
733
+ .visx-axis-tick:first-of-type {
734
+ transform: translate(20px, 0);
735
+ }
736
+
737
+ .visx-axis-tick:last-of-type {
738
+ transform: translate(-20px, 0);
739
+ }
740
+ }
644
741
 
645
- .cove-component__content .chart-container {
646
- padding: 1em;
647
742
  }
648
743
 
649
744
  .subtext,
@@ -651,29 +746,12 @@
651
746
  margin-top: 0px;
652
747
  }
653
748
 
654
- .isEditor {
749
+ .is-editor {
655
750
  position: relative;
656
751
  }
657
752
  }
658
753
 
659
- .cdc-open-viz-module .cove-component__content.sparkline {
660
- padding: 1em;
661
- }
662
-
663
- .cove-component__content.sparkline {
664
- border-bottom-left-radius: 3px;
665
- border-bottom-right-radius: 3px;
666
-
667
- .visx-axis-tick:first-of-type {
668
- transform: translate(20px, 0);
669
- }
670
-
671
- .visx-axis-tick:last-of-type {
672
- transform: translate(-20px, 0);
673
- }
674
- }
675
-
676
- .cdc-open-viz-module .debug {
754
+ .cove-visualization .debug {
677
755
  border: 2px solid red;
678
756
  }
679
757
 
@@ -0,0 +1,68 @@
1
+ # Config Selectors
2
+
3
+ Typed selector functions and hooks for extracting memoizable slices of chart configuration.
4
+
5
+ ## Purpose
6
+
7
+ These selectors help:
8
+ 1. **Reduce coupling** - Components depend on specific config slices, not the entire config object
9
+ 2. **Improve memoization** - Hooks use specific dependencies instead of the full config
10
+ 3. **Enhance testability** - Selectors can be easily mocked in tests
11
+ 4. **Document config usage** - Selectors serve as documentation for which config properties are used together
12
+
13
+ ## Usage
14
+
15
+ ### Direct Selectors
16
+
17
+ ```typescript
18
+ import { selectAxisConfig, selectVisualizationConfig } from '../selectors'
19
+
20
+ // In a component
21
+ const axisConfig = selectAxisConfig(config)
22
+ // Returns: { xAxis, yAxis, runtime: { xAxis, yAxis, originalXAxis } }
23
+ ```
24
+
25
+ ### Hook Versions (Memoized)
26
+
27
+ ```typescript
28
+ import { useAxisConfig, useVisualizationConfig } from '../selectors'
29
+
30
+ // In a component - automatically memoized
31
+ const axisConfig = useAxisConfig(config)
32
+ const vizConfig = useVisualizationConfig(config)
33
+ ```
34
+
35
+ ## Available Selectors
36
+
37
+ | Selector | Hook | Description |
38
+ |----------|------|-------------|
39
+ | `selectAxisConfig` | `useAxisConfig` | X/Y axis configuration |
40
+ | `selectVisualizationConfig` | `useVisualizationConfig` | Chart type and orientation |
41
+ | `selectDisplayConfig` | `useDisplayConfig` | Animation, debug flags |
42
+ | `selectTooltipConfig` | `useTooltipConfig` | Tooltip settings |
43
+ | `selectLegendConfig` | - | Legend position and visibility |
44
+ | `selectDataFormatConfig` | - | Number formatting options |
45
+ | `selectChartMessages` | - | UI message strings |
46
+ | `selectBrushConfig` | - | Brush/filter settings |
47
+ | `selectForestPlotConfig` | - | Forest plot specific options |
48
+ | `selectSmallMultiplesConfig` | - | Small multiples mode |
49
+
50
+ ## Type Exports
51
+
52
+ Each selector has a corresponding type export:
53
+
54
+ ```typescript
55
+ import type { AxisConfig, VisualizationConfig } from '../selectors'
56
+ ```
57
+
58
+ ## Adding New Selectors
59
+
60
+ 1. Add the selector function that extracts config properties
61
+ 2. Optionally add a hook version with proper dependencies
62
+ 3. Export the type using `ReturnType<typeof selectXxx>`
63
+ 4. Update this README
64
+
65
+ ## Notes
66
+
67
+ - Selectors are created but integration into LinearChart is deferred
68
+ - Future work: gradually replace direct `config.x.y` accesses with selector usage
@@ -75,5 +75,7 @@ export const reducer = (state: ChartState, action: ChartActions): ChartState =>
75
75
  return { ...state, isDraggingAnnotation: action.payload }
76
76
  case 'SET_BRUSH_DATA':
77
77
  return { ...state, brushData: action.payload }
78
+ default:
79
+ return state
78
80
  }
79
81
  }
@@ -1,11 +1,11 @@
1
- import path from 'path'
1
+ import path from 'node:path'
2
2
  import { testStandaloneBuild } from '@cdc/core/helpers/tests/testStandaloneBuild.ts'
3
3
  import { describe, it, expect } from 'vitest'
4
4
 
5
5
  describe('Chart', () => {
6
6
  it('Can be built in isolation', async () => {
7
7
  const pkgDir = path.join(__dirname, '..')
8
- const result = testStandaloneBuild(pkgDir)
8
+ const result = await testStandaloneBuild(pkgDir)
9
9
  expect(result).toBe(true)
10
10
  }, 300000)
11
11
  })
@@ -1,6 +1,7 @@
1
1
  import { Axis } from '@cdc/core/types/Axis'
2
2
  import { MarkupConfig } from '@cdc/core/types/MarkupVariable'
3
3
  import { type ForestPlotConfigSettings } from './ForestPlot'
4
+ import { type HorizonConfigSettings } from './Horizon'
4
5
  import { type Column } from '@cdc/core/types/Column'
5
6
  import { type Series } from '@cdc/core/types/Series'
6
7
  import { Runtime } from '@cdc/core/types/Runtime'
@@ -18,6 +19,7 @@ type General = CoreGeneral & {
18
19
  customColors?: string[]
19
20
  customColorsOrdered?: string[]
20
21
  }
22
+ useIntelligentLineChartLabels?: boolean
21
23
  }
22
24
  import { type Link } from './../components/Sankey/types'
23
25
  import { type DataDescription } from '@cdc/core/types/DataDescription'
@@ -39,9 +41,11 @@ export type VisualizationType =
39
41
  | 'Box Plot'
40
42
  | 'Deviation Bar'
41
43
  | 'Forest Plot'
44
+ | 'Horizon Chart'
42
45
  | 'Line'
43
46
  | 'Paired Bar'
44
47
  | 'Pie'
48
+ | 'Radar'
45
49
  | 'Scatter Plot'
46
50
  | 'Spark Line'
47
51
  | 'Combo'
@@ -130,6 +134,8 @@ type Visual = {
130
134
  accent?: boolean
131
135
  background?: boolean
132
136
  hideBackgroundColor?: boolean
137
+ tp5Treatment?: boolean
138
+ tp5Background?: boolean
133
139
  verticalHoverLine?: boolean
134
140
  horizontalHoverLine?: boolean
135
141
  lineDatapointSymbol: 'none' | 'standard'
@@ -152,6 +158,7 @@ export type AllChartsConfig = {
152
158
  columns: ChartColumns
153
159
  confidenceKeys: ConfidenceInterval
154
160
  data: Object[]
161
+ dataMetadata?: Record<string, string>
155
162
  dataUrl: string
156
163
  dataCutoff: number
157
164
  dataDescription: Partial<DataDescription>
@@ -172,6 +179,7 @@ export type AllChartsConfig = {
172
179
  mobileVertical: number
173
180
  }
174
181
  highlightedBarValues: { value: any; color: string; borderWidth: number; legendLabel: string }[]
182
+ horizon?: HorizonConfigSettings
175
183
  introText: string
176
184
  isLollipopChart: boolean
177
185
  isLegendValue: boolean
@@ -179,6 +187,7 @@ export type AllChartsConfig = {
179
187
  isPaletteReversed: boolean
180
188
  labels: boolean
181
189
  legend: Legend
190
+ locale: string
182
191
  lineDatapointColor: 'Same as Line' | 'Lighter than Line'
183
192
  lineDatapointStyle: 'hidden' | 'always show' | 'hover'
184
193
  lollipopColorStyle: 'regular' | 'two-tone'
@@ -267,6 +276,19 @@ export type AllChartsConfig = {
267
276
  default: string
268
277
  }
269
278
  }
279
+ radar?: {
280
+ gridRings: number
281
+ showGridRings: boolean
282
+ gridRingStyle: 'polygons' | 'circles'
283
+ scaleMin: number
284
+ scaleMax: number | string
285
+ showFill: boolean
286
+ fillOpacity: number
287
+ showPoints: boolean
288
+ pointRadius: number
289
+ strokeWidth: number
290
+ axisLabelOffset: number
291
+ }
270
292
  } & MarkupConfig
271
293
 
272
294
  type ForestPlotConfig = {
@@ -36,6 +36,7 @@ type SharedChartContext = {
36
36
  setLegendIsolateValues?: Function
37
37
  svgRef?: React.RefObject<SVGSVGElement>
38
38
  handleSmallMultipleHover?: (xAxisValue: any, yCoordinate: number) => void
39
+ visibleAnnotations?: Annotation[]
39
40
  }
40
41
 
41
42
  // Line Chart Specific Context