@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.
- package/CLAUDE.local.md +79 -0
- package/LICENSE +201 -0
- package/dist/{cdcchart-dgT_1dIT.es.js → cdcchart-DQ00cQCm.es.js} +1 -20
- package/dist/cdcchart.js +54742 -49796
- package/examples/data/data-with-metadata.json +10 -0
- package/examples/default.json +378 -0
- package/examples/feature/__data__/horizon-chart-data.json +373 -0
- package/examples/feature/annotations/index.json +3 -6
- package/examples/feature/horizon/horizon-chart.json +395 -0
- package/examples/feature/pie/planet-pie-example-config.json +2 -1
- package/examples/line-chart-states.json +1085 -0
- package/examples/metadata-variables.json +58 -0
- package/examples/private/123.json +694 -0
- package/examples/private/anchor-issue.json +4094 -0
- package/examples/private/backwards-slider.json +10430 -0
- package/examples/private/georgia.csv +160 -0
- package/examples/private/timeline-data.json +1 -0
- package/examples/private/timeline.json +389 -0
- package/examples/radar-chart-simple.json +133 -0
- package/examples/radar-chart.json +148 -0
- package/index.html +1 -31
- package/package.json +57 -59
- package/src/CdcChart.tsx +8 -4
- package/src/CdcChartComponent.tsx +398 -284
- package/src/_stories/Chart.Anchors.stories.tsx +10 -0
- package/src/_stories/Chart.BoxPlot.stories.tsx +7 -0
- package/src/_stories/Chart.CI.stories.tsx +13 -0
- package/src/_stories/Chart.Combo.stories.tsx +17 -0
- package/src/_stories/Chart.CustomColors.stories.tsx +78 -0
- package/src/_stories/Chart.Defaults.stories.tsx +95 -0
- package/src/_stories/Chart.DynamicSeries.stories.tsx +19 -0
- package/src/_stories/Chart.Filters.stories.tsx +4 -0
- package/src/_stories/Chart.Forecast.stories.tsx +4 -0
- package/src/_stories/Chart.HTMLInDataTable.stories.tsx +22 -0
- package/src/_stories/Chart.Legend.Gradient.stories.tsx +28 -0
- package/src/_stories/Chart.Patterns.stories.tsx +4 -0
- package/src/_stories/Chart.PreserveDecimals.stories.tsx +25 -0
- package/src/_stories/Chart.Regions.Categorical.stories.tsx +13 -0
- package/src/_stories/Chart.Regions.DateScale.stories.tsx +19 -0
- package/src/_stories/Chart.Regions.DateTimeScale.stories.tsx +25 -10
- package/src/_stories/Chart.ScatterPlot.stories.tsx +4 -0
- package/src/_stories/Chart.SmallMultiples.stories.tsx +16 -0
- package/src/_stories/Chart.SmallestLeftAxisMax.stories.tsx +64 -0
- package/src/_stories/Chart.stories.tsx +72 -1
- package/src/_stories/Chart.tooltip.stories.tsx +7 -0
- package/src/_stories/ChartAnnotation.stories.tsx +10 -0
- package/src/_stories/ChartAxisLabels.stories.tsx +4 -0
- package/src/_stories/ChartAxisTitles.stories.tsx +10 -0
- package/src/_stories/ChartBar.Editor.stories.tsx +97 -38
- package/src/_stories/ChartBrush.Editor.stories.tsx +11 -25
- package/src/_stories/ChartBrush.Matrix.Continuous.stories.tsx +41 -0
- package/src/_stories/ChartBrush.Matrix.Date.stories.tsx +114 -0
- package/src/_stories/ChartBrush.Matrix.DateTime.stories.tsx +78 -0
- package/src/_stories/ChartBrush.stories.tsx +7 -0
- package/src/_stories/ChartEditor.Editor.stories.tsx +1 -1
- package/src/_stories/ChartEditor.stories.tsx +7 -0
- package/src/_stories/ChartLine.QuadrantAngles.stories.tsx +89 -0
- package/src/_stories/ChartLine.Suppression.stories.tsx +7 -0
- package/src/_stories/ChartLine.Symbols.stories.tsx +4 -0
- package/src/_stories/ChartPrefixSuffix.stories.tsx +46 -1
- package/src/_stories/TechAdoptionWithLinks.stories.tsx +7 -0
- package/src/_stories/_mock/brush_continuous.json +86 -0
- package/src/_stories/_mock/brush_date_large.json +176 -0
- package/src/_stories/_mock/line_chart_angle_near_zero_fall.json +195 -0
- package/src/_stories/_mock/line_chart_angle_near_zero_rise.json +195 -0
- package/src/_stories/_mock/line_chart_angle_q1_steep_upward.json +195 -0
- package/src/_stories/_mock/line_chart_angle_q2_gentle_downward.json +195 -0
- package/src/_stories/_mock/line_chart_angle_q3_steep_downward.json +195 -0
- package/src/_stories/_mock/line_chart_angle_q4_gentle_upward.json +195 -0
- package/src/_stories/_mock/line_chart_quadrant_angles.json +264 -0
- package/src/_stories/_mock/paired-bar-abbr.json +421 -0
- package/src/_stories/_mock/pie_custom_colors.json +268 -0
- package/src/_stories/_mock/smallest_left_axis_max.json +104 -0
- package/src/components/Annotations/components/AnnotationDraggable.styles.css +14 -20
- package/src/components/Annotations/components/AnnotationDraggable.tsx +240 -116
- package/src/components/Annotations/components/AnnotationDropdown.styles.css +1 -2
- package/src/components/Annotations/components/AnnotationDropdown.tsx +8 -12
- package/src/components/Annotations/components/AnnotationList.styles.css +12 -18
- package/src/components/Annotations/components/AnnotationList.tsx +5 -4
- package/src/components/Annotations/components/findNearestDatum.ts +75 -85
- package/src/components/Annotations/helpers/getVisibleAnnotations.ts +38 -0
- package/src/components/Axis/BottomAxis.tsx +277 -0
- package/src/components/Axis/LeftAxis.tsx +404 -0
- package/src/components/Axis/LeftAxisGridlines.tsx +77 -0
- package/src/components/Axis/PairedBarAxis.tsx +192 -0
- package/src/components/Axis/README.md +94 -0
- package/src/components/Axis/RightAxis.tsx +108 -0
- package/src/components/Axis/axis.constants.ts +21 -0
- package/src/components/Axis/index.ts +7 -0
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +12 -28
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +12 -30
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +12 -31
- package/src/components/BarChart/components/BarChart.Vertical.tsx +12 -28
- package/src/components/BarChart/components/BarChart.tsx +7 -1
- package/src/components/BarChart/helpers/getPatternUrl.ts +94 -0
- package/src/components/BarChart/helpers/tests/getPatternUrl.test.ts +134 -0
- package/src/components/BarChart/helpers/useBarChart.ts +3 -0
- package/src/components/Brush/BrushSelector.tsx +155 -22
- package/src/components/Brush/MiniChartPreview.tsx +133 -21
- package/src/components/EditorPanel/EditorPanel.tsx +81 -54
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +67 -29
- package/src/components/EditorPanel/components/Panels/Panel.ForestPlotSettings.tsx +0 -78
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +120 -2
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +25 -43
- package/src/components/EditorPanel/components/Panels/Panel.Radar.tsx +353 -0
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +83 -3
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +66 -43
- package/src/components/EditorPanel/components/Panels/index.tsx +2 -0
- package/src/components/EditorPanel/editor-panel.scss +1 -1
- package/src/components/EditorPanel/useEditorPermissions.ts +55 -26
- package/src/components/ForestPlot/ForestPlot.tsx +26 -22
- package/src/components/HorizonChart/HorizonChart.tsx +131 -0
- package/src/components/HorizonChart/components/HorizonBand.tsx +160 -0
- package/src/components/HorizonChart/helpers/calculateHorizonBands.ts +27 -0
- package/src/components/HorizonChart/helpers/getHorizonLayerColors.ts +40 -0
- package/src/components/HorizonChart/index.tsx +3 -0
- package/src/components/Legend/Legend.Component.tsx +52 -4
- package/src/components/Legend/Legend.tsx +1 -1
- package/src/components/Legend/LegendGroup/LegendGroup.styles.css +4 -4
- package/src/components/Legend/LegendValueRange.tsx +77 -0
- package/src/components/Legend/helpers/createFormatLabels.tsx +16 -2
- package/src/components/Legend/helpers/generateValueRanges.ts +92 -0
- package/src/components/LineChart/helpers/README.md +292 -0
- package/src/components/LineChart/helpers/labelPositioning.test.ts +245 -0
- package/src/components/LineChart/helpers/labelPositioning.ts +304 -0
- package/src/components/LineChart/index.tsx +44 -8
- package/src/components/LinearChart/README.md +109 -0
- package/src/components/LinearChart/VisualizationRenderer.tsx +267 -0
- package/src/components/LinearChart/linearChart.constants.ts +84 -0
- package/src/components/LinearChart/tests/LinearChart.test.tsx +278 -0
- package/src/components/LinearChart/tests/mockConfigContext.ts +131 -0
- package/src/components/LinearChart/utils/tickFormatting.ts +146 -0
- package/src/components/LinearChart.tsx +268 -1057
- package/src/components/PieChart/PieChart.tsx +20 -5
- package/src/components/RadarChart/RadarAxis.tsx +78 -0
- package/src/components/RadarChart/RadarChart.tsx +298 -0
- package/src/components/RadarChart/RadarGrid.tsx +64 -0
- package/src/components/RadarChart/RadarPolygon.tsx +91 -0
- package/src/components/RadarChart/helpers.ts +83 -0
- package/src/components/RadarChart/index.tsx +3 -0
- package/src/components/Regions/components/Regions.tsx +6 -6
- package/src/components/Sankey/components/Sankey.tsx +3 -3
- package/src/components/Sankey/sankey.scss +1 -1
- package/src/components/SmallMultiples/SmallMultiples.css +5 -5
- package/src/components/Sparkline/index.scss +4 -2
- package/src/components/WarmingStripes/WarmingStripes.tsx +95 -25
- package/src/components/WarmingStripes/WarmingStripesGradientLegend.css +8 -8
- package/src/data/initial-state.js +37 -15
- package/src/data/legacy-defaults.ts +18 -0
- package/src/helpers/abbreviateNumber.ts +24 -17
- package/src/helpers/getChartPatternId.ts +17 -0
- package/src/helpers/getExcludedData.ts +4 -0
- package/src/helpers/getMinMax.ts +16 -2
- package/src/helpers/handleChartAriaLabels.ts +19 -19
- package/src/helpers/handleLineType.ts +22 -18
- package/src/helpers/seriesColumnSettings.ts +114 -0
- package/src/helpers/tests/countNumOfTicks.test.ts +77 -0
- package/src/helpers/tests/seriesColumnSettings.test.ts +84 -0
- package/src/hooks/useProgrammaticTooltip.ts +23 -2
- package/src/hooks/useRightAxis.ts +14 -0
- package/src/hooks/useScales.ts +99 -56
- package/src/hooks/useTooltip.tsx +23 -3
- package/src/scss/main.scss +157 -79
- package/src/selectors/README.md +68 -0
- package/src/store/chart.reducer.ts +2 -0
- package/src/test/CdcChart.test.jsx +2 -2
- package/src/types/ChartConfig.ts +22 -0
- package/src/types/ChartContext.ts +1 -0
- package/src/types/Horizon.ts +64 -0
- package/tests/fixtures/chart-config-with-metadata.json +29 -0
- package/tests/fixtures/data-with-metadata.json +10 -0
- package/preview.html +0 -1616
- package/src/components/Annotations/components/helpers/index.tsx +0 -46
|
@@ -3,6 +3,7 @@ import { Meta, Story } from '@storybook/react-vite'
|
|
|
3
3
|
import Chart from '../CdcChartComponent'
|
|
4
4
|
import exampleComboBarNonNumeric from './../../examples/feature/tests-date-exclusions/date-exclusions-config.json'
|
|
5
5
|
import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
|
|
6
|
+
import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
|
|
6
7
|
|
|
7
8
|
export default {
|
|
8
9
|
title: 'Components/Templates/Chart/Anchors',
|
|
@@ -15,17 +16,26 @@ export const Anchor_DateLinear: Story = {
|
|
|
15
16
|
args: {
|
|
16
17
|
config: exampleComboBarNonNumeric,
|
|
17
18
|
isEditor: false
|
|
19
|
+
},
|
|
20
|
+
play: async ({ canvasElement }) => {
|
|
21
|
+
await assertVisualizationRendered(canvasElement)
|
|
18
22
|
}
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
export const Anchor_Categorical: Story = {
|
|
22
26
|
args: {
|
|
23
27
|
config: editConfigKeys(exampleComboBarNonNumeric, [{ path: ['xAxis', 'type'], value: 'categorical' }])
|
|
28
|
+
},
|
|
29
|
+
play: async ({ canvasElement }) => {
|
|
30
|
+
await assertVisualizationRendered(canvasElement)
|
|
24
31
|
}
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
export const Anchor_Date_Time: Story = {
|
|
28
35
|
args: {
|
|
29
36
|
config: editConfigKeys(exampleComboBarNonNumeric, [{ path: ['xAxis', 'type'], value: 'date-time' }])
|
|
37
|
+
},
|
|
38
|
+
play: async ({ canvasElement }) => {
|
|
39
|
+
await assertVisualizationRendered(canvasElement)
|
|
30
40
|
}
|
|
31
41
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
2
|
import boxPlotConfig from './_mock/boxplot_multiseries.json'
|
|
3
3
|
import Chart from '../CdcChartComponent'
|
|
4
|
+
import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
|
|
4
5
|
|
|
5
6
|
const meta: Meta<typeof Chart> = {
|
|
6
7
|
title: 'Components/Templates/Chart/Box Plot',
|
|
@@ -17,6 +18,9 @@ export const BoxPlot_Vertical: Story = {
|
|
|
17
18
|
title: 'Vertical Multiseries Box Plot',
|
|
18
19
|
isEditor: false
|
|
19
20
|
}
|
|
21
|
+
},
|
|
22
|
+
play: async ({ canvasElement }) => {
|
|
23
|
+
await assertVisualizationRendered(canvasElement)
|
|
20
24
|
}
|
|
21
25
|
}
|
|
22
26
|
|
|
@@ -29,6 +33,9 @@ export const BoxPlot_Horizontal: Story = {
|
|
|
29
33
|
yAxis: { ...boxPlotConfig.yAxis, labelPlacement: 'Above Bar' }
|
|
30
34
|
},
|
|
31
35
|
isEditor: false
|
|
36
|
+
},
|
|
37
|
+
play: async ({ canvasElement }) => {
|
|
38
|
+
await assertVisualizationRendered(canvasElement)
|
|
32
39
|
}
|
|
33
40
|
}
|
|
34
41
|
|
|
@@ -4,6 +4,7 @@ import lineChartDynamicCI from './_mock/line_chart_dynamic_ci.json'
|
|
|
4
4
|
import lineChartNonDynamicCI from './_mock/line_chart_non_dynamic_ci.json'
|
|
5
5
|
|
|
6
6
|
import Chart from '../CdcChartComponent'
|
|
7
|
+
import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
|
|
7
8
|
|
|
8
9
|
const meta: Meta<typeof Chart> = {
|
|
9
10
|
title: 'Components/Templates/Chart/Confidence Intervals',
|
|
@@ -14,6 +15,9 @@ export const bar_chart_with_labels: Story = {
|
|
|
14
15
|
args: {
|
|
15
16
|
config: barChartCiLabels,
|
|
16
17
|
isEditor: false
|
|
18
|
+
},
|
|
19
|
+
play: async ({ canvasElement }) => {
|
|
20
|
+
await assertVisualizationRendered(canvasElement)
|
|
17
21
|
}
|
|
18
22
|
}
|
|
19
23
|
export const bar_chart_horizontal_labels: Story = {
|
|
@@ -24,6 +28,9 @@ export const bar_chart_horizontal_labels: Story = {
|
|
|
24
28
|
yAxis: { ...barChartCiLabels.yAxis, displayNumbersOnBar: true }
|
|
25
29
|
},
|
|
26
30
|
isEditor: false
|
|
31
|
+
},
|
|
32
|
+
play: async ({ canvasElement }) => {
|
|
33
|
+
await assertVisualizationRendered(canvasElement)
|
|
27
34
|
}
|
|
28
35
|
}
|
|
29
36
|
|
|
@@ -31,6 +38,9 @@ export const line_Chart_Dynamic_Confidence_Intervals: Story = {
|
|
|
31
38
|
args: {
|
|
32
39
|
config: lineChartDynamicCI,
|
|
33
40
|
isEditor: false
|
|
41
|
+
},
|
|
42
|
+
play: async ({ canvasElement }) => {
|
|
43
|
+
await assertVisualizationRendered(canvasElement)
|
|
34
44
|
}
|
|
35
45
|
}
|
|
36
46
|
|
|
@@ -38,6 +48,9 @@ export const line_Chart_Non_Dynamic_Confidence_Intervals: Story = {
|
|
|
38
48
|
args: {
|
|
39
49
|
config: lineChartNonDynamicCI,
|
|
40
50
|
isEditor: false
|
|
51
|
+
},
|
|
52
|
+
play: async ({ canvasElement }) => {
|
|
53
|
+
await assertVisualizationRendered(canvasElement)
|
|
41
54
|
}
|
|
42
55
|
}
|
|
43
56
|
export default meta
|
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
import React from 'react'
|
|
3
3
|
import { Meta, Story } from '@storybook/react'
|
|
4
4
|
import CdcChart from '@cdc/chart/src/CdcChart'
|
|
5
|
+
import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
|
|
6
|
+
import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
|
|
5
7
|
import comboChartConfig from './_mock/combo.json'
|
|
6
8
|
|
|
7
9
|
export default {
|
|
@@ -16,3 +18,18 @@ ComboChart.args = {
|
|
|
16
18
|
config: comboChartConfig,
|
|
17
19
|
isEditor: true
|
|
18
20
|
}
|
|
21
|
+
ComboChart.play = async ({ canvasElement }) => {
|
|
22
|
+
await assertVisualizationRendered(canvasElement)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export const ComboChartWithBrush = Template.bind({})
|
|
26
|
+
ComboChartWithBrush.args = {
|
|
27
|
+
config: editConfigKeys(comboChartConfig, [
|
|
28
|
+
{ path: ['xAxis', 'brushActive'], value: true },
|
|
29
|
+
{ path: ['xAxis', 'brushDefaultRecentDateCount'], value: 12 }
|
|
30
|
+
]),
|
|
31
|
+
isEditor: true
|
|
32
|
+
}
|
|
33
|
+
ComboChartWithBrush.play = async ({ canvasElement }) => {
|
|
34
|
+
await assertVisualizationRendered(canvasElement)
|
|
35
|
+
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
2
|
import Chart from '../CdcChartComponent'
|
|
3
3
|
import scatterPlotCustomColorConfig from './_mock/scatterplot_mock.json'
|
|
4
|
+
import pieCustomColorConfig from './_mock/pie_custom_colors.json'
|
|
5
|
+
import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
|
|
6
|
+
import { expect, userEvent, waitFor } from 'storybook/test'
|
|
4
7
|
|
|
5
8
|
const meta: Meta<typeof Chart> = {
|
|
6
9
|
title: 'Components/Templates/Chart/Custom Colors',
|
|
@@ -13,6 +16,81 @@ export const ScatterPlot: Story = {
|
|
|
13
16
|
args: {
|
|
14
17
|
config: scatterPlotCustomColorConfig,
|
|
15
18
|
isEditor: false
|
|
19
|
+
},
|
|
20
|
+
play: async ({ canvasElement }) => {
|
|
21
|
+
await assertVisualizationRendered(canvasElement)
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const pieCustomColors = ['#0B6E4F', '#C75000', '#7C4DFF', '#0077B6', '#D7263D']
|
|
26
|
+
const pieFallbackCustomColors = ['#004E89', '#1A659E', '#47A8BD', '#D1495B', '#EDAE49']
|
|
27
|
+
|
|
28
|
+
const normalizeColor = (color: string) => {
|
|
29
|
+
const swatch = document.createElement('div')
|
|
30
|
+
swatch.style.color = color
|
|
31
|
+
document.body.appendChild(swatch)
|
|
32
|
+
const normalized = getComputedStyle(swatch).color
|
|
33
|
+
swatch.remove()
|
|
34
|
+
return normalized
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const assertPieCustomColorStory = async (canvasElement: HTMLElement, expectedColors: string[]) => {
|
|
38
|
+
await assertVisualizationRendered(canvasElement)
|
|
39
|
+
|
|
40
|
+
const chart = canvasElement.querySelector('svg.animated-pie')
|
|
41
|
+
const legend = canvasElement.querySelector('.legend-container')
|
|
42
|
+
expect(chart).toBeTruthy()
|
|
43
|
+
expect(legend).toBeTruthy()
|
|
44
|
+
|
|
45
|
+
await waitFor(() => {
|
|
46
|
+
expect(chart?.querySelectorAll('path')).toHaveLength(expectedColors.length)
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
const legendItems = Array.from(legend!.querySelectorAll('[role="button"]')) as HTMLElement[]
|
|
50
|
+
expect(legendItems).toHaveLength(expectedColors.length)
|
|
51
|
+
|
|
52
|
+
const sliceColors = Array.from(chart!.querySelectorAll('path')).map(path =>
|
|
53
|
+
normalizeColor(path.getAttribute('fill') || '')
|
|
54
|
+
)
|
|
55
|
+
expect(sliceColors).toEqual(expectedColors.map(normalizeColor))
|
|
56
|
+
|
|
57
|
+
const legendColors = legendItems.map(item => {
|
|
58
|
+
const swatch = item.querySelector('span.legend-item') as HTMLElement | null
|
|
59
|
+
return normalizeColor(swatch ? getComputedStyle(swatch).backgroundColor : '')
|
|
60
|
+
})
|
|
61
|
+
expect(legendColors).toEqual(expectedColors.map(normalizeColor))
|
|
62
|
+
|
|
63
|
+
await userEvent.click(legendItems[0])
|
|
64
|
+
|
|
65
|
+
await waitFor(() => {
|
|
66
|
+
expect(chart?.querySelectorAll('path')).toHaveLength(1)
|
|
67
|
+
expect(legendItems[0].className).toContain('highlighted')
|
|
68
|
+
expect(legendItems[1].className).toContain('inactive')
|
|
69
|
+
})
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export const PieChart: Story = {
|
|
73
|
+
args: {
|
|
74
|
+
config: pieCustomColorConfig,
|
|
75
|
+
isEditor: false
|
|
76
|
+
},
|
|
77
|
+
play: async ({ canvasElement }) => {
|
|
78
|
+
await assertPieCustomColorStory(canvasElement, pieCustomColors)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const pieChartCustomColorsFallbackConfig = JSON.parse(JSON.stringify(pieCustomColorConfig))
|
|
83
|
+
pieChartCustomColorsFallbackConfig.title = 'Pie Chart Custom Colors Fallback'
|
|
84
|
+
pieChartCustomColorsFallbackConfig.general.palette.customColors = pieFallbackCustomColors
|
|
85
|
+
delete pieChartCustomColorsFallbackConfig.general.palette.customColorsOrdered
|
|
86
|
+
|
|
87
|
+
export const PieChartCustomColorsFallback: Story = {
|
|
88
|
+
args: {
|
|
89
|
+
config: pieChartCustomColorsFallbackConfig,
|
|
90
|
+
isEditor: false
|
|
91
|
+
},
|
|
92
|
+
play: async ({ canvasElement }) => {
|
|
93
|
+
await assertPieCustomColorStory(canvasElement, pieFallbackCustomColors)
|
|
16
94
|
}
|
|
17
95
|
}
|
|
18
96
|
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
|
+
import { expect } from 'storybook/test'
|
|
3
|
+
import Chart from '../CdcChart'
|
|
4
|
+
import simplifiedLine from './_mock/simplified_line.json'
|
|
5
|
+
import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
|
|
6
|
+
import { assertVisualizationRendered, waitForPresence } from '@cdc/core/helpers/testing'
|
|
7
|
+
|
|
8
|
+
const meta: Meta<typeof Chart> = {
|
|
9
|
+
title: 'Components/Templates/Chart/Defaults',
|
|
10
|
+
component: Chart
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type Story = StoryObj<typeof Chart>
|
|
14
|
+
|
|
15
|
+
const oldConfig = editConfigKeys(simplifiedLine, [
|
|
16
|
+
{ path: ['yAxis', 'hideAxis'], value: false },
|
|
17
|
+
{ path: ['yAxis', 'hideTicks'], value: false },
|
|
18
|
+
{ path: ['yAxis', 'gridLines'], value: false },
|
|
19
|
+
{ path: ['yAxis', 'numTicks'], value: '' },
|
|
20
|
+
{ path: ['xAxis', 'numTicks'], value: '' },
|
|
21
|
+
{ path: ['table', 'expanded'], value: true },
|
|
22
|
+
{ path: ['legend', 'position'], value: 'right' },
|
|
23
|
+
{ path: ['dataFormat', 'commas'], value: false },
|
|
24
|
+
{ path: ['tooltips', 'dateDisplayFormat'], value: '' }
|
|
25
|
+
])
|
|
26
|
+
|
|
27
|
+
const newConfig = editConfigKeys(simplifiedLine, [
|
|
28
|
+
{ path: ['yAxis', 'hideAxis'], value: true },
|
|
29
|
+
{ path: ['yAxis', 'hideTicks'], value: true },
|
|
30
|
+
{ path: ['yAxis', 'gridLines'], value: true },
|
|
31
|
+
{ path: ['yAxis', 'numTicks'], value: 4 },
|
|
32
|
+
{ path: ['xAxis', 'numTicks'], value: 6 },
|
|
33
|
+
{ path: ['table', 'expanded'], value: false },
|
|
34
|
+
{ path: ['legend', 'position'], value: 'top' },
|
|
35
|
+
{ path: ['dataFormat', 'commas'], value: true },
|
|
36
|
+
{ path: ['tooltips', 'dateDisplayFormat'], value: '%B %-d, %Y' }
|
|
37
|
+
])
|
|
38
|
+
|
|
39
|
+
export const OldConfig_Preserves_Legacy_Defaults: Story = {
|
|
40
|
+
args: {
|
|
41
|
+
config: oldConfig,
|
|
42
|
+
isEditor: false
|
|
43
|
+
},
|
|
44
|
+
play: async ({ canvasElement }) => {
|
|
45
|
+
await assertVisualizationRendered(canvasElement)
|
|
46
|
+
|
|
47
|
+
await waitForPresence('.legend-container', canvasElement)
|
|
48
|
+
const legend = canvasElement.querySelector('.legend-container')
|
|
49
|
+
expect(legend).toBeInTheDocument()
|
|
50
|
+
expect(legend?.classList.contains('right')).toBe(true)
|
|
51
|
+
|
|
52
|
+
const axisLine = canvasElement.querySelector('.left-axis line[stroke="#000"]')
|
|
53
|
+
expect(axisLine).toBeInTheDocument()
|
|
54
|
+
|
|
55
|
+
const gridlines = canvasElement.querySelectorAll('.left-axis line[stroke="#d6d6d6"]')
|
|
56
|
+
expect(gridlines.length).toBe(0)
|
|
57
|
+
|
|
58
|
+
const dataTable = canvasElement.querySelector('.data-table')
|
|
59
|
+
expect(dataTable).toBeInTheDocument()
|
|
60
|
+
expect(dataTable?.getAttribute('hidden')).toBeNull()
|
|
61
|
+
|
|
62
|
+
const tickTexts = canvasElement.querySelectorAll('.left-axis .vx-axis-tick text')
|
|
63
|
+
for (const tick of tickTexts) {
|
|
64
|
+
expect(tick.textContent).not.toMatch(/,/)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export const NewConfig_Gets_New_Defaults: Story = {
|
|
70
|
+
args: {
|
|
71
|
+
config: newConfig,
|
|
72
|
+
isEditor: false
|
|
73
|
+
},
|
|
74
|
+
play: async ({ canvasElement }) => {
|
|
75
|
+
await assertVisualizationRendered(canvasElement)
|
|
76
|
+
|
|
77
|
+
await waitForPresence('.legend-container', canvasElement)
|
|
78
|
+
const legend = canvasElement.querySelector('.legend-container')
|
|
79
|
+
expect(legend).toBeInTheDocument()
|
|
80
|
+
expect(legend?.classList.contains('top')).toBe(true)
|
|
81
|
+
|
|
82
|
+
const axisLine = canvasElement.querySelector('.left-axis line[stroke="#000"]')
|
|
83
|
+
expect(axisLine).toBeNull()
|
|
84
|
+
|
|
85
|
+
await waitForPresence('.left-axis line[stroke="#d6d6d6"]', canvasElement)
|
|
86
|
+
const gridlines = canvasElement.querySelectorAll('.left-axis line[stroke="#d6d6d6"]')
|
|
87
|
+
expect(gridlines.length).toBeGreaterThan(0)
|
|
88
|
+
|
|
89
|
+
const dataTable = canvasElement.querySelector('.data-table')
|
|
90
|
+
expect(dataTable).toBeInTheDocument()
|
|
91
|
+
expect(dataTable?.getAttribute('hidden')).not.toBeNull()
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export default meta
|
|
@@ -3,6 +3,7 @@ import DynamicSeriesBarConfig from './_mock/dynamic_series_bar_config.json'
|
|
|
3
3
|
import DynamicSeriesSuppression from './_mock/dynamic_series_suppression_mock.json'
|
|
4
4
|
import { Meta, StoryObj } from '@storybook/react-vite'
|
|
5
5
|
import Chart from '../CdcChartComponent'
|
|
6
|
+
import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
|
|
6
7
|
|
|
7
8
|
const meta: Meta<typeof Chart> = {
|
|
8
9
|
title: 'Components/Templates/Chart/Dynamic Series',
|
|
@@ -23,6 +24,9 @@ export const LineShowPoints: Story = {
|
|
|
23
24
|
lineDatapointStyle: 'always show'
|
|
24
25
|
},
|
|
25
26
|
isEditor: false
|
|
27
|
+
},
|
|
28
|
+
play: async ({ canvasElement }) => {
|
|
29
|
+
await assertVisualizationRendered(canvasElement)
|
|
26
30
|
}
|
|
27
31
|
}
|
|
28
32
|
|
|
@@ -30,6 +34,9 @@ export const LineSuppression: Story = {
|
|
|
30
34
|
args: {
|
|
31
35
|
config: DynamicSeriesSuppression,
|
|
32
36
|
isEditor: false
|
|
37
|
+
},
|
|
38
|
+
play: async ({ canvasElement }) => {
|
|
39
|
+
await assertVisualizationRendered(canvasElement)
|
|
33
40
|
}
|
|
34
41
|
}
|
|
35
42
|
|
|
@@ -37,6 +44,9 @@ export const LineHoverPoints: Story = {
|
|
|
37
44
|
args: {
|
|
38
45
|
config: DynamicSeriesConfig,
|
|
39
46
|
isEditor: false
|
|
47
|
+
},
|
|
48
|
+
play: async ({ canvasElement }) => {
|
|
49
|
+
await assertVisualizationRendered(canvasElement)
|
|
40
50
|
}
|
|
41
51
|
}
|
|
42
52
|
|
|
@@ -44,6 +54,9 @@ export const Bar_Vertical: Story = {
|
|
|
44
54
|
args: {
|
|
45
55
|
config: DynamicSeriesBarConfig,
|
|
46
56
|
isEditor: true
|
|
57
|
+
},
|
|
58
|
+
play: async ({ canvasElement }) => {
|
|
59
|
+
await assertVisualizationRendered(canvasElement)
|
|
47
60
|
}
|
|
48
61
|
}
|
|
49
62
|
|
|
@@ -51,6 +64,9 @@ export const Bar_Horizontal: Story = {
|
|
|
51
64
|
args: {
|
|
52
65
|
config: { ...DynamicSeriesBarConfig, orientation: 'horizontal' },
|
|
53
66
|
isEditor: false
|
|
67
|
+
},
|
|
68
|
+
play: async ({ canvasElement }) => {
|
|
69
|
+
await assertVisualizationRendered(canvasElement)
|
|
54
70
|
}
|
|
55
71
|
}
|
|
56
72
|
|
|
@@ -62,6 +78,9 @@ export const Legend_Order: Story = {
|
|
|
62
78
|
legend: { ...DynamicSeriesBarConfig, order: 'desc' }
|
|
63
79
|
},
|
|
64
80
|
isEditor: false
|
|
81
|
+
},
|
|
82
|
+
play: async ({ canvasElement }) => {
|
|
83
|
+
await assertVisualizationRendered(canvasElement)
|
|
65
84
|
}
|
|
66
85
|
}
|
|
67
86
|
|
|
@@ -2,6 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
|
2
2
|
import Chart from '../CdcChartComponent'
|
|
3
3
|
import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
|
|
4
4
|
import scatterPlotDownloadImage from './_mock/scatterplot-image-download.json'
|
|
5
|
+
import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
|
|
5
6
|
|
|
6
7
|
const meta: Meta<typeof Chart> = {
|
|
7
8
|
title: 'Components/Templates/Chart/Filters',
|
|
@@ -13,6 +14,9 @@ type Story = StoryObj<typeof Chart>
|
|
|
13
14
|
export const Tab_Simple: Story = {
|
|
14
15
|
args: {
|
|
15
16
|
config: editConfigKeys(scatterPlotDownloadImage, [{ path: ['filters', '0', 'filterStyle'], value: 'tab-simple' }])
|
|
17
|
+
},
|
|
18
|
+
play: async ({ canvasElement }) => {
|
|
19
|
+
await assertVisualizationRendered(canvasElement)
|
|
16
20
|
}
|
|
17
21
|
}
|
|
18
22
|
|
|
@@ -2,6 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
|
2
2
|
|
|
3
3
|
import Chart from '../CdcChart'
|
|
4
4
|
import forecastComboWithGaps from './_mock/forecast_combo_with_gaps.json'
|
|
5
|
+
import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
|
|
5
6
|
|
|
6
7
|
const meta: Meta<typeof Chart> = {
|
|
7
8
|
title: 'Components/Templates/Chart/Forecast Chart',
|
|
@@ -30,6 +31,9 @@ export const Forecast_Combo_With_Gaps: Story = {
|
|
|
30
31
|
'A combo chart with forecast confidence intervals that demonstrates proper gap handling. The forecast areas and lines are split into separate segments when gaps are detected, preventing misleading connections across missing data periods. Invalid data points (NA values) are automatically filtered out.'
|
|
31
32
|
}
|
|
32
33
|
}
|
|
34
|
+
},
|
|
35
|
+
play: async ({ canvasElement }) => {
|
|
36
|
+
await assertVisualizationRendered(canvasElement)
|
|
33
37
|
}
|
|
34
38
|
}
|
|
35
39
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
2
|
import CdcChart from '../CdcChartComponent'
|
|
3
|
+
import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
|
|
3
4
|
|
|
4
5
|
const meta: Meta<typeof CdcChart> = {
|
|
5
6
|
title: 'Components/Templates/Chart/HTML in Data Table',
|
|
@@ -148,6 +149,9 @@ export const BasicHTMLInFootnoteColumn: Story = {
|
|
|
148
149
|
}
|
|
149
150
|
},
|
|
150
151
|
isEditor: true
|
|
152
|
+
},
|
|
153
|
+
play: async ({ canvasElement }) => {
|
|
154
|
+
await assertVisualizationRendered(canvasElement)
|
|
151
155
|
}
|
|
152
156
|
}
|
|
153
157
|
|
|
@@ -208,6 +212,9 @@ export const HTMLWithLinksAndFormatting: Story = {
|
|
|
208
212
|
}
|
|
209
213
|
},
|
|
210
214
|
isEditor: true
|
|
215
|
+
},
|
|
216
|
+
play: async ({ canvasElement }) => {
|
|
217
|
+
await assertVisualizationRendered(canvasElement)
|
|
211
218
|
}
|
|
212
219
|
}
|
|
213
220
|
|
|
@@ -265,6 +272,9 @@ export const HTMLWithLineBreaks: Story = {
|
|
|
265
272
|
}
|
|
266
273
|
},
|
|
267
274
|
isEditor: true
|
|
275
|
+
},
|
|
276
|
+
play: async ({ canvasElement }) => {
|
|
277
|
+
await assertVisualizationRendered(canvasElement)
|
|
268
278
|
}
|
|
269
279
|
}
|
|
270
280
|
|
|
@@ -315,6 +325,9 @@ export const ComplexHTMLWithLists: Story = {
|
|
|
315
325
|
}
|
|
316
326
|
},
|
|
317
327
|
isEditor: true
|
|
328
|
+
},
|
|
329
|
+
play: async ({ canvasElement }) => {
|
|
330
|
+
await assertVisualizationRendered(canvasElement)
|
|
318
331
|
}
|
|
319
332
|
}
|
|
320
333
|
|
|
@@ -368,6 +381,9 @@ export const HTMLWithInlineStyles: Story = {
|
|
|
368
381
|
}
|
|
369
382
|
},
|
|
370
383
|
isEditor: true
|
|
384
|
+
},
|
|
385
|
+
play: async ({ canvasElement }) => {
|
|
386
|
+
await assertVisualizationRendered(canvasElement)
|
|
371
387
|
}
|
|
372
388
|
}
|
|
373
389
|
|
|
@@ -444,6 +460,9 @@ export const LineChartWithHTMLFootnotes: Story = {
|
|
|
444
460
|
}
|
|
445
461
|
},
|
|
446
462
|
isEditor: true
|
|
463
|
+
},
|
|
464
|
+
play: async ({ canvasElement }) => {
|
|
465
|
+
await assertVisualizationRendered(canvasElement)
|
|
447
466
|
}
|
|
448
467
|
}
|
|
449
468
|
|
|
@@ -516,5 +535,8 @@ export const PieChartWithHTMLFootnotes: Story = {
|
|
|
516
535
|
}
|
|
517
536
|
},
|
|
518
537
|
isEditor: true
|
|
538
|
+
},
|
|
539
|
+
play: async ({ canvasElement }) => {
|
|
540
|
+
await assertVisualizationRendered(canvasElement)
|
|
519
541
|
}
|
|
520
542
|
}
|
|
@@ -5,6 +5,7 @@ import SimplifiedLineConfig from './_mock/simplified_line.json'
|
|
|
5
5
|
|
|
6
6
|
import Chart from '../CdcChartComponent'
|
|
7
7
|
import { editConfigKeys } from '@cdc/core/helpers/configHelpers'
|
|
8
|
+
import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
|
|
8
9
|
|
|
9
10
|
const meta: Meta<typeof Chart> = {
|
|
10
11
|
title: 'Components/Templates/Chart/Legend',
|
|
@@ -16,41 +17,62 @@ type Story = StoryObj<typeof Chart>
|
|
|
16
17
|
export const Legend_Gradient_Smooth: Story = {
|
|
17
18
|
args: {
|
|
18
19
|
config: chartGradientConfig
|
|
20
|
+
},
|
|
21
|
+
play: async ({ canvasElement }) => {
|
|
22
|
+
await assertVisualizationRendered(canvasElement)
|
|
19
23
|
}
|
|
20
24
|
}
|
|
21
25
|
export const Legend_Group_By: Story = {
|
|
22
26
|
args: {
|
|
23
27
|
config: chartGroupedLagend
|
|
28
|
+
},
|
|
29
|
+
play: async ({ canvasElement }) => {
|
|
30
|
+
await assertVisualizationRendered(canvasElement)
|
|
24
31
|
}
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
export const Legend_Gradient_Linear_Blocks: Story = {
|
|
28
35
|
args: {
|
|
29
36
|
config: editConfigKeys(chartGradientConfig, [{ path: ['legend', 'subStyle'], value: 'linear blocks' }])
|
|
37
|
+
},
|
|
38
|
+
play: async ({ canvasElement }) => {
|
|
39
|
+
await assertVisualizationRendered(canvasElement)
|
|
30
40
|
}
|
|
31
41
|
}
|
|
32
42
|
|
|
33
43
|
export const Labels_On_Line_Legend_On_Top: Story = {
|
|
34
44
|
args: {
|
|
35
45
|
config: editConfigKeys(chartGradientConfig, [{ path: ['yAxis', 'labelsAboveGridlines'], value: true }])
|
|
46
|
+
},
|
|
47
|
+
play: async ({ canvasElement }) => {
|
|
48
|
+
await assertVisualizationRendered(canvasElement)
|
|
36
49
|
}
|
|
37
50
|
}
|
|
38
51
|
|
|
39
52
|
export const Legend_On_Right: Story = {
|
|
40
53
|
args: {
|
|
41
54
|
config: SimplifiedLineConfig
|
|
55
|
+
},
|
|
56
|
+
play: async ({ canvasElement }) => {
|
|
57
|
+
await assertVisualizationRendered(canvasElement)
|
|
42
58
|
}
|
|
43
59
|
}
|
|
44
60
|
|
|
45
61
|
export const Legend_On_Right_With_Box: Story = {
|
|
46
62
|
args: {
|
|
47
63
|
config: editConfigKeys(SimplifiedLineConfig, [{ path: ['legend', 'hideBorder'], value: false }])
|
|
64
|
+
},
|
|
65
|
+
play: async ({ canvasElement }) => {
|
|
66
|
+
await assertVisualizationRendered(canvasElement)
|
|
48
67
|
}
|
|
49
68
|
}
|
|
50
69
|
|
|
51
70
|
export const Legend_Gradient_With_box: Story = {
|
|
52
71
|
args: {
|
|
53
72
|
config: editConfigKeys(chartGradientConfig, [{ path: ['legend', 'hideBorder'], value: false }])
|
|
73
|
+
},
|
|
74
|
+
play: async ({ canvasElement }) => {
|
|
75
|
+
await assertVisualizationRendered(canvasElement)
|
|
54
76
|
}
|
|
55
77
|
}
|
|
56
78
|
|
|
@@ -61,6 +83,9 @@ export const Legend_Gradient_With_Text: Story = {
|
|
|
61
83
|
{ path: ['legend', 'description'], value: 'Description' },
|
|
62
84
|
{ path: ['legend', 'hideBorder'], value: false }
|
|
63
85
|
])
|
|
86
|
+
},
|
|
87
|
+
play: async ({ canvasElement }) => {
|
|
88
|
+
await assertVisualizationRendered(canvasElement)
|
|
64
89
|
}
|
|
65
90
|
}
|
|
66
91
|
export const Legend_Gradient_Wrapping_Label: Story = {
|
|
@@ -74,6 +99,9 @@ export const Legend_Gradient_Wrapping_Label: Story = {
|
|
|
74
99
|
])
|
|
75
100
|
).replace(/Data 1/g, 'This is a long string that should wrap')
|
|
76
101
|
)
|
|
102
|
+
},
|
|
103
|
+
play: async ({ canvasElement }) => {
|
|
104
|
+
await assertVisualizationRendered(canvasElement)
|
|
77
105
|
}
|
|
78
106
|
}
|
|
79
107
|
|
|
@@ -2,6 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react'
|
|
|
2
2
|
import StackedPattern from './_mock/stacked-pattern-test.json'
|
|
3
3
|
|
|
4
4
|
import Chart from '../CdcChartComponent'
|
|
5
|
+
import { assertVisualizationRendered } from '@cdc/core/helpers/testing'
|
|
5
6
|
|
|
6
7
|
const meta: Meta<typeof Chart> = {
|
|
7
8
|
title: 'Components/Templates/Chart/Patterns',
|
|
@@ -14,6 +15,9 @@ export const Stacked_Bar_Pattern: Story = {
|
|
|
14
15
|
args: {
|
|
15
16
|
config: StackedPattern,
|
|
16
17
|
isEditor: true
|
|
18
|
+
},
|
|
19
|
+
play: async ({ canvasElement }) => {
|
|
20
|
+
await assertVisualizationRendered(canvasElement)
|
|
17
21
|
}
|
|
18
22
|
}
|
|
19
23
|
|