@cdc/chart 4.23.10-alpha → 4.23.11
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/dist/cdcchart.js +30598 -28669
- package/examples/feature/bar/example-bar-chart.json +1 -46
- package/examples/feature/dev-4261.json +399 -0
- package/examples/feature/forest-plot/{broken.json → linear.json} +55 -50
- package/examples/{private/forest-plot.json → feature/forest-plot/logarithmic.json} +305 -355
- package/examples/feature/line/line-points.json +340 -0
- package/examples/feature/regions/index.json +462 -0
- package/examples/gallery/bar-chart-vertical/combo-line-chart.json +181 -48
- package/examples/sparkline-multilple.json +846 -0
- package/index.html +11 -8
- package/package.json +3 -3
- package/src/CdcChart.tsx +71 -60
- package/src/_stories/Chart.tooltip.stories.tsx +305 -0
- package/src/_stories/ChartBrush.stories.tsx +19 -0
- package/src/_stories/ChartSuppress.stories.tsx +19 -0
- package/{examples/private/missing-color.json → src/_stories/_mock/brush_mock.json} +392 -332
- package/src/_stories/_mock/suppress_mock.json +911 -0
- package/src/components/AreaChart.Stacked.jsx +4 -5
- package/src/components/AreaChart.jsx +6 -35
- package/src/components/{BarChart.Horizontal.jsx → BarChart.Horizontal.tsx} +106 -29
- package/src/components/{BarChart.StackedHorizontal.jsx → BarChart.StackedHorizontal.tsx} +22 -17
- package/src/components/{BarChart.StackedVertical.jsx → BarChart.StackedVertical.tsx} +22 -26
- package/src/components/{BarChart.Vertical.jsx → BarChart.Vertical.tsx} +175 -31
- package/src/components/BarChart.jsx +1 -1
- package/src/components/DeviationBar.jsx +4 -3
- package/src/components/EditorPanel.jsx +176 -50
- package/src/components/ForestPlot/ForestPlotProps.ts +11 -0
- package/src/components/ForestPlot/index.scss +1 -0
- package/src/components/{ForestPlot.jsx → ForestPlot/index.tsx} +51 -31
- package/src/components/ForestPlotSettings.jsx +162 -112
- package/src/components/Legend.jsx +35 -2
- package/src/components/{LineChart.Circle.tsx → LineChart/LineChart.Circle.tsx} +26 -23
- package/src/components/LineChart/LineChartProps.ts +17 -0
- package/src/components/LineChart/index.scss +1 -0
- package/src/components/{LineChart.tsx → LineChart/index.tsx} +60 -24
- package/src/components/LinearChart.jsx +120 -60
- package/src/components/PairedBarChart.jsx +2 -2
- package/src/components/Series.jsx +22 -3
- package/src/components/ZoomBrush.tsx +168 -0
- package/src/data/initial-state.js +27 -12
- package/src/hooks/useBarChart.js +70 -6
- package/src/hooks/useColorScale.ts +50 -0
- package/src/hooks/useEditorPermissions.js +22 -4
- package/src/hooks/{useMinMax.js → useMinMax.ts} +75 -23
- package/src/hooks/{useRightAxis.js → useRightAxis.ts} +10 -2
- package/src/hooks/{useScales.js → useScales.ts} +64 -17
- package/src/hooks/useTooltip.jsx +68 -41
- package/src/scss/main.scss +3 -35
- package/src/types/ChartConfig.ts +43 -0
- package/src/types/ChartContext.ts +38 -0
- package/src/types/ChartProps.ts +7 -0
- package/src/types/ForestPlot.ts +60 -0
- package/examples/private/full.json +0 -45324
- /package/{examples/private/TESTING.json → src/components/ForestPlot/Readme.md} +0 -0
package/index.html
CHANGED
|
@@ -34,19 +34,22 @@
|
|
|
34
34
|
-->
|
|
35
35
|
|
|
36
36
|
<!-- GENERIC CHART TYPES -->
|
|
37
|
-
<div class="react-container" data-config="/examples/private/
|
|
37
|
+
<div class="react-container" data-config="/examples/private/highlight.json"></div>
|
|
38
|
+
<div class="react-container" data-config="/examples/private/aggregate.json"></div>
|
|
39
|
+
<!-- <div class="react-container" data-config="/examples/private/missing-color.json"></div> -->
|
|
38
40
|
<!-- <div class="react-container" data-config="/examples/private/combo.json"></div> -->
|
|
39
41
|
<!-- <div class="react-container" data-config="/examples/feature/legend-highlights/highlights.json"></div> -->
|
|
40
42
|
<!-- <div class="react-container" data-config="/examples/private/tooltip-issue.json"></div> -->
|
|
41
43
|
<!-- <div class="react-container" data-config="https://cdc.gov/poxvirus/mpox/modules/data-viz/mpx-trends_1.json"></div> -->
|
|
42
44
|
<!-- <div class="react-container" data-config="/examples/feature/area/area-chart-date-city-temperature.json"></div> -->
|
|
43
45
|
<!-- <div class="react-container" data-config="/examples/feature/area/area-chart-date-apple.json"></div> -->
|
|
44
|
-
<!-- <div class="react-container" data-config="/examples/feature/
|
|
45
|
-
<!-- <div class="react-container" data-config="/examples/
|
|
46
|
+
<!-- <div class="react-container" data-config="/examples/feature/forest-plot/linear.json"></div> -->
|
|
47
|
+
<!-- <div class="react-container" data-config="/examples/feature/forest-plot/logarithmic.json"></div> -->
|
|
48
|
+
<!-- <div class="react-container" data-config="/examples/feature/forest-plot/forest-plot.json"></div> -->
|
|
46
49
|
<!-- <div class="react-container" data-config="/examples/feature/pie/planet-pie-example-config.json"></div> -->
|
|
47
50
|
<!-- <div class="react-container" data-config=https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Line_Chart_Viz.json></div> -->
|
|
51
|
+
<!-- <div class="react-container" data-config=/examples/feature/regions/index.json></div> -->
|
|
48
52
|
<!-- <div class="react-container" data-config=https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Line_Chart_Regions_Viz.json></div> -->
|
|
49
|
-
<!-- <div class="react-container" data-config="/examples/feature/line/line-chart.json"></div> -->
|
|
50
53
|
<!-- <div class="react-container" data-config="/examples/feature/forecasting/forecasting.json"></div> -->
|
|
51
54
|
<!-- <div class="react-container" data-config="/examples/feature/forecasting/combo-forecasting.json"></div> -->
|
|
52
55
|
<!-- <div class="react-container" data-config="/examples/feature/forecasting/effective_reproduction.json"></div> -->
|
|
@@ -69,7 +72,7 @@
|
|
|
69
72
|
<!-- <div class="react-container" data-config="/examples/feature/bar/planet-chart-horizontal-example-config.json"></div> -->
|
|
70
73
|
|
|
71
74
|
<!-- SPARKLINE -->
|
|
72
|
-
<!-- <div class="react-container" data-config="/examples/feature/
|
|
75
|
+
<!-- <div class="react-container" data-config="/examples/feature/dev-4261.json"></div> -->
|
|
73
76
|
|
|
74
77
|
<!-- TESTS DATA TABLE SORTING -->
|
|
75
78
|
<!-- Bar Chart with Confidence Intervals (bottom of page) -->
|
|
@@ -103,7 +106,7 @@
|
|
|
103
106
|
<!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/example-combo-bar-nonnumeric.json"></div> -->
|
|
104
107
|
<!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/example-bar-chart-nonnumeric.json"></div> -->
|
|
105
108
|
<!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/sparkline-chart-nonnumeric.json"></div> -->
|
|
106
|
-
<div class="react-container" data-config="/examples/feature/bar/lollipop.json"></div>
|
|
109
|
+
<!-- <div class="react-container" data-config="/examples/feature/bar/lollipop.json"></div> -->
|
|
107
110
|
<!-- <div class="react-container" data-config="/examples/feature/tests-non-numerics/stacked-vertical-bar-example-nonnumerics.json"></div> -->
|
|
108
111
|
|
|
109
112
|
<!-- TESTS CUTOFF -->
|
|
@@ -131,10 +134,10 @@
|
|
|
131
134
|
<!-- VERTICAL BAR CHARTS -->
|
|
132
135
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/combo-line-chart.json"></div> -->
|
|
133
136
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json"></div> -->
|
|
134
|
-
|
|
137
|
+
<div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json"></div>
|
|
135
138
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-confidence.json"></div> -->
|
|
136
139
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart.json"></div> -->
|
|
137
|
-
<div class="react-container" data-config="https://www.cdc.gov/respiratory-viruses/modules/respiratory-virus-activity/emergency-dept-visits_live.json"></div>
|
|
140
|
+
<!-- <div class="react-container" data-config="https://www.cdc.gov/respiratory-viruses/modules/respiratory-virus-activity/emergency-dept-visits_live.json"></div> -->
|
|
138
141
|
|
|
139
142
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
140
143
|
</body>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdc/chart",
|
|
3
|
-
"version": "4.23.
|
|
3
|
+
"version": "4.23.11",
|
|
4
4
|
"description": "React component for visualizing tabular data in various types of charts",
|
|
5
5
|
"moduleName": "CdcChart",
|
|
6
6
|
"main": "dist/cdcchart",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"js-base64": "^2.5.2",
|
|
49
49
|
"papaparse": "^5.3.0",
|
|
50
50
|
"react-accessible-accordion": "^3.3.4",
|
|
51
|
-
"react-icons": "^4.
|
|
51
|
+
"react-icons": "^4.11.0",
|
|
52
52
|
"react-spring": "^8.0.27",
|
|
53
53
|
"react-table": "^7.5.0",
|
|
54
54
|
"react-tooltip": "5.8.2-beta.3",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"react": "^18.2.0",
|
|
60
60
|
"react-dom": "^18.2.0"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "ecad213667a3cb96c921eaddba43a31c84caaa08",
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"resize-observer-polyfill": "^1.5.1"
|
|
65
65
|
}
|
package/src/CdcChart.tsx
CHANGED
|
@@ -43,6 +43,7 @@ import './scss/main.scss'
|
|
|
43
43
|
// load both then config below determines which to use
|
|
44
44
|
import DataTable from '@cdc/core/components/DataTable'
|
|
45
45
|
import { getFileExtension } from '@cdc/core/helpers/getFileExtension'
|
|
46
|
+
import Title from '@cdc/core/components/ui/Title'
|
|
46
47
|
|
|
47
48
|
const generateColorsArray = (color = '#000000', special = false) => {
|
|
48
49
|
let colorObj = chroma(color)
|
|
@@ -50,29 +51,6 @@ const generateColorsArray = (color = '#000000', special = false) => {
|
|
|
50
51
|
|
|
51
52
|
return [color, hoverColor, colorObj.darken(0.3).hex()]
|
|
52
53
|
}
|
|
53
|
-
const hashObj = row => {
|
|
54
|
-
try {
|
|
55
|
-
if (!row) throw new Error('No row supplied to hashObj')
|
|
56
|
-
|
|
57
|
-
let str = JSON.stringify(row)
|
|
58
|
-
let hash = 0
|
|
59
|
-
|
|
60
|
-
if (str.length === 0) return hash
|
|
61
|
-
|
|
62
|
-
for (let i = 0; i < str.length; i++) {
|
|
63
|
-
let char = str.charCodeAt(i)
|
|
64
|
-
hash = (hash << 5) - hash + char
|
|
65
|
-
hash = hash & hash
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return hash
|
|
69
|
-
} catch (e) {
|
|
70
|
-
console.error('COVE: ', e) // eslint-disable-line
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// * FILE REVIEW
|
|
75
|
-
// TODO: @tturnerswdev33 - remove/fix mentions of runtimeLegend that were added
|
|
76
54
|
|
|
77
55
|
export default function CdcChart({ configUrl, config: configObj, isEditor = false, isDebug = false, isDashboard = false, setConfig: setParentConfig, setEditing, hostname, link, setSharedFilter, setSharedFilterValue, dashboardConfig }) {
|
|
78
56
|
const transform = new DataTransform()
|
|
@@ -90,7 +68,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
90
68
|
const [coveLoadedEventRan, setCoveLoadedEventRan] = useState(false)
|
|
91
69
|
const [dynamicLegendItems, setDynamicLegendItems] = useState<any[]>([])
|
|
92
70
|
const [imageId] = useState(`cove-${Math.random().toString(16).slice(-4)}`)
|
|
93
|
-
|
|
71
|
+
type Config = typeof config
|
|
94
72
|
let legendMemo = useRef(new Map()) // map collection
|
|
95
73
|
let innerContainerRef = useRef()
|
|
96
74
|
|
|
@@ -310,8 +288,13 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
310
288
|
|
|
311
289
|
newConfig.series.map(series => {
|
|
312
290
|
if (!series.tooltip) series.tooltip = true
|
|
291
|
+
if (!series.axis) series.axis = 'Left'
|
|
313
292
|
})
|
|
314
293
|
|
|
294
|
+
if (!newConfig.data && data) {
|
|
295
|
+
newConfig.data = data
|
|
296
|
+
}
|
|
297
|
+
|
|
315
298
|
const processedConfig = { ...(await coveUpdateWorker(newConfig)) }
|
|
316
299
|
|
|
317
300
|
updateConfig(processedConfig, data)
|
|
@@ -563,6 +546,11 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
563
546
|
if ((newConfig.visualizationType === 'Bar' && newConfig.orientation === 'horizontal') || ['Deviation Bar', 'Paired Bar', 'Forest Plot'].includes(newConfig.visualizationType)) {
|
|
564
547
|
newConfig.runtime.xAxis = newConfig.yAxis
|
|
565
548
|
newConfig.runtime.yAxis = newConfig.xAxis
|
|
549
|
+
|
|
550
|
+
if (newConfig.visualizationType === 'Forest Plot') {
|
|
551
|
+
newConfig.runtime.xAxis.type = newConfig.forestPlot.type
|
|
552
|
+
newConfig.runtime.xAxis.tickRotation = newConfig.xAxis.tickRotation
|
|
553
|
+
}
|
|
566
554
|
newConfig.runtime.horizontal = true
|
|
567
555
|
newConfig.orientation = 'horizontal'
|
|
568
556
|
} else if (['Box Plot', 'Scatter Plot', 'Area Chart', 'Line', 'Forecasting'].includes(newConfig.visualizationType)) {
|
|
@@ -1128,18 +1116,6 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1128
1116
|
return generateColorsArray(mapColorPalette[3])
|
|
1129
1117
|
}
|
|
1130
1118
|
|
|
1131
|
-
let hash = hashObj(rowObj)
|
|
1132
|
-
|
|
1133
|
-
if (legendMemo.current.has(hash)) {
|
|
1134
|
-
let idx = legendMemo.current.get(hash)
|
|
1135
|
-
if (runtimeLegend[idx]?.disabled) return false
|
|
1136
|
-
|
|
1137
|
-
// DEV-784 changed to use bin prop to get color instead of idx
|
|
1138
|
-
// bc we re-order legend when showSpecialClassesLast is checked
|
|
1139
|
-
let legendBinColor = runtimeLegend.find(o => o.bin === idx)?.color
|
|
1140
|
-
return generateColorsArray(legendBinColor, runtimeLegend[idx]?.special)
|
|
1141
|
-
}
|
|
1142
|
-
|
|
1143
1119
|
// Fail state
|
|
1144
1120
|
return generateColorsArray()
|
|
1145
1121
|
} catch (e) {
|
|
@@ -1160,6 +1136,61 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1160
1136
|
return key
|
|
1161
1137
|
}
|
|
1162
1138
|
|
|
1139
|
+
const computeMarginBottom = (config: Config): string => {
|
|
1140
|
+
const isLegendBottom = legend.position === 'bottom' || ['sm', 'xs', 'xxs'].includes(currentViewport)
|
|
1141
|
+
const isHorizontal = config.orientation === 'horizontal'
|
|
1142
|
+
const tickRotation = Number(config.xAxis.tickRotation) > 0 ? Number(config.xAxis.tickRotation) : 0
|
|
1143
|
+
const isBrush = config.brush.active
|
|
1144
|
+
const offset = 20
|
|
1145
|
+
const brushHeight = config.brush.height
|
|
1146
|
+
let bottom = 0
|
|
1147
|
+
if (!isLegendBottom && isHorizontal && !config.yAxis.label) {
|
|
1148
|
+
bottom = Number(config.xAxis.labelOffset)
|
|
1149
|
+
}
|
|
1150
|
+
if (!isLegendBottom && isHorizontal && config.yAxis.label && !config.isResponsiveTicks) {
|
|
1151
|
+
bottom = Number(config.runtime.xAxis.size) + Number(config.xAxis.labelOffset)
|
|
1152
|
+
}
|
|
1153
|
+
if (!isLegendBottom && isHorizontal && config.yAxis.label && config.isResponsiveTicks) {
|
|
1154
|
+
bottom = config.dynamicMarginTop + offset
|
|
1155
|
+
}
|
|
1156
|
+
if (!isLegendBottom && isHorizontal && !config.yAxis.label && config.isResponsiveTicks) {
|
|
1157
|
+
bottom = config.dynamicMarginTop ? config.dynamicMarginTop - offset : Number(config.xAxis.labelOffset) - offset
|
|
1158
|
+
}
|
|
1159
|
+
if (!isLegendBottom && isHorizontal && config.yAxis.label && config.isResponsiveTicks) {
|
|
1160
|
+
bottom = config.dynamicMarginTop ? config.dynamicMarginTop + offset : Number(config.xAxis.labelOffset)
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
if (!isHorizontal && !isLegendBottom && config.xAxis.label && tickRotation && !config.isResponsiveTicks) {
|
|
1164
|
+
bottom = isBrush ? brushHeight + config.xAxis.tickWidthMax + -config.xAxis.size + config.xAxis.labelOffset + offset : config.xAxis.tickWidthMax + offset + -config.xAxis.size + config.xAxis.labelOffset
|
|
1165
|
+
}
|
|
1166
|
+
if (!isHorizontal && !isLegendBottom && !config.xAxis.label && tickRotation && !config.isResponsiveTicks) {
|
|
1167
|
+
}
|
|
1168
|
+
if (!isHorizontal && !isLegendBottom && !config.xAxis.label && tickRotation && !config.dynamicMarginTop && !config.isResponsiveTicks) {
|
|
1169
|
+
bottom = isBrush ? config.xAxis.tickWidthMax + brushHeight + offset + -config.xAxis.size : 0
|
|
1170
|
+
}
|
|
1171
|
+
|
|
1172
|
+
if (!isHorizontal && !isLegendBottom && config.xAxis.label && !tickRotation && !config.isResponsiveTicks) {
|
|
1173
|
+
bottom = isBrush ? brushHeight + -config.xAxis.size + config.xAxis.labelOffset + offset : -config.xAxis.size + config.xAxis.labelOffset + offset
|
|
1174
|
+
}
|
|
1175
|
+
if (!isHorizontal && !isLegendBottom && config.xAxis.label && config.dynamicMarginTop && config.isResponsiveTicks) {
|
|
1176
|
+
bottom = isBrush ? brushHeight + config.xAxis.labelOffset + -config.xAxis.size + config.xAxis.tickWidthMax : config.dynamicMarginTop + -config.xAxis.size + offset
|
|
1177
|
+
}
|
|
1178
|
+
if (!isHorizontal && !isLegendBottom && !config.xAxis.label && config.dynamicMarginTop && config.isResponsiveTicks) {
|
|
1179
|
+
bottom = isBrush ? brushHeight + config.xAxis.labelOffset + -config.xAxis.size + config.xAxis.tickWidthMax : config.dynamicMarginTop + -config.xAxis.size - offset
|
|
1180
|
+
}
|
|
1181
|
+
if (!isHorizontal && !isLegendBottom && config.xAxis.label && !config.dynamicMarginTop && config.isResponsiveTicks) {
|
|
1182
|
+
bottom = isBrush ? brushHeight + config.xAxis.labelOffset + -config.xAxis.size + 25 : config.xAxis.labelOffset + -config.xAxis.size + offset
|
|
1183
|
+
}
|
|
1184
|
+
if (!isHorizontal && !isLegendBottom && !config.xAxis.label && !config.dynamicMarginTop && config.isResponsiveTicks) {
|
|
1185
|
+
bottom = -config.xAxis.size + offset + config.xAxis.labelOffset
|
|
1186
|
+
}
|
|
1187
|
+
if (!isHorizontal && !isLegendBottom && !config.xAxis.label && !tickRotation && !config.dynamicMarginTop && !config.isResponsiveTicks) {
|
|
1188
|
+
bottom = isBrush ? brushHeight + -config.xAxis.size + config.xAxis.labelOffset : 0
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
return `${bottom}px`
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1163
1194
|
// Prevent render if loading
|
|
1164
1195
|
let body = <Loading />
|
|
1165
1196
|
|
|
@@ -1174,13 +1205,8 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1174
1205
|
{isEditor && <EditorPanel />}
|
|
1175
1206
|
{!missingRequiredSections() && !config.newViz && (
|
|
1176
1207
|
<div className='cdc-chart-inner-container'>
|
|
1177
|
-
{
|
|
1178
|
-
|
|
1179
|
-
<div role='heading' className={`chart-title ${config.theme} cove-component__header`} aria-level={2}>
|
|
1180
|
-
{config && <sup className='superTitle'>{parse(config.superTitle || '')}</sup>}
|
|
1181
|
-
<div>{parse(title)}</div>
|
|
1182
|
-
</div>
|
|
1183
|
-
)}
|
|
1208
|
+
<Title showTitle={config.showTitle} isDashboard={isDashboard} title={title} superTitle={config.superTitle} classes={['chart-title', `${config.theme}`, 'cove-component__header']} style={undefined} />
|
|
1209
|
+
|
|
1184
1210
|
<a id='skip-chart-container' className='cdcdataviz-sr-only-focusable' href={handleChartTabbing}>
|
|
1185
1211
|
Skip Over Chart Container
|
|
1186
1212
|
</a>
|
|
@@ -1188,10 +1214,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1188
1214
|
{config.filters && !externalFilters && <Filters config={config} setConfig={setConfig} setFilteredData={setFilteredData} filteredData={filteredData} excludedData={excludedData} filterData={filterData} dimensions={dimensions} />}
|
|
1189
1215
|
{/* Visualization */}
|
|
1190
1216
|
{config?.introText && config.visualizationType !== 'Spark Line' && <section className='introText'>{parse(config.introText)}</section>}
|
|
1191
|
-
<div
|
|
1192
|
-
style={{ marginBottom: config.legend.position !== 'bottom' && config.orientation === 'horizontal' ? `${config.runtime.xAxis.size}px` : '0px' }}
|
|
1193
|
-
className={`chart-container p-relative ${config.legend.position === 'bottom' ? 'bottom' : ''}${config.legend.hide ? ' legend-hidden' : ''}${lineDatapointClass}${barBorderClass} ${contentClasses.join(' ')}`}
|
|
1194
|
-
>
|
|
1217
|
+
<div style={{ marginBottom: computeMarginBottom(config) }} className={`chart-container p-relative ${config.legend.position === 'bottom' ? 'bottom' : ''}${config.legend.hide ? ' legend-hidden' : ''}${lineDatapointClass}${barBorderClass} ${contentClasses.join(' ')}`}>
|
|
1195
1218
|
{/* All charts except sparkline */}
|
|
1196
1219
|
{config.visualizationType !== 'Spark Line' && chartComponents[config.visualizationType]}
|
|
1197
1220
|
|
|
@@ -1232,11 +1255,9 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1232
1255
|
<DataTable
|
|
1233
1256
|
config={config}
|
|
1234
1257
|
rawData={config.data}
|
|
1235
|
-
runtimeData={filteredData || excludedData}
|
|
1258
|
+
runtimeData={transform.applySuppression(filteredData || excludedData, config.suppressedData)}
|
|
1236
1259
|
expandDataTable={config.table.expanded}
|
|
1237
1260
|
columns={config.columns}
|
|
1238
|
-
showDownloadButton={config.general.showDownloadButton}
|
|
1239
|
-
runtimeLegend={dynamicLegendItems}
|
|
1240
1261
|
displayDataAsText={displayDataAsText}
|
|
1241
1262
|
displayGeoName={displayGeoName}
|
|
1242
1263
|
applyLegendToRow={applyLegendToRow}
|
|
@@ -1244,18 +1265,8 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1244
1265
|
indexTitle={config.table.indexLabel}
|
|
1245
1266
|
vizTitle={title}
|
|
1246
1267
|
viewport={currentViewport}
|
|
1247
|
-
parseDate={parseDate}
|
|
1248
|
-
formatDate={formatDate}
|
|
1249
|
-
formatNumber={formatNumber}
|
|
1250
1268
|
tabbingId={handleChartTabbing}
|
|
1251
|
-
showDownloadImgButton={config.showDownloadImgButton}
|
|
1252
|
-
showDownloadPdfButton={config.showDownloadPdfButton}
|
|
1253
|
-
innerContainerRef={innerContainerRef}
|
|
1254
|
-
outerContainerRef={outerContainerRef}
|
|
1255
|
-
imageRef={imageId}
|
|
1256
1269
|
colorScale={colorScale}
|
|
1257
|
-
isDebug={isDebug}
|
|
1258
|
-
isEditor={isEditor}
|
|
1259
1270
|
/>
|
|
1260
1271
|
)}
|
|
1261
1272
|
{config?.footnotes && <section className='footnotes'>{parse(config.footnotes)}</section>}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
|
|
3
|
+
import Chart from '../CdcChart'
|
|
4
|
+
|
|
5
|
+
const meta: Meta<typeof Chart> = {
|
|
6
|
+
title: 'Components/Templates/Chart/Tooltip',
|
|
7
|
+
component: Chart
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
type Story = StoryObj<typeof Chart>
|
|
11
|
+
|
|
12
|
+
export const Additional_Tooltip: Story = {
|
|
13
|
+
args: {
|
|
14
|
+
config: {
|
|
15
|
+
type: 'chart',
|
|
16
|
+
debugSvg: false,
|
|
17
|
+
chartMessage: {
|
|
18
|
+
noData: 'No Data Available'
|
|
19
|
+
},
|
|
20
|
+
title: 'Example Stacked Bar Chart with Additional tolltip column',
|
|
21
|
+
showTitle: true,
|
|
22
|
+
showDownloadMediaButton: false,
|
|
23
|
+
theme: 'theme-orange',
|
|
24
|
+
animate: false,
|
|
25
|
+
fontSize: 'medium',
|
|
26
|
+
lineDatapointStyle: 'hover',
|
|
27
|
+
barHasBorder: 'false',
|
|
28
|
+
isLollipopChart: false,
|
|
29
|
+
lollipopShape: 'circle',
|
|
30
|
+
lollipopColorStyle: 'two-tone',
|
|
31
|
+
visualizationSubType: 'stacked',
|
|
32
|
+
barStyle: '',
|
|
33
|
+
roundingStyle: 'standard',
|
|
34
|
+
tipRounding: 'top',
|
|
35
|
+
isResponsiveTicks: false,
|
|
36
|
+
general: {
|
|
37
|
+
showDownloadButton: false
|
|
38
|
+
},
|
|
39
|
+
padding: {
|
|
40
|
+
left: 5,
|
|
41
|
+
right: 5
|
|
42
|
+
},
|
|
43
|
+
yAxis: {
|
|
44
|
+
hideAxis: false,
|
|
45
|
+
displayNumbersOnBar: false,
|
|
46
|
+
hideLabel: false,
|
|
47
|
+
hideTicks: false,
|
|
48
|
+
size: '64',
|
|
49
|
+
gridLines: false,
|
|
50
|
+
enablePadding: false,
|
|
51
|
+
min: '',
|
|
52
|
+
max: '',
|
|
53
|
+
labelColor: '#333',
|
|
54
|
+
tickLabelColor: '#333',
|
|
55
|
+
tickColor: '#333',
|
|
56
|
+
rightHideAxis: true,
|
|
57
|
+
rightAxisSize: 0,
|
|
58
|
+
rightLabel: '',
|
|
59
|
+
rightLabelOffsetSize: 0,
|
|
60
|
+
rightAxisLabelColor: '#333',
|
|
61
|
+
rightAxisTickLabelColor: '#333',
|
|
62
|
+
rightAxisTickColor: '#333',
|
|
63
|
+
numTicks: '',
|
|
64
|
+
axisPadding: 0,
|
|
65
|
+
tickRotation: 0,
|
|
66
|
+
anchors: [],
|
|
67
|
+
label: 'Y-Axis Label Example'
|
|
68
|
+
},
|
|
69
|
+
boxplot: {
|
|
70
|
+
plots: [],
|
|
71
|
+
borders: 'true',
|
|
72
|
+
firstQuartilePercentage: 25,
|
|
73
|
+
thirdQuartilePercentage: 75,
|
|
74
|
+
boxWidthPercentage: 40,
|
|
75
|
+
plotOutlierValues: false,
|
|
76
|
+
plotNonOutlierValues: true,
|
|
77
|
+
legend: {
|
|
78
|
+
showHowToReadText: false,
|
|
79
|
+
howToReadText: ''
|
|
80
|
+
},
|
|
81
|
+
labels: {
|
|
82
|
+
q1: 'Lower Quartile',
|
|
83
|
+
q2: 'q2',
|
|
84
|
+
q3: 'Upper Quartile',
|
|
85
|
+
q4: 'q4',
|
|
86
|
+
minimum: 'Minimum',
|
|
87
|
+
maximum: 'Maximum',
|
|
88
|
+
mean: 'Mean',
|
|
89
|
+
median: 'Median',
|
|
90
|
+
sd: 'Standard Deviation',
|
|
91
|
+
iqr: 'Interquartile Range',
|
|
92
|
+
total: 'Total',
|
|
93
|
+
outliers: 'Outliers',
|
|
94
|
+
values: 'Values',
|
|
95
|
+
lowerBounds: 'Lower Bounds',
|
|
96
|
+
upperBounds: 'Upper Bounds'
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
topAxis: {
|
|
100
|
+
hasLine: false
|
|
101
|
+
},
|
|
102
|
+
isLegendValue: false,
|
|
103
|
+
barThickness: 0.35,
|
|
104
|
+
barHeight: 25,
|
|
105
|
+
barSpace: 15,
|
|
106
|
+
heights: {
|
|
107
|
+
vertical: 300,
|
|
108
|
+
horizontal: 750
|
|
109
|
+
},
|
|
110
|
+
xAxis: {
|
|
111
|
+
sortDates: false,
|
|
112
|
+
anchors: [],
|
|
113
|
+
type: 'categorical',
|
|
114
|
+
showTargetLabel: true,
|
|
115
|
+
targetLabel: 'Target',
|
|
116
|
+
hideAxis: false,
|
|
117
|
+
hideLabel: false,
|
|
118
|
+
hideTicks: false,
|
|
119
|
+
size: '67',
|
|
120
|
+
tickRotation: '25',
|
|
121
|
+
min: '',
|
|
122
|
+
max: '',
|
|
123
|
+
labelColor: '#333',
|
|
124
|
+
tickLabelColor: '#333',
|
|
125
|
+
tickColor: '#333',
|
|
126
|
+
numTicks: '',
|
|
127
|
+
labelOffset: 65,
|
|
128
|
+
axisPadding: 0,
|
|
129
|
+
target: 0,
|
|
130
|
+
maxTickRotation: 0,
|
|
131
|
+
dataKey: 'Year',
|
|
132
|
+
label: 'X-Axis Label Example',
|
|
133
|
+
tickWidthMax: 41
|
|
134
|
+
},
|
|
135
|
+
table: {
|
|
136
|
+
label: 'Data Table',
|
|
137
|
+
expanded: true,
|
|
138
|
+
limitHeight: false,
|
|
139
|
+
height: '',
|
|
140
|
+
caption: '',
|
|
141
|
+
showDownloadUrl: false,
|
|
142
|
+
showDataTableLink: true,
|
|
143
|
+
indexLabel: '',
|
|
144
|
+
download: true,
|
|
145
|
+
showVertical: false,
|
|
146
|
+
show: true
|
|
147
|
+
},
|
|
148
|
+
orientation: 'vertical',
|
|
149
|
+
color: 'pinkpurple',
|
|
150
|
+
columns: {
|
|
151
|
+
additionalColumn1: {
|
|
152
|
+
label: 'New Column',
|
|
153
|
+
dataTable: false,
|
|
154
|
+
tooltips: true,
|
|
155
|
+
prefix: '',
|
|
156
|
+
suffix: '',
|
|
157
|
+
forestPlot: false,
|
|
158
|
+
startingPoint: '0',
|
|
159
|
+
forestPlotAlignRight: false,
|
|
160
|
+
name: 'Data 1'
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
legend: {
|
|
164
|
+
hide: false,
|
|
165
|
+
behavior: 'isolate',
|
|
166
|
+
singleRow: false,
|
|
167
|
+
colorCode: '',
|
|
168
|
+
reverseLabelOrder: false,
|
|
169
|
+
description: '',
|
|
170
|
+
dynamicLegend: false,
|
|
171
|
+
dynamicLegendDefaultText: 'Show All',
|
|
172
|
+
dynamicLegendItemLimit: 5,
|
|
173
|
+
dynamicLegendItemLimitMessage: 'Dynamic Legend Item Limit Hit.',
|
|
174
|
+
dynamicLegendChartMessage: 'Select Options from the Legend',
|
|
175
|
+
lineMode: false,
|
|
176
|
+
verticalSorted: false,
|
|
177
|
+
position: 'right',
|
|
178
|
+
label: 'Data Type'
|
|
179
|
+
},
|
|
180
|
+
brush: {
|
|
181
|
+
height: 25,
|
|
182
|
+
data: [],
|
|
183
|
+
active: false
|
|
184
|
+
},
|
|
185
|
+
exclusions: {
|
|
186
|
+
active: false,
|
|
187
|
+
keys: []
|
|
188
|
+
},
|
|
189
|
+
palette: 'qualitative-bold',
|
|
190
|
+
isPaletteReversed: false,
|
|
191
|
+
twoColor: {
|
|
192
|
+
palette: 'monochrome-1',
|
|
193
|
+
isPaletteReversed: false
|
|
194
|
+
},
|
|
195
|
+
labels: false,
|
|
196
|
+
dataFormat: {
|
|
197
|
+
commas: false,
|
|
198
|
+
prefix: '',
|
|
199
|
+
suffix: '%',
|
|
200
|
+
abbreviated: false,
|
|
201
|
+
bottomSuffix: '',
|
|
202
|
+
bottomPrefix: '',
|
|
203
|
+
bottomAbbreviated: false
|
|
204
|
+
},
|
|
205
|
+
confidenceKeys: {},
|
|
206
|
+
visual: {
|
|
207
|
+
border: true,
|
|
208
|
+
accent: true,
|
|
209
|
+
background: true,
|
|
210
|
+
verticalHoverLine: false,
|
|
211
|
+
horizontalHoverLine: false
|
|
212
|
+
},
|
|
213
|
+
useLogScale: false,
|
|
214
|
+
filterBehavior: 'Filter Change',
|
|
215
|
+
highlightedBarValues: [],
|
|
216
|
+
series: [
|
|
217
|
+
{
|
|
218
|
+
dataKey: 'Data 2',
|
|
219
|
+
type: 'Bar',
|
|
220
|
+
tooltip: true
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
dataKey: 'Data 3',
|
|
224
|
+
type: 'Bar',
|
|
225
|
+
tooltip: true
|
|
226
|
+
}
|
|
227
|
+
],
|
|
228
|
+
tooltips: {
|
|
229
|
+
opacity: 90
|
|
230
|
+
},
|
|
231
|
+
forestPlot: {
|
|
232
|
+
startAt: 0,
|
|
233
|
+
width: 'auto',
|
|
234
|
+
colors: {
|
|
235
|
+
line: '',
|
|
236
|
+
shape: ''
|
|
237
|
+
},
|
|
238
|
+
estimateField: '',
|
|
239
|
+
estimateRadius: '',
|
|
240
|
+
lowerCiField: '',
|
|
241
|
+
upperCiField: '',
|
|
242
|
+
shape: '',
|
|
243
|
+
rowHeight: 20,
|
|
244
|
+
showZeroLine: false,
|
|
245
|
+
description: {
|
|
246
|
+
show: true,
|
|
247
|
+
text: 'description',
|
|
248
|
+
location: 0
|
|
249
|
+
},
|
|
250
|
+
result: {
|
|
251
|
+
show: true,
|
|
252
|
+
text: 'result',
|
|
253
|
+
location: 100
|
|
254
|
+
},
|
|
255
|
+
radius: {
|
|
256
|
+
min: 1,
|
|
257
|
+
max: 8,
|
|
258
|
+
scalingColumn: ''
|
|
259
|
+
},
|
|
260
|
+
regression: {
|
|
261
|
+
lower: 0,
|
|
262
|
+
upper: 0,
|
|
263
|
+
estimateField: 0
|
|
264
|
+
},
|
|
265
|
+
leftWidthOffset: 0,
|
|
266
|
+
rightWidthOffset: 0
|
|
267
|
+
},
|
|
268
|
+
area: {
|
|
269
|
+
isStacked: false
|
|
270
|
+
},
|
|
271
|
+
height: '375',
|
|
272
|
+
data: [
|
|
273
|
+
{
|
|
274
|
+
Year: '2015',
|
|
275
|
+
'Data 1': '25',
|
|
276
|
+
'Data 2': '20',
|
|
277
|
+
'Data 3': '55'
|
|
278
|
+
},
|
|
279
|
+
{
|
|
280
|
+
Year: '2016',
|
|
281
|
+
'Data 1': '35',
|
|
282
|
+
'Data 2': '30',
|
|
283
|
+
'Data 3': '35'
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
Year: '2017',
|
|
287
|
+
'Data 1': '22',
|
|
288
|
+
'Data 2': '38',
|
|
289
|
+
'Data 3': '40'
|
|
290
|
+
},
|
|
291
|
+
{
|
|
292
|
+
Year: '2018',
|
|
293
|
+
'Data 1': '40',
|
|
294
|
+
'Data 2': '40',
|
|
295
|
+
'Data 3': '20'
|
|
296
|
+
}
|
|
297
|
+
],
|
|
298
|
+
visualizationType: 'Bar',
|
|
299
|
+
validated: 4.23,
|
|
300
|
+
dynamicMarginTop: 0
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
export default meta
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import chartBrushConfig from './_mock/brush_mock.json'
|
|
3
|
+
|
|
4
|
+
import Chart from '../CdcChart'
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof Chart> = {
|
|
7
|
+
title: 'Components/Templates/Chart/Brush',
|
|
8
|
+
component: Chart
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type Story = StoryObj<typeof Chart>
|
|
12
|
+
|
|
13
|
+
export const Area_Brush: Story = {
|
|
14
|
+
args: {
|
|
15
|
+
config: chartBrushConfig
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default meta
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import suppressMock from './_mock/suppress_mock.json'
|
|
3
|
+
|
|
4
|
+
import Chart from '../CdcChart'
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof Chart> = {
|
|
7
|
+
title: 'Components/Templates/Chart/Suppress',
|
|
8
|
+
component: Chart
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type Story = StoryObj<typeof Chart>
|
|
12
|
+
|
|
13
|
+
export const Horizontal_Chart: Story = {
|
|
14
|
+
args: {
|
|
15
|
+
config: suppressMock
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default meta
|