@cdc/chart 4.26.3 → 4.26.5
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/CONFIG.md +489 -0
- package/README.md +42 -17
- package/dist/cdcchart.js +39024 -36587
- package/examples/feature/bar/additional-column-tooltip.json +3 -3
- package/examples/feature/deviation/planet-deviation-config.json +2 -2
- package/examples/feature/heatmap/average-age-categorical.json +313 -0
- package/examples/feature/heatmap/calendar-heatmap.json +134 -0
- package/examples/feature/heatmap/cell-values-bottom-axis.json +181 -0
- package/examples/feature/heatmap/sparse-aggregation.json +158 -0
- package/examples/feature/paired-bar/paired-bar-example.json +2 -2
- package/examples/feature/tests-case-rate/case-rate-example-config.json +2 -2
- package/examples/feature/tests-covid/covid-confidence-example-config.json +2 -2
- package/examples/feature/tests-covid/covid-example-config.json +2 -2
- package/examples/feature/tests-cutoff/cutoff-example-config.json +2 -2
- package/examples/feature/tests-non-numerics/planet-pie-example-config-nonnumeric.json +2 -2
- package/examples/metadata-variables.json +1 -1
- package/examples/minimal-example.json +24 -0
- package/examples/private/bump-chart.json +1116 -0
- package/examples/private/test-123.json +624 -0
- package/examples/private/test2.json +35012 -0
- package/package.json +5 -4
- package/src/CdcChartComponent.tsx +144 -60
- package/src/_stories/Chart.AltText.stories.tsx +136 -0
- package/src/_stories/{Chart.HTMLInDataTable.stories.tsx → Chart.HTMLInDataTable.smoke.stories.tsx} +10 -0
- package/src/_stories/Chart.HeatMap.stories.tsx +187 -0
- package/src/_stories/Chart.Minimal.smoke.stories.tsx +25 -0
- package/src/_stories/Chart.Sankey.smoke.stories.tsx +62 -0
- package/src/_stories/Chart.SmallMultiples.smoke.stories.tsx +108 -0
- package/src/_stories/{Chart.stories.tsx → Chart.smoke.stories.tsx} +12 -0
- package/src/_stories/{Chart.tooltip.stories.tsx → Chart.tooltip.smoke.stories.tsx} +68 -0
- package/src/_stories/{ChartAxisTitles.stories.tsx → ChartAxisTitles.smoke.stories.tsx} +13 -0
- package/src/_stories/ChartBar.Editor.stories.tsx +151 -85
- package/src/_stories/ChartBrush.Interaction.stories.tsx +112 -0
- package/src/_stories/{ChartBrush.stories.tsx → ChartBrush.smoke.stories.tsx} +13 -4
- package/src/_stories/ChartEditor.Editor.stories.tsx +23 -0
- package/src/_stories/ChartLine.DashedDates.smoke.stories.tsx +23 -0
- package/src/_stories/_mock/alt_text_metadata.json +38 -0
- package/src/_stories/_mock/heatmap-average-age-categorical.json +315 -0
- package/src/_stories/_mock/heatmap.json +156 -0
- package/src/_stories/_mock/line_chart_dashed_dates.json +276 -0
- package/src/_stories/_mock/paired-bar-abbr.json +1 -1
- package/src/_stories/_mock/paired-bar.json +1 -1
- package/src/_stories/_mock/reported_pertussis_cases.json +1643 -0
- package/src/_stories/_mock/sankey_mock.json +78 -0
- package/src/_stories/_mock/small_multiples/small_multiples_lines.json +1 -1
- package/src/components/Annotations/components/AnnotationDraggable.tsx +2 -2
- package/src/components/Annotations/components/AnnotationDropdown.tsx +5 -2
- package/src/components/AreaChart/components/AreaChart.Stacked.jsx +10 -2
- package/src/components/Axis/BottomAxis.tsx +1 -1
- package/src/components/Axis/LeftAxis.tsx +15 -14
- package/src/components/Axis/LeftAxisGridlines.tsx +14 -13
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +9 -5
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +9 -5
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +9 -5
- package/src/components/BarChart/components/BarChart.Vertical.tsx +9 -6
- package/src/components/BarChart/components/BarChart.tsx +2 -6
- package/src/components/BarChart/helpers/useBarChart.ts +1 -1
- package/src/components/BoxPlot/BoxPlot.Vertical.tsx +3 -3
- package/src/components/Brush/BrushSelector.tsx +88 -187
- package/src/components/Brush/brushInteraction.ts +22 -0
- package/src/components/Brush/tests/brushInteraction.test.ts +38 -0
- package/src/components/EditorPanel/EditorPanel.tsx +946 -960
- package/src/components/EditorPanel/EditorPanelContext.ts +1 -1
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +229 -165
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +105 -13
- package/src/components/EditorPanel/components/Panels/Panel.PatternSettings.tsx +169 -116
- package/src/components/EditorPanel/components/Panels/Panel.Regions.tsx +159 -109
- package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +3 -3
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +14 -28
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +1 -1
- package/src/components/EditorPanel/helpers/getVisualizationTypeConfigUpdate.ts +57 -0
- package/src/components/EditorPanel/helpers/tests/getVisualizationTypeConfigUpdate.test.ts +56 -0
- package/src/components/EditorPanel/useEditorPermissions.test.tsx +70 -0
- package/src/components/EditorPanel/useEditorPermissions.ts +32 -21
- package/src/components/Forecasting/Forecasting.tsx +2 -2
- package/src/components/HeatMap/components/HeatMap.tsx +762 -0
- package/src/components/HeatMap/components/HeatMapGradientLegend.tsx +114 -0
- package/src/components/HeatMap/heatmap.constants.ts +13 -0
- package/src/components/HeatMap/heatmap.css +71 -0
- package/src/components/HeatMap/helpers/index.ts +261 -0
- package/src/components/HeatMap/index.tsx +5 -0
- package/src/components/HeatMap/tests/HeatMap.test.tsx +1040 -0
- package/src/components/HeatMap/tests/helpers.test.ts +167 -0
- package/src/components/HorizonChart/HorizonChart.tsx +10 -2
- package/src/components/HoverLine/HoverLine.tsx +6 -8
- package/src/components/Legend/Legend.Component.tsx +4 -4
- package/src/components/Legend/LegendGroup/LegendGroup.styles.css +5 -0
- package/src/components/Legend/LegendGroup/LegendGroup.tsx +3 -1
- package/src/components/Legend/helpers/index.ts +0 -2
- package/src/components/LineChart/LineChartProps.ts +1 -0
- package/src/components/LineChart/components/LineChart.BumpCircle.tsx +22 -24
- package/src/components/LineChart/helpers.test.ts +345 -0
- package/src/components/LineChart/helpers.ts +15 -5
- package/src/components/LineChart/index.tsx +18 -5
- package/src/components/LinearChart/VisualizationRenderer.tsx +11 -1
- package/src/components/LinearChart/tests/LinearChart.test.tsx +228 -7
- package/src/components/LinearChart/tests/mockConfigContext.ts +1 -0
- package/src/components/LinearChart.tsx +155 -77
- package/src/components/PairedBarChart.jsx +2 -2
- package/src/components/PieChart/PieChart.tsx +15 -10
- package/src/components/RadarChart/RadarChart.tsx +3 -1
- package/src/components/Regions/components/Regions.tsx +199 -35
- package/src/components/Sankey/components/Sankey.tsx +7 -3
- package/src/components/Sankey/helpers/getSankeyTooltip.tsx +7 -6
- package/src/components/ScatterPlot/ScatterPlot.jsx +19 -17
- package/src/components/SmallMultiples/SmallMultipleTile.tsx +31 -3
- package/src/components/SmallMultiples/SmallMultiples.css +12 -0
- package/src/components/SmallMultiples/SmallMultiples.tsx +15 -9
- package/src/components/SmallMultiples/tests/SmallMultipleTile.test.tsx +152 -0
- package/src/components/Sparkline/components/SparkLine.tsx +5 -10
- package/src/components/WarmingStripes/WarmingStripes.tsx +5 -3
- package/src/components/WarmingStripes/WarmingStripesGradientLegend.css +1 -1
- package/src/components/WarmingStripes/WarmingStripesGradientLegend.tsx +2 -2
- package/src/data/initial-state.js +12 -0
- package/src/helpers/axisLabelFontSize.ts +8 -0
- package/src/helpers/bumpChartTooltip.ts +54 -0
- package/src/helpers/calculateLeftYAxisWidth.ts +197 -0
- package/src/helpers/ensureSpecialChartAxisTypes.ts +11 -0
- package/src/helpers/getMinMax.ts +2 -3
- package/src/helpers/getYAxisAutoPadding.ts +8 -6
- package/src/helpers/getYAxisAutoPaddingMode.ts +17 -0
- package/src/helpers/handleChartAriaLabels.ts +23 -10
- package/src/helpers/seriesHighlight.ts +26 -0
- package/src/helpers/tests/axisLabelFontSize.test.ts +15 -0
- package/src/helpers/tests/bumpChartTooltip.test.ts +75 -0
- package/src/helpers/tests/ensureSpecialChartAxisTypes.test.ts +30 -0
- package/src/helpers/tests/getYAxisAutoPadding.test.ts +37 -0
- package/src/helpers/tests/getYAxisAutoPaddingMode.test.ts +90 -0
- package/src/helpers/tests/handleChartAriaLabels.test.ts +71 -0
- package/src/helpers/tests/seriesHighlight.test.ts +61 -0
- package/src/helpers/tests/tooltipHelpers.test.ts +151 -0
- package/src/helpers/tooltipHelpers.ts +176 -0
- package/src/hooks/tests/useScales.test.tsx +105 -0
- package/src/hooks/useHighlightedBars.ts +9 -16
- package/src/hooks/useProgrammaticTooltip.ts +16 -2
- package/src/hooks/useScales.ts +19 -9
- package/src/hooks/useSmallMultipleSynchronization.ts +3 -4
- package/src/hooks/useTooltip.tsx +167 -38
- package/src/index.jsx +5 -2
- package/src/scss/main.scss +32 -49
- package/src/test/CdcChart.test.jsx +24 -0
- package/src/types/ChartConfig.ts +19 -0
- package/src/types/ChartContext.ts +2 -0
- package/examples/chart-regression-2.json +0 -2360
- package/examples/feature/__data__/age-adjusted-rates.json +0 -1486
- package/examples/feature/__data__/city-temperature.json +0 -2198
- package/examples/feature/bar/Barchart_with_negative.json +0 -34
- package/examples/feature/boxplot/box-plot-data.json +0 -71
- package/examples/feature/boxplot/boxplot-data.json +0 -156
- package/examples/feature/combo/combochart-categories_are_numbers .json +0 -18
- package/examples/feature/forest-plot/log.json +0 -26
- package/examples/feature/tests-date-exclusions/date-exclusions-data.json +0 -162
- package/examples/region-issue.json +0 -2065
- package/examples/xaxis.json +0 -493
- package/src/_stories/Chart.SmallMultiples.stories.tsx +0 -63
- /package/examples/{data → __data__}/data-with-metadata.json +0 -0
- /package/examples/feature/bar/{tall-data.json → __data__/tall-data.json} +0 -0
- /package/examples/feature/deviation/{planet-deviation-data.json → __data__/planet-deviation-data.json} +0 -0
- /package/examples/feature/paired-bar/{paired-bar-data.json → __data__/paired-bar-data.json} +0 -0
- /package/examples/feature/paired-bar/{paired-bar-formatted.json → __data__/paired-bar-formatted.json} +0 -0
- /package/examples/feature/tests-case-rate/{case-rate-example-data.json → __data__/case-rate-example-data.json} +0 -0
- /package/examples/feature/tests-covid/{covid-example-data-confidence.json → __data__/covid-example-data-confidence.json} +0 -0
- /package/examples/feature/tests-covid/{covid-example-data.json → __data__/covid-example-data.json} +0 -0
- /package/examples/feature/tests-cutoff/{cutoff-example-data.json → __data__/cutoff-example-data.json} +0 -0
- /package/examples/feature/tests-non-numerics/{planet-example-data-nonnumeric.json → __data__/planet-example-data-nonnumeric.json} +0 -0
- /package/src/_stories/{Chart.Anchors.stories.tsx → Chart.Anchors.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.BoxPlot.stories.tsx → Chart.BoxPlot.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.CI.stories.tsx → Chart.CI.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Combo.stories.tsx → Chart.Combo.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.CustomColors.stories.tsx → Chart.CustomColors.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Defaults.stories.tsx → Chart.Defaults.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.DynamicSeries.stories.tsx → Chart.DynamicSeries.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Filters.stories.tsx → Chart.Filters.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Forecast.stories.tsx → Chart.Forecast.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Legend.Gradient.stories.tsx → Chart.Legend.Gradient.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Patterns.stories.tsx → Chart.Patterns.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.PreserveDecimals.stories.tsx → Chart.PreserveDecimals.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Regions.Categorical.stories.tsx → Chart.Regions.Categorical.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Regions.DateScale.stories.tsx → Chart.Regions.DateScale.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.Regions.DateTimeScale.stories.tsx → Chart.Regions.DateTimeScale.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.ScatterPlot.stories.tsx → Chart.ScatterPlot.smoke.stories.tsx} +0 -0
- /package/src/_stories/{Chart.SmallestLeftAxisMax.stories.tsx → Chart.SmallestLeftAxisMax.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartAnnotation.stories.tsx → ChartAnnotation.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartAxisLabels.stories.tsx → ChartAxisLabels.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartBrush.Matrix.Continuous.stories.tsx → ChartBrush.Matrix.Continuous.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartBrush.Matrix.Date.stories.tsx → ChartBrush.Matrix.Date.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartBrush.Matrix.DateTime.stories.tsx → ChartBrush.Matrix.DateTime.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartLine.QuadrantAngles.stories.tsx → ChartLine.QuadrantAngles.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartLine.Suppression.stories.tsx → ChartLine.Suppression.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartLine.Symbols.stories.tsx → ChartLine.Symbols.smoke.stories.tsx} +0 -0
- /package/src/_stories/{ChartPrefixSuffix.stories.tsx → ChartPrefixSuffix.smoke.stories.tsx} +0 -0
- /package/src/_stories/{TechAdoptionWithLinks.stories.tsx → TechAdoptionWithLinks.smoke.stories.tsx} +0 -0
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdc/chart",
|
|
3
|
-
"version": "4.26.
|
|
3
|
+
"version": "4.26.5",
|
|
4
4
|
"description": "React component for visualizing tabular data in various types of charts",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Matthew Pallansch <mpallansch@adittech.com>",
|
|
7
7
|
"bugs": "https://github.com/CDCgov/cdc-open-viz/issues",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@cdc/core": "^4.26.
|
|
9
|
+
"@cdc/core": "^4.26.5",
|
|
10
10
|
"@hello-pangea/dnd": "^16.2.0",
|
|
11
11
|
"@react-spring/web": "^9.7.5",
|
|
12
12
|
"@rollup/plugin-dsv": "^3.0.2",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"@visx/event": "^3.12.0",
|
|
19
19
|
"@visx/glyph": "^3.12.0",
|
|
20
20
|
"@visx/gradient": "^3.12.0",
|
|
21
|
+
"@visx/heatmap": "^3.12.0",
|
|
21
22
|
"@visx/legend": "^3.12.0",
|
|
22
23
|
"@visx/marker": "^3.12.0",
|
|
23
24
|
"@visx/mock-data": "^3.12.0",
|
|
@@ -34,7 +35,7 @@
|
|
|
34
35
|
"d3-format": "^3.1.2",
|
|
35
36
|
"d3-sankey": "^0.12.3",
|
|
36
37
|
"d3-time-format": "^4.1.0",
|
|
37
|
-
"dompurify": "^3.
|
|
38
|
+
"dompurify": "^3.4.0",
|
|
38
39
|
"html-react-parser": "^5.2.3",
|
|
39
40
|
"js-base64": "^2.5.2",
|
|
40
41
|
"lodash": "^4.17.23",
|
|
@@ -56,7 +57,7 @@
|
|
|
56
57
|
"@types/d3-sankey": "^0.12.4",
|
|
57
58
|
"@types/d3-time-format": "^4.0.3"
|
|
58
59
|
},
|
|
59
|
-
"gitHead": "
|
|
60
|
+
"gitHead": "61c025165d96b45a6002c34582c5a622a9d865a9",
|
|
60
61
|
"main": "dist/cdcchart",
|
|
61
62
|
"moduleName": "CdcChart",
|
|
62
63
|
"peerDependencies": {
|
|
@@ -27,7 +27,6 @@ import parse from 'html-react-parser'
|
|
|
27
27
|
import cloneDeep from 'lodash/cloneDeep'
|
|
28
28
|
import defaultsDeep from 'lodash/defaultsDeep'
|
|
29
29
|
import lodashDefaults from 'lodash/defaults'
|
|
30
|
-
import findKey from 'lodash/findKey'
|
|
31
30
|
import forEach from 'lodash/forEach'
|
|
32
31
|
import get from 'lodash/get'
|
|
33
32
|
import isEmpty from 'lodash/isEmpty'
|
|
@@ -44,6 +43,7 @@ import ConfigContext, { ChartDispatchContext } from './ConfigContext'
|
|
|
44
43
|
import PieChart from './components/PieChart'
|
|
45
44
|
import RadarChart from './components/RadarChart'
|
|
46
45
|
import SankeyChart from './components/Sankey'
|
|
46
|
+
import HeatMap, { HeatMapGradientLegend } from './components/HeatMap'
|
|
47
47
|
import LinearChart from './components/LinearChart'
|
|
48
48
|
import { isDateScale, formatDate as coreFormatDate } from '@cdc/core/helpers/cove/date'
|
|
49
49
|
|
|
@@ -74,9 +74,11 @@ import { getVisibleAnnotations } from './components/Annotations/helpers/getVisib
|
|
|
74
74
|
import { DataTransform } from '@cdc/core/helpers/DataTransform'
|
|
75
75
|
import { backfillDefaults } from '@cdc/core/helpers/backfillDefaults'
|
|
76
76
|
import { isLegendWrapViewport } from '@cdc/core/helpers/viewports'
|
|
77
|
+
import { getAxisLabelFontSize } from './helpers/axisLabelFontSize'
|
|
77
78
|
import { missingRequiredSections } from '@cdc/core/helpers/missingRequiredSections'
|
|
78
79
|
import { filterVizData } from '@cdc/core/helpers/filterVizData'
|
|
79
80
|
import { addValuesToFilters } from '@cdc/core/helpers/addValuesToFilters'
|
|
81
|
+
import { hasVisibleVizFilters } from '@cdc/core/helpers/filterVisibility'
|
|
80
82
|
import { publish, subscribe, unsubscribe } from '@cdc/core/helpers/events'
|
|
81
83
|
import useDataVizClasses from '@cdc/core/helpers/useDataVizClasses'
|
|
82
84
|
import numberFromString from '@cdc/core/helpers/numberFromString'
|
|
@@ -93,8 +95,12 @@ import { getComboChartConfig } from './helpers/getComboChartConfig'
|
|
|
93
95
|
import { getExcludedData } from './helpers/getExcludedData'
|
|
94
96
|
import { getColorScale } from './helpers/getColorScale'
|
|
95
97
|
import { getTransformedData } from './helpers/getTransformedData'
|
|
98
|
+
import { getLegendHighlightKey, shouldResetSeriesHighlight } from './helpers/seriesHighlight'
|
|
96
99
|
import { getPiePercent } from './helpers/getPiePercent'
|
|
97
100
|
import { prepareSmallMultiplesDataTable } from './helpers/smallMultiplesHelpers'
|
|
101
|
+
import { calcInitialHeight } from './helpers/sizeHelpers'
|
|
102
|
+
import { ensureSpecialChartAxisTypes } from './helpers/ensureSpecialChartAxisTypes'
|
|
103
|
+
import { findColumnConfigByName } from './helpers/seriesColumnSettings'
|
|
98
104
|
|
|
99
105
|
// styles
|
|
100
106
|
import './scss/main.scss'
|
|
@@ -147,6 +153,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
147
153
|
excludedData,
|
|
148
154
|
filteredData,
|
|
149
155
|
currentViewport,
|
|
156
|
+
vizViewport,
|
|
150
157
|
isLoading,
|
|
151
158
|
dimensions,
|
|
152
159
|
container,
|
|
@@ -300,6 +307,17 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
300
307
|
}
|
|
301
308
|
}
|
|
302
309
|
|
|
310
|
+
if (loadedConfig?.visualizationType === 'HeatMap' && !loadedConfig?.general?.palette) {
|
|
311
|
+
if (!defaultsWithoutPalette.general) {
|
|
312
|
+
defaultsWithoutPalette.general = {}
|
|
313
|
+
}
|
|
314
|
+
defaultsWithoutPalette.general.palette = {
|
|
315
|
+
isReversed: false,
|
|
316
|
+
version: '2.0',
|
|
317
|
+
name: 'sequential_blue'
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
303
321
|
let newConfig = { ...defaultsWithoutPalette, ...loadedConfig }
|
|
304
322
|
|
|
305
323
|
// Ensure Horizon Chart has enough palette colors for all layers
|
|
@@ -322,9 +340,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
322
340
|
})
|
|
323
341
|
})
|
|
324
342
|
|
|
325
|
-
|
|
326
|
-
newConfig.xAxis.type === 'date-time'
|
|
327
|
-
}
|
|
343
|
+
ensureSpecialChartAxisTypes(newConfig)
|
|
328
344
|
if (!isDashboard) return coveUpdateWorker(newConfig)
|
|
329
345
|
return newConfig
|
|
330
346
|
}
|
|
@@ -380,6 +396,10 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
380
396
|
const updateConfig = (_config: AllChartsConfig, dataOverride?: any[]) => {
|
|
381
397
|
const newConfig = cloneConfig(_config)
|
|
382
398
|
let data = dataOverride || stateData
|
|
399
|
+
const shouldUseHeatMapSideTitlePlacement =
|
|
400
|
+
newConfig.visualizationType === 'HeatMap' && !newConfig.yAxis?.titlePlacement
|
|
401
|
+
|
|
402
|
+
ensureSpecialChartAxisTypes(newConfig)
|
|
383
403
|
|
|
384
404
|
data = handleRankByValue(data, newConfig)
|
|
385
405
|
|
|
@@ -388,6 +408,9 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
388
408
|
|
|
389
409
|
// Backfill missing properties from defaults, respecting legacy values
|
|
390
410
|
backfillDefaults(newConfig, defaults, LEGACY_CHART_DEFAULTS)
|
|
411
|
+
if (shouldUseHeatMapSideTitlePlacement) {
|
|
412
|
+
newConfig.yAxis.titlePlacement = 'side'
|
|
413
|
+
}
|
|
391
414
|
|
|
392
415
|
// Auto-populate table.defaultSort for date-axis charts if not already set by user
|
|
393
416
|
const hasDateAxisType = ['date-time', 'date'].includes(newConfig.xAxis?.type)
|
|
@@ -528,6 +551,31 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
528
551
|
}
|
|
529
552
|
}
|
|
530
553
|
|
|
554
|
+
if (newConfig.visualizationType === 'HeatMap') {
|
|
555
|
+
const heatMapSeriesKeys = newConfig.series.map(series => series.dataKey)
|
|
556
|
+
const heatMapSeriesLabels = newConfig.series.reduce<Record<string, string>>((acc, series) => {
|
|
557
|
+
const heatMapColumnConfig = findColumnConfigByName(newConfig.columns || {}, series.dataKey)?.columnConfig
|
|
558
|
+
const configuredColumnLabel = heatMapColumnConfig?.label
|
|
559
|
+
const hasCustomColumnLabel = configuredColumnLabel && configuredColumnLabel !== series.dataKey
|
|
560
|
+
acc[series.dataKey] = hasCustomColumnLabel ? configuredColumnLabel : series.name || series.dataKey
|
|
561
|
+
return acc
|
|
562
|
+
}, {})
|
|
563
|
+
|
|
564
|
+
newConfig.legend = {
|
|
565
|
+
...newConfig.legend,
|
|
566
|
+
position: newConfig.legend?.position || 'top',
|
|
567
|
+
style: newConfig.legend?.style || 'gradient',
|
|
568
|
+
subStyle: newConfig.legend?.subStyle || 'smooth'
|
|
569
|
+
}
|
|
570
|
+
newConfig.yAxis = {
|
|
571
|
+
...newConfig.yAxis,
|
|
572
|
+
type: 'categorical'
|
|
573
|
+
}
|
|
574
|
+
newConfig.runtime.seriesKeys = heatMapSeriesKeys
|
|
575
|
+
newConfig.runtime.seriesLabelsAll = heatMapSeriesKeys
|
|
576
|
+
newConfig.runtime.seriesLabels = heatMapSeriesLabels
|
|
577
|
+
}
|
|
578
|
+
|
|
531
579
|
if (isHorizontalVariant) {
|
|
532
580
|
// For horizontal charts, axes are swapped, so processedYAxis goes to runtime.xAxis and vice versa
|
|
533
581
|
const horizontalXAxisSource = cloneDeep((newConfig.yAxis as any)?.yAxis || newConfig.yAxis)
|
|
@@ -540,7 +588,6 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
540
588
|
...horizontalYAxisSource,
|
|
541
589
|
label: runtimeYAxisLabel ?? horizontalYAxisSource?.label
|
|
542
590
|
}
|
|
543
|
-
newConfig.runtime.yAxis.labelOffset *= -1
|
|
544
591
|
|
|
545
592
|
newConfig.runtime.horizontal = false
|
|
546
593
|
newConfig.orientation = 'horizontal'
|
|
@@ -580,6 +627,19 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
580
627
|
} else {
|
|
581
628
|
newConfig.runtime.editorErrorMessage = ''
|
|
582
629
|
}
|
|
630
|
+
} else if (newConfig.visualizationType === 'HeatMap') {
|
|
631
|
+
const missingXColumn = !newConfig.xAxis.dataKey || newConfig.xAxis.dataKey === ''
|
|
632
|
+
const missingSeries = !Array.isArray(newConfig.series) || newConfig.series.length === 0
|
|
633
|
+
|
|
634
|
+
if (missingXColumn && missingSeries) {
|
|
635
|
+
newConfig.runtime.editorErrorMessage = 'Date/Category Axis and Data Series must be set for heatmaps.'
|
|
636
|
+
} else if (missingXColumn) {
|
|
637
|
+
newConfig.runtime.editorErrorMessage = 'Date/Category Axis must be set for heatmaps.'
|
|
638
|
+
} else if (missingSeries) {
|
|
639
|
+
newConfig.runtime.editorErrorMessage = 'Data Series must be set for heatmaps.'
|
|
640
|
+
} else {
|
|
641
|
+
newConfig.runtime.editorErrorMessage = ''
|
|
642
|
+
}
|
|
583
643
|
} else {
|
|
584
644
|
// No errors
|
|
585
645
|
newConfig.runtime.editorErrorMessage = ''
|
|
@@ -871,17 +931,15 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
871
931
|
}, [config, stateData, getProcessedAxisLabels, dispatch, editorContext, isEditor, isDashboard])
|
|
872
932
|
|
|
873
933
|
// Called on legend click, highlights/unhighlights the data series with the given label
|
|
874
|
-
const highlight = (label: Label): void => {
|
|
934
|
+
const highlight = (label: Label | string): void => {
|
|
935
|
+
const newHighlight = getLegendHighlightKey(config.runtime.seriesLabels, label)
|
|
936
|
+
|
|
875
937
|
if (
|
|
876
|
-
seriesHighlight
|
|
877
|
-
config.visualizationType !== 'Forecasting' &&
|
|
878
|
-
!seriesHighlight.includes(label.datum)
|
|
938
|
+
shouldResetSeriesHighlight(seriesHighlight, config.runtime.seriesKeys, newHighlight, config.visualizationType)
|
|
879
939
|
) {
|
|
880
940
|
return handleShowAll()
|
|
881
941
|
}
|
|
882
942
|
|
|
883
|
-
const newHighlight = findKey(config.runtime.seriesLabels, v => v === label.datum) || label.datum
|
|
884
|
-
|
|
885
943
|
const newSeriesHighlight = xor(seriesHighlight, [newHighlight])
|
|
886
944
|
dispatch({ type: 'SET_SERIES_HIGHLIGHT', payload: newSeriesHighlight })
|
|
887
945
|
}
|
|
@@ -1200,6 +1258,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1200
1258
|
|
|
1201
1259
|
// Filter annotations to only those visible in current data view
|
|
1202
1260
|
const visibleAnnotations = getVisibleAnnotations(config.annotations, transformedData, config.xAxis?.dataKey)
|
|
1261
|
+
const isHeatMap = config.visualizationType === 'HeatMap'
|
|
1203
1262
|
const isTp5Treatment = ENABLE_CHART_MAP_TP5_TREATMENT && config.visual?.tp5Treatment
|
|
1204
1263
|
const visualSettingClasses = new Set([
|
|
1205
1264
|
'component--has-border-color-theme',
|
|
@@ -1220,6 +1279,12 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1220
1279
|
bodyClasses.push('component--hide-background-color')
|
|
1221
1280
|
}
|
|
1222
1281
|
if (isTp5Treatment && !bodyClasses.includes('no-borders')) bodyClasses.push('no-borders')
|
|
1282
|
+
const bodyWrapClasses = [
|
|
1283
|
+
isTp5Treatment ? 'cdc-callout d-flex flex-column tp5-chart-callout' : '',
|
|
1284
|
+
isHeatMap ? 'cdc-heatmap__body-wrap' : ''
|
|
1285
|
+
]
|
|
1286
|
+
.filter(Boolean)
|
|
1287
|
+
.join(' ')
|
|
1223
1288
|
const chartTitle = (
|
|
1224
1289
|
<Title
|
|
1225
1290
|
showTitle={config.showTitle}
|
|
@@ -1242,7 +1307,6 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1242
1307
|
return kebabCase(string)
|
|
1243
1308
|
}
|
|
1244
1309
|
const getChartWrapperClasses = () => {
|
|
1245
|
-
const isLegendOnBottom = legend?.position === 'bottom' || isLegendWrapViewport(currentViewport)
|
|
1246
1310
|
const classes = ['chart-container', 'visualization-container', 'p-relative']
|
|
1247
1311
|
const visualSettingClasses = ['component--has-border-color-theme', 'component--has-accent']
|
|
1248
1312
|
if (legend?.position) {
|
|
@@ -1253,11 +1317,10 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1253
1317
|
}
|
|
1254
1318
|
}
|
|
1255
1319
|
if (legend?.hide) classes.push('legend-hidden')
|
|
1320
|
+
if (isHeatMap) classes.push('cdc-heatmap__container')
|
|
1256
1321
|
if (contentClasses.includes('sparkline')) classes.push('sparkline')
|
|
1257
1322
|
if (lineDatapointClass) classes.push(lineDatapointClass)
|
|
1258
1323
|
if (!config.barHasBorder) classes.push('chart-bar--no-border')
|
|
1259
|
-
if (config.xAxis.brushActive && dashboardConfig?.type === 'dashboard' && (!isLegendOnBottom || legend.hide))
|
|
1260
|
-
classes.push('dashboard-brush')
|
|
1261
1324
|
|
|
1262
1325
|
if (!ENABLE_CHART_VISUAL_SETTINGS) {
|
|
1263
1326
|
const filtered = classes.filter(className => !visualSettingClasses.includes(className))
|
|
@@ -1276,6 +1339,34 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1276
1339
|
return classes
|
|
1277
1340
|
}
|
|
1278
1341
|
|
|
1342
|
+
const showTopYAxisTitle =
|
|
1343
|
+
config.yAxis?.titlePlacement === 'top' &&
|
|
1344
|
+
!config.smallMultiples?.mode &&
|
|
1345
|
+
!config.hideYAxisLabel &&
|
|
1346
|
+
Boolean(config.runtime?.yAxis?.label)
|
|
1347
|
+
const topYAxisTitleFontSize = getAxisLabelFontSize(vizViewport)
|
|
1348
|
+
|
|
1349
|
+
const renderTopYAxisTitle = () =>
|
|
1350
|
+
showTopYAxisTitle ? (
|
|
1351
|
+
<div className='y-axis-top-title' style={{ fontSize: `${topYAxisTitleFontSize}px` }}>
|
|
1352
|
+
{config.runtime.yAxis.label}
|
|
1353
|
+
</div>
|
|
1354
|
+
) : null
|
|
1355
|
+
|
|
1356
|
+
const renderLinearChartWithParentSize = (
|
|
1357
|
+
getParentWidth: (parent: { width: number; height: number }) => number = parent => parent.width,
|
|
1358
|
+
wrapperStyle: React.CSSProperties = { width: '100%' }
|
|
1359
|
+
) => (
|
|
1360
|
+
<>
|
|
1361
|
+
{renderTopYAxisTitle()}
|
|
1362
|
+
<div ref={parentRef} style={wrapperStyle}>
|
|
1363
|
+
<ParentSize>
|
|
1364
|
+
{parent => <LinearChart ref={svgRef} parentWidth={getParentWidth(parent)} parentHeight={parent.height} />}
|
|
1365
|
+
</ParentSize>
|
|
1366
|
+
</div>
|
|
1367
|
+
</>
|
|
1368
|
+
)
|
|
1369
|
+
|
|
1279
1370
|
if (!isLoading) {
|
|
1280
1371
|
const tableLink = (
|
|
1281
1372
|
<a href={`#data-table-${config.dataKey}`} className='margin-left-href'>
|
|
@@ -1288,11 +1379,11 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1288
1379
|
{!missingRequiredSections(config) && !config.newViz && (
|
|
1289
1380
|
<VisualizationContent
|
|
1290
1381
|
innerClassName={`type-${makeClassName(config.visualizationType)}`}
|
|
1291
|
-
innerProps={{
|
|
1382
|
+
innerProps={{ tabIndex: 0 }}
|
|
1292
1383
|
bodyClassName={bodyClasses.join(' ')}
|
|
1293
|
-
bodyWrapClassName={
|
|
1384
|
+
bodyWrapClassName={bodyWrapClasses}
|
|
1294
1385
|
filters={
|
|
1295
|
-
config.filters
|
|
1386
|
+
hasVisibleVizFilters(config.filters) && !externalFilters && config.visualizationType !== 'Spark Line' ? (
|
|
1296
1387
|
<Filters
|
|
1297
1388
|
config={config}
|
|
1298
1389
|
setFilters={setFilters}
|
|
@@ -1304,7 +1395,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1304
1395
|
}
|
|
1305
1396
|
bodySubtext={
|
|
1306
1397
|
processedDescription && config.visualizationType !== 'Spark Line' ? (
|
|
1307
|
-
<div className={getChartSubTextClasses().join(' ')}>{parse(processedDescription)}</div>
|
|
1398
|
+
<div className={`cove-prose ${getChartSubTextClasses().join(' ')}`}>{parse(processedDescription)}</div>
|
|
1308
1399
|
) : null
|
|
1309
1400
|
}
|
|
1310
1401
|
bodyFooter={
|
|
@@ -1391,21 +1482,26 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1391
1482
|
)}
|
|
1392
1483
|
{visibleAnnotations.length > 0 && <Annotation.Dropdown />}
|
|
1393
1484
|
{processedLegacyFootnotes && (
|
|
1394
|
-
<section className='footnotes pt-2 mt-4'>{parse(processedLegacyFootnotes)}</section>
|
|
1485
|
+
<section className='footnotes cove-prose pt-2 mt-4'>{parse(processedLegacyFootnotes)}</section>
|
|
1395
1486
|
)}
|
|
1396
1487
|
</>
|
|
1397
1488
|
}
|
|
1398
1489
|
header={isTp5Treatment ? null : chartTitle}
|
|
1399
1490
|
messageIsIntroText={config.visualizationType !== 'Spark Line' && !!processedIntroText}
|
|
1400
|
-
message={
|
|
1491
|
+
message={
|
|
1492
|
+
config.visualizationType !== 'Spark Line' && processedIntroText ? (
|
|
1493
|
+
<div className='cove-prose'>{parse(processedIntroText)}</div>
|
|
1494
|
+
) : null
|
|
1495
|
+
}
|
|
1401
1496
|
footer={
|
|
1402
1497
|
<FootnotesStandAlone
|
|
1403
|
-
config={
|
|
1498
|
+
config={config.footnotes}
|
|
1404
1499
|
filters={config.filters?.filter(f => f.filterFootnotes)}
|
|
1405
1500
|
markupVariables={config.markupVariables}
|
|
1406
1501
|
enableMarkupVariables={config.enableMarkupVariables}
|
|
1407
1502
|
data={config.data}
|
|
1408
1503
|
dataMetadata={config.dataMetadata}
|
|
1504
|
+
footerClassName='cove-visualization__footnotes'
|
|
1409
1505
|
/>
|
|
1410
1506
|
}
|
|
1411
1507
|
>
|
|
@@ -1443,15 +1539,8 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1443
1539
|
{/* All charts with LinearChart */}
|
|
1444
1540
|
{filteredData &&
|
|
1445
1541
|
filteredData.length > 0 &&
|
|
1446
|
-
!['Spark Line', 'Line', 'Sankey', 'Pie', 'Radar'].includes(config.visualizationType) &&
|
|
1447
|
-
|
|
1448
|
-
<ParentSize>
|
|
1449
|
-
{parent => (
|
|
1450
|
-
<LinearChart ref={svgRef} parentWidth={parent.width} parentHeight={parent.height} />
|
|
1451
|
-
)}
|
|
1452
|
-
</ParentSize>
|
|
1453
|
-
</div>
|
|
1454
|
-
)}
|
|
1542
|
+
!['Spark Line', 'Line', 'Sankey', 'Pie', 'Radar', 'HeatMap'].includes(config.visualizationType) &&
|
|
1543
|
+
renderLinearChartWithParentSize()}
|
|
1455
1544
|
|
|
1456
1545
|
{filteredData && filteredData.length > 0 && config.visualizationType === 'Pie' && (
|
|
1457
1546
|
<ParentSize className='justify-content-center d-flex' style={{ width: `100%` }}>
|
|
@@ -1478,38 +1567,31 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1478
1567
|
)}
|
|
1479
1568
|
</ParentSize>
|
|
1480
1569
|
)}
|
|
1570
|
+
{filteredData && filteredData.length > 0 && config.visualizationType === 'HeatMap' && (
|
|
1571
|
+
<div
|
|
1572
|
+
ref={parentRef}
|
|
1573
|
+
style={{ width: '100%', height: `${calcInitialHeight(config, currentViewport) || 400}px` }}
|
|
1574
|
+
>
|
|
1575
|
+
<ParentSize>
|
|
1576
|
+
{parent => <HeatMap parentWidth={parent.width} parentHeight={parent.height} />}
|
|
1577
|
+
</ParentSize>
|
|
1578
|
+
</div>
|
|
1579
|
+
)}
|
|
1481
1580
|
{/* Line Chart */}
|
|
1482
1581
|
{filteredData &&
|
|
1483
1582
|
filteredData.length > 0 &&
|
|
1484
1583
|
config.visualizationType === 'Line' &&
|
|
1485
|
-
(convertLineToBarGraph
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
{parent => {
|
|
1497
|
-
const labelMargin = 120
|
|
1498
|
-
const widthReduction =
|
|
1499
|
-
config.showLineSeriesLabels && (config.legend.position !== 'right' || config.legend.hide)
|
|
1500
|
-
? labelMargin
|
|
1501
|
-
: 0
|
|
1502
|
-
return (
|
|
1503
|
-
<LinearChart
|
|
1504
|
-
ref={svgRef}
|
|
1505
|
-
parentWidth={parent.width - widthReduction}
|
|
1506
|
-
parentHeight={parent.height}
|
|
1507
|
-
/>
|
|
1508
|
-
)
|
|
1509
|
-
}}
|
|
1510
|
-
</ParentSize>
|
|
1511
|
-
</div>
|
|
1512
|
-
))}
|
|
1584
|
+
(convertLineToBarGraph
|
|
1585
|
+
? renderLinearChartWithParentSize()
|
|
1586
|
+
: renderLinearChartWithParentSize(parent => {
|
|
1587
|
+
const labelMargin = 120
|
|
1588
|
+
const widthReduction =
|
|
1589
|
+
config.showLineSeriesLabels && (config.legend.position !== 'right' || config.legend.hide)
|
|
1590
|
+
? labelMargin
|
|
1591
|
+
: 0
|
|
1592
|
+
|
|
1593
|
+
return parent.width - widthReduction
|
|
1594
|
+
}))}
|
|
1513
1595
|
{/* Sparkline */}
|
|
1514
1596
|
{config.visualizationType === 'Spark Line' && (
|
|
1515
1597
|
<>
|
|
@@ -1521,7 +1603,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1521
1603
|
interactionLabel={interactionLabel}
|
|
1522
1604
|
/>
|
|
1523
1605
|
{processedIntroText && (
|
|
1524
|
-
<section className='introText' style={{ padding: '0px 0 35px' }}>
|
|
1606
|
+
<section className='introText cove-prose' style={{ padding: '0px 0 35px' }}>
|
|
1525
1607
|
{parse(processedIntroText)}
|
|
1526
1608
|
</section>
|
|
1527
1609
|
)}
|
|
@@ -1529,7 +1611,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1529
1611
|
<ParentSize>{parent => <SparkLine width={parent.width} height={parent.height} />}</ParentSize>
|
|
1530
1612
|
</div>
|
|
1531
1613
|
{processedDescription && (
|
|
1532
|
-
<div className='subtext' style={{ padding: '35px 0 1.5rem' }}>
|
|
1614
|
+
<div className='subtext cove-prose' style={{ padding: '35px 0 1.5rem' }}>
|
|
1533
1615
|
{parse(processedDescription)}
|
|
1534
1616
|
</div>
|
|
1535
1617
|
)}
|
|
@@ -1546,6 +1628,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1546
1628
|
{!config.legend.hide &&
|
|
1547
1629
|
config.visualizationType !== 'Spark Line' &&
|
|
1548
1630
|
config.visualizationType !== 'Sankey' &&
|
|
1631
|
+
config.visualizationType !== 'HeatMap' &&
|
|
1549
1632
|
!(config.visualizationType === 'Warming Stripes' && config.legend?.style === 'gradient') &&
|
|
1550
1633
|
!(config.visualizationType === 'Warming Stripes' && config.smallMultiples?.mode) && (
|
|
1551
1634
|
<Legend
|
|
@@ -1557,6 +1640,7 @@ const CdcChart: React.FC<CdcChartProps> = ({
|
|
|
1557
1640
|
{config.visualizationType === 'Warming Stripes' &&
|
|
1558
1641
|
config.legend?.style === 'gradient' &&
|
|
1559
1642
|
!config.smallMultiples?.mode && <WarmingStripesGradientLegend />}
|
|
1643
|
+
{config.visualizationType === 'HeatMap' && <HeatMapGradientLegend />}
|
|
1560
1644
|
</LegendWrapper>
|
|
1561
1645
|
</div>
|
|
1562
1646
|
</VisualizationContent>
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react-vite'
|
|
2
|
+
import { within, expect } from 'storybook/test'
|
|
3
|
+
import Chart from '../CdcChartComponent'
|
|
4
|
+
import {
|
|
5
|
+
assertVisualizationRendered,
|
|
6
|
+
waitForPresence,
|
|
7
|
+
waitForEditor,
|
|
8
|
+
openAccordion,
|
|
9
|
+
MIN_ANIMATION_DELAY_MS
|
|
10
|
+
} from '@cdc/core/helpers/testing'
|
|
11
|
+
import altTextConfig from './_mock/alt_text_metadata.json'
|
|
12
|
+
|
|
13
|
+
const meta: Meta<typeof Chart> = {
|
|
14
|
+
title: 'Components/Templates/Chart/Accessible Alt Text',
|
|
15
|
+
component: Chart,
|
|
16
|
+
parameters: {
|
|
17
|
+
docs: {
|
|
18
|
+
description: {
|
|
19
|
+
component:
|
|
20
|
+
'Demonstrates SVG accessibility: auto-generated aria-label with optional configurable description concatenated into the label for reliable screen reader support.'
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export default meta
|
|
27
|
+
type Story = StoryObj<typeof Chart>
|
|
28
|
+
|
|
29
|
+
export const MetadataDescription: Story = {
|
|
30
|
+
args: {
|
|
31
|
+
config: {
|
|
32
|
+
...altTextConfig,
|
|
33
|
+
altText: { type: 'metadata', metadataKey: 'altDescription' }
|
|
34
|
+
},
|
|
35
|
+
isEditor: false
|
|
36
|
+
},
|
|
37
|
+
parameters: {
|
|
38
|
+
docs: {
|
|
39
|
+
description: {
|
|
40
|
+
story:
|
|
41
|
+
'Description pulled from dataMetadata is concatenated into the aria-label after the auto-generated title for reliable screen reader support.'
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
play: async ({ canvasElement }) => {
|
|
46
|
+
await assertVisualizationRendered(canvasElement)
|
|
47
|
+
const svg = await waitForPresence('svg[role="img"]', canvasElement)
|
|
48
|
+
|
|
49
|
+
const expected = `Line chart with the title: COVID-19 Test Positivity. ${altTextConfig.dataMetadata.altDescription}`
|
|
50
|
+
expect(svg?.getAttribute('aria-label')).toBe(expected)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
export const StaticDescription: Story = {
|
|
55
|
+
args: {
|
|
56
|
+
config: {
|
|
57
|
+
...altTextConfig,
|
|
58
|
+
altText: {
|
|
59
|
+
type: 'static',
|
|
60
|
+
value: 'COVID-19 positivity has doubled in 8 weeks, suggesting increased community transmission.'
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
isEditor: false
|
|
64
|
+
},
|
|
65
|
+
parameters: {
|
|
66
|
+
docs: {
|
|
67
|
+
description: {
|
|
68
|
+
story: 'Static manually written description concatenated with the auto-generated title.'
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
play: async ({ canvasElement }) => {
|
|
73
|
+
await assertVisualizationRendered(canvasElement)
|
|
74
|
+
const svg = await waitForPresence('svg[role="img"]', canvasElement)
|
|
75
|
+
|
|
76
|
+
expect(svg?.getAttribute('aria-label')).toBe(
|
|
77
|
+
'Line chart with the title: COVID-19 Test Positivity. COVID-19 positivity has doubled in 8 weeks, suggesting increased community transmission.'
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export const AutoGenerated: Story = {
|
|
83
|
+
args: {
|
|
84
|
+
config: altTextConfig,
|
|
85
|
+
isEditor: false
|
|
86
|
+
},
|
|
87
|
+
parameters: {
|
|
88
|
+
docs: {
|
|
89
|
+
description: {
|
|
90
|
+
story:
|
|
91
|
+
'No altText configured. Falls back to the auto-generated aria-label: "Line chart with the title: COVID-19 Test Positivity".'
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
play: async ({ canvasElement }) => {
|
|
96
|
+
await assertVisualizationRendered(canvasElement)
|
|
97
|
+
const svg = await waitForPresence('svg[role="img"]', canvasElement)
|
|
98
|
+
|
|
99
|
+
expect(svg?.getAttribute('aria-label')).toBe('Line chart with the title: COVID-19 Test Positivity')
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export const EditorWithMetadata: Story = {
|
|
104
|
+
args: {
|
|
105
|
+
config: {
|
|
106
|
+
...altTextConfig,
|
|
107
|
+
altText: { type: 'metadata', metadataKey: 'altDescription' }
|
|
108
|
+
},
|
|
109
|
+
isEditor: true
|
|
110
|
+
},
|
|
111
|
+
parameters: {
|
|
112
|
+
docs: {
|
|
113
|
+
description: {
|
|
114
|
+
story:
|
|
115
|
+
'Editor mode showing the alt text description control in the General accordion with metadata-driven description.'
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
play: async ({ canvasElement }) => {
|
|
120
|
+
const canvas = within(canvasElement)
|
|
121
|
+
await waitForEditor(canvas)
|
|
122
|
+
|
|
123
|
+
if (MIN_ANIMATION_DELAY_MS > 0) {
|
|
124
|
+
await new Promise(resolve => setTimeout(resolve, MIN_ANIMATION_DELAY_MS))
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
await openAccordion(canvas, 'General')
|
|
128
|
+
|
|
129
|
+
if (MIN_ANIMATION_DELAY_MS > 0) {
|
|
130
|
+
await new Promise(resolve => setTimeout(resolve, MIN_ANIMATION_DELAY_MS))
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const descPreview = await waitForPresence('[data-testid="alt-text-desc-preview"]', canvasElement)
|
|
134
|
+
expect(descPreview?.textContent).toContain('COVID-19 test positivity')
|
|
135
|
+
}
|
|
136
|
+
}
|
package/src/_stories/{Chart.HTMLInDataTable.stories.tsx → Chart.HTMLInDataTable.smoke.stories.tsx}
RENAMED
|
@@ -493,6 +493,16 @@ export const PieChartWithHTMLFootnotes: Story = {
|
|
|
493
493
|
Footnote: '<strong>7 states</strong> with 60-79% coverage<br>Target: Move to <em>high category</em>'
|
|
494
494
|
}
|
|
495
495
|
],
|
|
496
|
+
xAxis: {
|
|
497
|
+
label: 'Coverage Category',
|
|
498
|
+
dataKey: 'Category',
|
|
499
|
+
type: 'categorical'
|
|
500
|
+
},
|
|
501
|
+
yAxis: {
|
|
502
|
+
label: 'Percentage',
|
|
503
|
+
dataKey: 'Percentage',
|
|
504
|
+
type: 'linear'
|
|
505
|
+
},
|
|
496
506
|
series: [
|
|
497
507
|
{
|
|
498
508
|
dataKey: 'Percentage',
|