@cdc/chart 4.23.11 → 4.24.1
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 +30220 -29764
- package/examples/feature/bar/additional-column-tooltip.json +446 -0
- package/examples/feature/bar/tall-data.json +98 -0
- package/examples/feature/forest-plot/forest-plot.json +63 -19
- package/examples/feature/forest-plot/linear.json +52 -3
- package/examples/feature/forest-plot/log.json +26 -0
- package/examples/feature/forest-plot/logarithmic.json +0 -35
- package/examples/feature/line/line-chart-preliminary.json +346 -0
- package/examples/feature/scatterplot/scatterplot.json +272 -33
- package/examples/private/chart-t.json +3740 -0
- package/examples/private/combo.json +369 -0
- package/examples/private/epi-data.csv +13 -0
- package/examples/private/epi-data.json +62 -0
- package/examples/private/epi.json +403 -0
- package/examples/private/occupancy.json +109283 -0
- package/examples/private/prod-line-config.json +401 -0
- package/examples/private/region-data.json +822 -0
- package/examples/private/region-testing.json +312 -0
- package/examples/private/scaling.json +45325 -0
- package/examples/private/testing-data.json +1739 -0
- package/examples/private/testing.json +816 -0
- package/index.html +7 -7
- package/package.json +2 -2
- package/src/CdcChart.tsx +29 -210
- package/src/ConfigContext.tsx +6 -0
- package/src/_stories/ChartEditor.stories.tsx +22 -0
- package/src/_stories/ChartLine.preliminary.tsx +19 -0
- package/src/_stories/_mock/pie_config.json +191 -0
- package/src/_stories/_mock/pie_data.json +218 -0
- package/src/_stories/_mock/preliminary_mock.json +346 -0
- package/src/components/{AreaChart.Stacked.jsx → AreaChart/components/AreaChart.Stacked.jsx} +2 -2
- package/src/components/{AreaChart.jsx → AreaChart/components/AreaChart.jsx} +1 -1
- package/src/components/AreaChart/index.tsx +4 -0
- package/src/components/{BarChart.Horizontal.tsx → BarChart/components/BarChart.Horizontal.tsx} +8 -8
- package/src/components/{BarChart.StackedHorizontal.tsx → BarChart/components/BarChart.StackedHorizontal.tsx} +37 -7
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +106 -0
- package/src/components/{BarChart.Vertical.tsx → BarChart/components/BarChart.Vertical.tsx} +41 -57
- package/src/components/BarChart/components/BarChart.jsx +39 -0
- package/src/components/{BarChartType.jsx → BarChart/components/BarChartType.jsx} +0 -2
- package/src/components/BarChart/components/context.tsx +13 -0
- package/src/components/BarChart/index.tsx +3 -0
- package/src/components/{BoxPlot.jsx → BoxPlot/BoxPlot.jsx} +1 -1
- package/src/components/BoxPlot/index.tsx +3 -0
- package/src/components/{EditorPanel.jsx → EditorPanel/EditorPanel.tsx} +667 -851
- package/src/components/EditorPanel/components/Panel.DateHighlighting.tsx +109 -0
- package/src/components/{ForestPlotSettings.jsx → EditorPanel/components/Panel.ForestPlotSettings.tsx} +87 -166
- package/src/components/EditorPanel/components/Panel.Regions.tsx +168 -0
- package/src/components/{Series.jsx → EditorPanel/components/Panel.Series.tsx} +1 -1
- package/src/components/EditorPanel/components/PanelProps.ts +3 -0
- package/src/components/EditorPanel/components/Panels.tsx +13 -0
- package/src/components/EditorPanel/components/panels.scss +72 -0
- package/src/components/EditorPanel/editor-panel.scss +751 -0
- package/src/components/EditorPanel/index.tsx +3 -0
- package/src/{hooks → components/EditorPanel}/useEditorPermissions.js +29 -2
- package/src/components/{Forecasting.jsx → Forecasting/Forecasting.jsx} +1 -1
- package/src/components/Forecasting/index.tsx +3 -0
- package/src/components/ForestPlot/ForestPlot.tsx +254 -0
- package/src/components/ForestPlot/ForestPlotProps.ts +7 -0
- package/src/components/ForestPlot/index.tsx +1 -209
- package/src/components/{Legend.jsx → Legend/Legend.tsx} +150 -113
- package/src/components/Legend/index.tsx +3 -0
- package/src/components/LineChart/LineChartProps.ts +29 -0
- package/src/components/LineChart/{LineChart.Circle.tsx → components/LineChart.Circle.tsx} +12 -3
- package/src/components/LineChart/helpers.ts +45 -0
- package/src/components/LineChart/index.tsx +20 -8
- package/src/components/LinearChart.jsx +52 -69
- package/src/components/{PieChart.jsx → PieChart/PieChart.tsx} +16 -7
- package/src/components/PieChart/index.tsx +3 -0
- package/src/components/Regions/components/Regions.tsx +135 -0
- package/src/components/Regions/index.tsx +3 -0
- package/src/components/{ScatterPlot.jsx → ScatterPlot/ScatterPlot.jsx} +3 -3
- package/src/components/ScatterPlot/index.tsx +3 -0
- package/src/components/{SparkLine.jsx → Sparkline/SparkLine.jsx} +2 -2
- package/src/components/Sparkline/index.tsx +3 -0
- package/src/data/initial-state.js +5 -6
- package/src/helpers/abbreviateNumber.ts +17 -0
- package/src/helpers/computeMarginBottom.ts +55 -0
- package/src/helpers/filterData.ts +18 -0
- package/src/helpers/generateColorsArray.ts +8 -0
- package/src/helpers/getQuartiles.ts +30 -0
- package/src/helpers/handleChartAriaLabels.ts +19 -0
- package/src/helpers/handleLineType.ts +18 -0
- package/src/helpers/lineOptions.ts +18 -0
- package/src/helpers/sort.ts +7 -0
- package/src/helpers/tests/computeMarginBottom.test.ts +20 -0
- package/src/hooks/useBarChart.js +7 -6
- package/src/hooks/useScales.ts +1 -1
- package/src/hooks/{useTooltip.jsx → useTooltip.tsx} +23 -21
- package/src/scss/main.scss +67 -3
- package/src/types/ChartConfig.ts +158 -23
- package/src/types/ChartContext.ts +26 -10
- package/src/types/ForestPlot.ts +7 -14
- package/examples/feature/scatterplot/scatterplot-continuous.csv +0 -17
- package/src/ConfigContext.jsx +0 -5
- package/src/components/BarChart.StackedVertical.tsx +0 -91
- package/src/components/BarChart.jsx +0 -30
- package/src/components/ForestPlot/Readme.md +0 -0
- package/src/scss/LinearChart.scss +0 -0
- package/src/scss/editor-panel.scss +0 -745
- package/src/scss/legend.scss +0 -206
- package/src/scss/mixins.scss +0 -0
- package/src/scss/variables.scss +0 -1
- package/src/types/ChartProps.ts +0 -7
package/index.html
CHANGED
|
@@ -34,12 +34,9 @@
|
|
|
34
34
|
-->
|
|
35
35
|
|
|
36
36
|
<!-- GENERIC CHART TYPES -->
|
|
37
|
-
<div class="react-container" data-config="/examples/private/
|
|
38
|
-
<div class="react-container" data-config="/examples/private/
|
|
39
|
-
<!-- <div class="react-container" data-config="/examples/
|
|
40
|
-
<!-- <div class="react-container" data-config="/examples/private/combo.json"></div> -->
|
|
41
|
-
<!-- <div class="react-container" data-config="/examples/feature/legend-highlights/highlights.json"></div> -->
|
|
42
|
-
<!-- <div class="react-container" data-config="/examples/private/tooltip-issue.json"></div> -->
|
|
37
|
+
<!-- <div class="react-container" data-config="/examples/private/prod-line-config.json"></div> -->
|
|
38
|
+
<!-- <div class="react-container" data-config="/examples/private/chart-t.json"></div> -->
|
|
39
|
+
<!-- <div class="react-container" data-config="/examples/feature/bar/additional-column-tooltip.json"></div> -->
|
|
43
40
|
<!-- <div class="react-container" data-config="https://cdc.gov/poxvirus/mpox/modules/data-viz/mpx-trends_1.json"></div> -->
|
|
44
41
|
<!-- <div class="react-container" data-config="/examples/feature/area/area-chart-date-city-temperature.json"></div> -->
|
|
45
42
|
<!-- <div class="react-container" data-config="/examples/feature/area/area-chart-date-apple.json"></div> -->
|
|
@@ -50,6 +47,7 @@
|
|
|
50
47
|
<!-- <div class="react-container" data-config=https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Line_Chart_Viz.json></div> -->
|
|
51
48
|
<!-- <div class="react-container" data-config=/examples/feature/regions/index.json></div> -->
|
|
52
49
|
<!-- <div class="react-container" data-config=https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Line_Chart_Regions_Viz.json></div> -->
|
|
50
|
+
<!-- <div class="react-container" data-config=https://www.cdc.gov/wcms/4.0/cdc-wp/data-presentation/examples/Line_Chart_Regions_Viz.json></div> -->
|
|
53
51
|
<!-- <div class="react-container" data-config="/examples/feature/forecasting/forecasting.json"></div> -->
|
|
54
52
|
<!-- <div class="react-container" data-config="/examples/feature/forecasting/combo-forecasting.json"></div> -->
|
|
55
53
|
<!-- <div class="react-container" data-config="/examples/feature/forecasting/effective_reproduction.json"></div> -->
|
|
@@ -125,6 +123,8 @@
|
|
|
125
123
|
|
|
126
124
|
<!-- GENERIC CHART TYPES -->
|
|
127
125
|
<!-- <div class="react-container" data-config="/examples/gallery/paired-bar/paired-bar-chart.json"></div> -->
|
|
126
|
+
<div class="react-container" data-config="/examples/feature/line/line-chart-preliminary.json"></div>
|
|
127
|
+
|
|
128
128
|
|
|
129
129
|
<!-- HORIZONTAL BAR CHARTS -->
|
|
130
130
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json"></div> -->
|
|
@@ -134,7 +134,7 @@
|
|
|
134
134
|
<!-- VERTICAL BAR CHARTS -->
|
|
135
135
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/combo-line-chart.json"></div> -->
|
|
136
136
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json"></div> -->
|
|
137
|
-
<div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json"></div>
|
|
137
|
+
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json"></div> -->
|
|
138
138
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-confidence.json"></div> -->
|
|
139
139
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart.json"></div> -->
|
|
140
140
|
<!-- <div class="react-container" data-config="https://www.cdc.gov/respiratory-viruses/modules/respiratory-virus-activity/emergency-dept-visits_live.json"></div> -->
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cdc/chart",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.24.1",
|
|
4
4
|
"description": "React component for visualizing tabular data in various types of charts",
|
|
5
5
|
"moduleName": "CdcChart",
|
|
6
6
|
"main": "dist/cdcchart",
|
|
@@ -59,7 +59,7 @@
|
|
|
59
59
|
"react": "^18.2.0",
|
|
60
60
|
"react-dom": "^18.2.0"
|
|
61
61
|
},
|
|
62
|
-
"gitHead": "
|
|
62
|
+
"gitHead": "a352a3f74f4b681191e3244061dbb3621f36eec3",
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"resize-observer-polyfill": "^1.5.1"
|
|
65
65
|
}
|
package/src/CdcChart.tsx
CHANGED
|
@@ -12,19 +12,27 @@ import { timeParse, timeFormat } from 'd3-time-format'
|
|
|
12
12
|
import Papa from 'papaparse'
|
|
13
13
|
import parse from 'html-react-parser'
|
|
14
14
|
import 'react-tooltip/dist/react-tooltip.css'
|
|
15
|
-
import chroma from 'chroma-js'
|
|
16
15
|
|
|
17
16
|
// Primary Components
|
|
18
17
|
import ConfigContext from './ConfigContext'
|
|
19
|
-
import PieChart from './components/PieChart'
|
|
18
|
+
import PieChart from './components/PieChart/PieChart'
|
|
20
19
|
import LinearChart from './components/LinearChart'
|
|
21
20
|
|
|
22
21
|
import { colorPalettesChart as colorPalettes, twoColorPalette } from '@cdc/core/data/colorPalettes'
|
|
23
22
|
|
|
24
|
-
import SparkLine from './components/
|
|
23
|
+
import SparkLine from './components/Sparkline'
|
|
25
24
|
import Legend from './components/Legend'
|
|
26
25
|
import defaults from './data/initial-state'
|
|
27
26
|
import EditorPanel from './components/EditorPanel'
|
|
27
|
+
import { abbreviateNumber } from './helpers/abbreviateNumber'
|
|
28
|
+
import { getQuartiles } from './helpers/getQuartiles'
|
|
29
|
+
import { sortAsc, sortDesc } from './helpers/sort'
|
|
30
|
+
import { filterData } from './helpers/filterData'
|
|
31
|
+
import { handleChartAriaLabels } from './helpers/handleChartAriaLabels'
|
|
32
|
+
import { lineOptions } from './helpers/lineOptions'
|
|
33
|
+
import { handleLineType } from './helpers/handleLineType'
|
|
34
|
+
import { generateColorsArray } from './helpers/generateColorsArray'
|
|
35
|
+
import { computeMarginBottom } from './helpers/computeMarginBottom'
|
|
28
36
|
import Loading from '@cdc/core/components/Loading'
|
|
29
37
|
import Filters from '@cdc/core/components/Filters'
|
|
30
38
|
import MediaControls from '@cdc/core/components/MediaControls'
|
|
@@ -45,13 +53,6 @@ import DataTable from '@cdc/core/components/DataTable'
|
|
|
45
53
|
import { getFileExtension } from '@cdc/core/helpers/getFileExtension'
|
|
46
54
|
import Title from '@cdc/core/components/ui/Title'
|
|
47
55
|
|
|
48
|
-
const generateColorsArray = (color = '#000000', special = false) => {
|
|
49
|
-
let colorObj = chroma(color)
|
|
50
|
-
let hoverColor = special ? colorObj.brighten(0.5).hex() : colorObj.saturate(1.3).hex()
|
|
51
|
-
|
|
52
|
-
return [color, hoverColor, colorObj.darken(0.3).hex()]
|
|
53
|
-
}
|
|
54
|
-
|
|
55
56
|
export default function CdcChart({ configUrl, config: configObj, isEditor = false, isDebug = false, isDashboard = false, setConfig: setParentConfig, setEditing, hostname, link, setSharedFilter, setSharedFilterValue, dashboardConfig }) {
|
|
56
57
|
const transform = new DataTransform()
|
|
57
58
|
const [loading, setLoading] = useState(true)
|
|
@@ -88,34 +89,6 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
88
89
|
|
|
89
90
|
const handleChartTabbing = config.showSidebar ? `#legend` : config?.title ? `#dataTableSection__${config.title.replace(/\s/g, '')}` : `#dataTableSection`
|
|
90
91
|
|
|
91
|
-
const sortAsc = (a, b) => {
|
|
92
|
-
return a.toString().localeCompare(b.toString(), 'en', { numeric: true })
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const sortDesc = (a, b) => {
|
|
96
|
-
return b.toString().localeCompare(a.toString(), 'en', { numeric: true })
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
const handleChartAriaLabels = (state, testing = false) => {
|
|
100
|
-
if (testing) console.log(`handleChartAriaLabels Testing On:`, state) // eslint-disable-line
|
|
101
|
-
try {
|
|
102
|
-
if (!state.visualizationType) throw Error('handleChartAriaLabels: no visualization type found in state')
|
|
103
|
-
let ariaLabel = ''
|
|
104
|
-
|
|
105
|
-
if (state.visualizationType) {
|
|
106
|
-
ariaLabel += `${state.visualizationType} chart`
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
if (state.title && state.visualizationType) {
|
|
110
|
-
ariaLabel += ` with the title: ${state.title}`
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return ariaLabel
|
|
114
|
-
} catch (e) {
|
|
115
|
-
console.error('COVE: ', e.message) // eslint-disable-line
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
|
|
119
92
|
const reloadURLData = async () => {
|
|
120
93
|
if (config.dataUrl) {
|
|
121
94
|
const dataUrl = new URL(config.runtimeDataUrl || config.dataUrl, window.location.origin)
|
|
@@ -143,7 +116,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
143
116
|
let data: any[] = []
|
|
144
117
|
|
|
145
118
|
try {
|
|
146
|
-
const ext = getFileExtension(dataUrl.
|
|
119
|
+
const ext = getFileExtension(dataUrl.href)
|
|
147
120
|
if ('csv' === ext) {
|
|
148
121
|
data = await fetch(dataUrlFinal)
|
|
149
122
|
.then(response => response.text())
|
|
@@ -182,44 +155,6 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
182
155
|
}
|
|
183
156
|
}
|
|
184
157
|
|
|
185
|
-
const handleLineType = lineType => {
|
|
186
|
-
switch (lineType) {
|
|
187
|
-
case 'dashed-sm':
|
|
188
|
-
return '5 5'
|
|
189
|
-
case 'Dashed Small':
|
|
190
|
-
return '5 5'
|
|
191
|
-
case 'dashed-md':
|
|
192
|
-
return '10 5'
|
|
193
|
-
case 'Dashed Medium':
|
|
194
|
-
return '10 5'
|
|
195
|
-
case 'dashed-lg':
|
|
196
|
-
return '15 5'
|
|
197
|
-
case 'Dashed Large':
|
|
198
|
-
return '15 5'
|
|
199
|
-
default:
|
|
200
|
-
return 0
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
const lineOptions = [
|
|
205
|
-
{
|
|
206
|
-
value: 'Dashed Small',
|
|
207
|
-
key: 'dashed-sm'
|
|
208
|
-
},
|
|
209
|
-
{
|
|
210
|
-
value: 'Dashed Medium',
|
|
211
|
-
key: 'dashed-md'
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
value: 'Dashed Large',
|
|
215
|
-
key: 'dashed-lg'
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
value: 'Solid Line',
|
|
219
|
-
key: 'solid-line'
|
|
220
|
-
}
|
|
221
|
-
]
|
|
222
|
-
|
|
223
158
|
const loadConfig = async () => {
|
|
224
159
|
let response = configObj || (await (await fetch(configUrl)).json())
|
|
225
160
|
|
|
@@ -392,37 +327,6 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
392
327
|
let tableData: any[] = []
|
|
393
328
|
const plots: any[] = []
|
|
394
329
|
|
|
395
|
-
/**
|
|
396
|
-
* Calculates the first quartile (q1) and third quartile (q3) from an array of integers or decimals.
|
|
397
|
-
*
|
|
398
|
-
* @param {Array} arr - The array of integers or decimals.
|
|
399
|
-
* @returns {Object} An object containing the q1 and q3 values.
|
|
400
|
-
*/
|
|
401
|
-
const getQuartiles = arr => {
|
|
402
|
-
arr.sort((a, b) => a - b)
|
|
403
|
-
|
|
404
|
-
// Calculate the index of the median value of the array
|
|
405
|
-
const medianIndex = Math.floor(arr.length / 2)
|
|
406
|
-
|
|
407
|
-
// Check if the length of the array is even or odd
|
|
408
|
-
const isEvenLength = arr.length % 2 === 0
|
|
409
|
-
|
|
410
|
-
// Split the array into two subarrays based on the median index
|
|
411
|
-
const q1Array = isEvenLength ? arr.slice(0, medianIndex) : arr.slice(0, medianIndex + 1)
|
|
412
|
-
const q3Array = isEvenLength ? arr.slice(medianIndex) : arr.slice(medianIndex + 1)
|
|
413
|
-
|
|
414
|
-
// Calculate the median of the first subarray to get the q1 value
|
|
415
|
-
const q1Index = Math.floor(q1Array.length / 2)
|
|
416
|
-
const q1 = isEvenLength ? (q1Array[q1Index - 1] + q1Array[q1Index]) / 2 : q1Array[q1Index]
|
|
417
|
-
|
|
418
|
-
// Calculate the median of the second subarray to get the q3 value
|
|
419
|
-
const q3Index = Math.floor(q3Array.length / 2)
|
|
420
|
-
const q3 = isEvenLength ? (q3Array[q3Index - 1] + q3Array[q3Index]) / 2 : q3Array[q3Index]
|
|
421
|
-
|
|
422
|
-
// Return an object containing the q1 and q3 values
|
|
423
|
-
return { q1, q3 }
|
|
424
|
-
}
|
|
425
|
-
|
|
426
330
|
// group specific statistics
|
|
427
331
|
// prevent re-renders
|
|
428
332
|
if (!groups) return
|
|
@@ -547,11 +451,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
547
451
|
newConfig.runtime.xAxis = newConfig.yAxis
|
|
548
452
|
newConfig.runtime.yAxis = newConfig.xAxis
|
|
549
453
|
|
|
550
|
-
|
|
551
|
-
newConfig.runtime.xAxis.type = newConfig.forestPlot.type
|
|
552
|
-
newConfig.runtime.xAxis.tickRotation = newConfig.xAxis.tickRotation
|
|
553
|
-
}
|
|
554
|
-
newConfig.runtime.horizontal = true
|
|
454
|
+
newConfig.runtime.horizontal = false
|
|
555
455
|
newConfig.orientation = 'horizontal'
|
|
556
456
|
} else if (['Box Plot', 'Scatter Plot', 'Area Chart', 'Line', 'Forecasting'].includes(newConfig.visualizationType)) {
|
|
557
457
|
newConfig.runtime.xAxis = newConfig.xAxis
|
|
@@ -569,25 +469,6 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
569
469
|
setConfig(newConfig)
|
|
570
470
|
}
|
|
571
471
|
|
|
572
|
-
const filterData = (filters, data) => {
|
|
573
|
-
let filteredData: any[] = []
|
|
574
|
-
|
|
575
|
-
data.forEach(row => {
|
|
576
|
-
let add = true
|
|
577
|
-
filters
|
|
578
|
-
.filter(filter => filter.type !== 'url')
|
|
579
|
-
.forEach(filter => {
|
|
580
|
-
if (row[filter.columnName] != filter.active) {
|
|
581
|
-
add = false
|
|
582
|
-
}
|
|
583
|
-
})
|
|
584
|
-
|
|
585
|
-
if (add) filteredData.push(row)
|
|
586
|
-
})
|
|
587
|
-
|
|
588
|
-
return filteredData
|
|
589
|
-
}
|
|
590
|
-
|
|
591
472
|
// Gets filter values from dataset
|
|
592
473
|
const generateValuesForFilter = (columnName, data = this.state.data) => {
|
|
593
474
|
const values: any[] = []
|
|
@@ -845,24 +726,6 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
845
726
|
return Math.ceil(context.measureText(text).width)
|
|
846
727
|
}
|
|
847
728
|
|
|
848
|
-
const abbreviateNumber = num => {
|
|
849
|
-
let unit = ''
|
|
850
|
-
let absNum = Math.abs(num)
|
|
851
|
-
|
|
852
|
-
if (absNum >= 1e9) {
|
|
853
|
-
unit = 'B'
|
|
854
|
-
num = num / 1e9
|
|
855
|
-
} else if (absNum >= 1e6) {
|
|
856
|
-
unit = 'M'
|
|
857
|
-
num = num / 1e6
|
|
858
|
-
} else if (absNum >= 1e3) {
|
|
859
|
-
unit = 'K'
|
|
860
|
-
num = num / 1e3
|
|
861
|
-
}
|
|
862
|
-
|
|
863
|
-
return num + unit
|
|
864
|
-
}
|
|
865
|
-
|
|
866
729
|
// Format numeric data based on settings in config OR from passed in settings for Additional Columns
|
|
867
730
|
// - use only for old horizontal data - newer formatNumber is in helper/formatNumber
|
|
868
731
|
// TODO: we should combine various formatNumber functions across this project.
|
|
@@ -914,11 +777,17 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
914
777
|
}
|
|
915
778
|
}
|
|
916
779
|
|
|
780
|
+
const resolveBottomTickRounding = () => {
|
|
781
|
+
if (config.forestPlot.type === 'Logarithmic' && !bottomRoundTo) return 2
|
|
782
|
+
if (Number(bottomRoundTo)) return Number(bottomRoundTo)
|
|
783
|
+
return 0
|
|
784
|
+
}
|
|
785
|
+
|
|
917
786
|
if (axis === 'bottom') {
|
|
918
787
|
stringFormattingOptions = {
|
|
919
788
|
useGrouping: config.dataFormat.bottomCommas ? true : false,
|
|
920
|
-
minimumFractionDigits:
|
|
921
|
-
maximumFractionDigits:
|
|
789
|
+
minimumFractionDigits: resolveBottomTickRounding(),
|
|
790
|
+
maximumFractionDigits: resolveBottomTickRounding()
|
|
922
791
|
}
|
|
923
792
|
}
|
|
924
793
|
|
|
@@ -1136,61 +1005,6 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1136
1005
|
return key
|
|
1137
1006
|
}
|
|
1138
1007
|
|
|
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
|
-
|
|
1194
1008
|
// Prevent render if loading
|
|
1195
1009
|
let body = <Loading />
|
|
1196
1010
|
|
|
@@ -1214,7 +1028,10 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1214
1028
|
{config.filters && !externalFilters && <Filters config={config} setConfig={setConfig} setFilteredData={setFilteredData} filteredData={filteredData} excludedData={excludedData} filterData={filterData} dimensions={dimensions} />}
|
|
1215
1029
|
{/* Visualization */}
|
|
1216
1030
|
{config?.introText && config.visualizationType !== 'Spark Line' && <section className='introText'>{parse(config.introText)}</section>}
|
|
1217
|
-
<div
|
|
1031
|
+
<div
|
|
1032
|
+
style={{ marginBottom: computeMarginBottom(config, legend, currentViewport) }}
|
|
1033
|
+
className={`chart-container p-relative ${config.legend.position === 'bottom' ? 'bottom' : ''}${config.legend.hide ? ' legend-hidden' : ''}${lineDatapointClass}${barBorderClass} ${contentClasses.join(' ')} ${isDebug ? 'debug' : ''}`}
|
|
1034
|
+
>
|
|
1218
1035
|
{/* All charts except sparkline */}
|
|
1219
1036
|
{config.visualizationType !== 'Spark Line' && chartComponents[config.visualizationType]}
|
|
1220
1037
|
|
|
@@ -1236,7 +1053,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1236
1053
|
)}
|
|
1237
1054
|
</>
|
|
1238
1055
|
)}
|
|
1239
|
-
{!config.legend.hide && config.visualizationType !== 'Spark Line' && <Legend />}
|
|
1056
|
+
{!config.legend.hide && config.visualizationType !== 'Spark Line' && config.visualizationType !== 'Forest Plot' && <Legend />}
|
|
1240
1057
|
</div>
|
|
1241
1058
|
{/* Link */}
|
|
1242
1059
|
{isDashboard && config.table && config.table.show && config.table.showDataTableLink ? tableLink : link && link}
|
|
@@ -1286,6 +1103,7 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1286
1103
|
|
|
1287
1104
|
const contextValues = {
|
|
1288
1105
|
capitalize,
|
|
1106
|
+
computeMarginBottom,
|
|
1289
1107
|
getXAxisData,
|
|
1290
1108
|
getYAxisData,
|
|
1291
1109
|
config,
|
|
@@ -1328,7 +1146,8 @@ export default function CdcChart({ configUrl, config: configObj, isEditor = fals
|
|
|
1328
1146
|
isDebug,
|
|
1329
1147
|
setSharedFilter,
|
|
1330
1148
|
setSharedFilterValue,
|
|
1331
|
-
dashboardConfig
|
|
1149
|
+
dashboardConfig,
|
|
1150
|
+
debugSvg: isDebug
|
|
1332
1151
|
}
|
|
1333
1152
|
|
|
1334
1153
|
const classes = ['cdc-open-viz-module', 'type-chart', `${currentViewport}`, `font-${config.fontSize}`, `${config.theme}`]
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
|
|
3
|
+
import Chart from '../CdcChart'
|
|
4
|
+
|
|
5
|
+
import pieChartExample from './_mock/pie_config.json'
|
|
6
|
+
import pieData from './_mock/pie_data.json'
|
|
7
|
+
|
|
8
|
+
const meta: Meta<typeof Chart> = {
|
|
9
|
+
title: 'Components/Templates/Editor/Chart',
|
|
10
|
+
component: Chart
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type Story = StoryObj<typeof Chart>
|
|
14
|
+
|
|
15
|
+
export const Primary: Story = {
|
|
16
|
+
args: {
|
|
17
|
+
config: { ...pieChartExample, data: pieData },
|
|
18
|
+
isEditor: true
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default meta
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react'
|
|
2
|
+
import chartLinepreliminary from './_mock/preliminary_mock.json'
|
|
3
|
+
|
|
4
|
+
import Chart from '../CdcChart'
|
|
5
|
+
|
|
6
|
+
const meta: Meta<typeof Chart> = {
|
|
7
|
+
title: 'Components/Templates/Chart/Line/Preliminary',
|
|
8
|
+
component: Chart
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type Story = StoryObj<typeof Chart>
|
|
12
|
+
|
|
13
|
+
export const Line_Chart: Story = {
|
|
14
|
+
args: {
|
|
15
|
+
config: chartLinepreliminary
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export default meta
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
{
|
|
2
|
+
"type": "chart",
|
|
3
|
+
"debugSvg": false,
|
|
4
|
+
"chartMessage": {
|
|
5
|
+
"noData": "No Data Available"
|
|
6
|
+
},
|
|
7
|
+
"title": "ARDI",
|
|
8
|
+
"showTitle": true,
|
|
9
|
+
"showDownloadMediaButton": false,
|
|
10
|
+
"theme": "theme-blue",
|
|
11
|
+
"animate": false,
|
|
12
|
+
"fontSize": "medium",
|
|
13
|
+
"lineDatapointStyle": "hover",
|
|
14
|
+
"lineDatapointColor": "Same as Line",
|
|
15
|
+
"barHasBorder": "false",
|
|
16
|
+
"isLollipopChart": false,
|
|
17
|
+
"lollipopShape": "circle",
|
|
18
|
+
"lollipopColorStyle": "two-tone",
|
|
19
|
+
"visualizationSubType": "regular",
|
|
20
|
+
"barStyle": "",
|
|
21
|
+
"roundingStyle": "standard",
|
|
22
|
+
"tipRounding": "top",
|
|
23
|
+
"isResponsiveTicks": false,
|
|
24
|
+
"general": {
|
|
25
|
+
"showDownloadButton": false
|
|
26
|
+
},
|
|
27
|
+
"padding": {
|
|
28
|
+
"left": 5,
|
|
29
|
+
"right": 5
|
|
30
|
+
},
|
|
31
|
+
"suppressedData": [],
|
|
32
|
+
"yAxis": {
|
|
33
|
+
"hideAxis": false,
|
|
34
|
+
"displayNumbersOnBar": false,
|
|
35
|
+
"hideLabel": false,
|
|
36
|
+
"hideTicks": false,
|
|
37
|
+
"size": 50,
|
|
38
|
+
"gridLines": false,
|
|
39
|
+
"enablePadding": false,
|
|
40
|
+
"min": "",
|
|
41
|
+
"max": "",
|
|
42
|
+
"labelColor": "#333",
|
|
43
|
+
"tickLabelColor": "#333",
|
|
44
|
+
"tickColor": "#333",
|
|
45
|
+
"rightHideAxis": true,
|
|
46
|
+
"rightAxisSize": 0,
|
|
47
|
+
"rightLabel": "",
|
|
48
|
+
"rightLabelOffsetSize": 0,
|
|
49
|
+
"rightAxisLabelColor": "#333",
|
|
50
|
+
"rightAxisTickLabelColor": "#333",
|
|
51
|
+
"rightAxisTickColor": "#333",
|
|
52
|
+
"numTicks": "",
|
|
53
|
+
"axisPadding": 0,
|
|
54
|
+
"tickRotation": 0,
|
|
55
|
+
"anchors": [],
|
|
56
|
+
"dataKey": "males"
|
|
57
|
+
},
|
|
58
|
+
"topAxis": {
|
|
59
|
+
"hasLine": false
|
|
60
|
+
},
|
|
61
|
+
"isLegendValue": false,
|
|
62
|
+
"barThickness": 0.35,
|
|
63
|
+
"barHeight": 25,
|
|
64
|
+
"barSpace": 15,
|
|
65
|
+
"heights": {
|
|
66
|
+
"vertical": 300,
|
|
67
|
+
"horizontal": 750
|
|
68
|
+
},
|
|
69
|
+
"xAxis": {
|
|
70
|
+
"sortDates": false,
|
|
71
|
+
"anchors": [],
|
|
72
|
+
"type": "categorical",
|
|
73
|
+
"showTargetLabel": true,
|
|
74
|
+
"targetLabel": "Target",
|
|
75
|
+
"hideAxis": false,
|
|
76
|
+
"hideLabel": false,
|
|
77
|
+
"hideTicks": false,
|
|
78
|
+
"size": 75,
|
|
79
|
+
"tickRotation": 0,
|
|
80
|
+
"min": "",
|
|
81
|
+
"max": "",
|
|
82
|
+
"labelColor": "#333",
|
|
83
|
+
"tickLabelColor": "#333",
|
|
84
|
+
"tickColor": "#333",
|
|
85
|
+
"numTicks": "",
|
|
86
|
+
"labelOffset": 65,
|
|
87
|
+
"axisPadding": 0,
|
|
88
|
+
"target": 0,
|
|
89
|
+
"maxTickRotation": 0,
|
|
90
|
+
"dataKey": "cause_type"
|
|
91
|
+
},
|
|
92
|
+
"table": {
|
|
93
|
+
"label": "Data Table",
|
|
94
|
+
"expanded": true,
|
|
95
|
+
"limitHeight": false,
|
|
96
|
+
"height": "",
|
|
97
|
+
"caption": "",
|
|
98
|
+
"showDownloadUrl": false,
|
|
99
|
+
"showDataTableLink": true,
|
|
100
|
+
"indexLabel": "",
|
|
101
|
+
"download": false,
|
|
102
|
+
"showVertical": true,
|
|
103
|
+
"show": true,
|
|
104
|
+
"customTableConfig": true
|
|
105
|
+
},
|
|
106
|
+
"orientation": "vertical",
|
|
107
|
+
"color": "pinkpurple",
|
|
108
|
+
"columns": {},
|
|
109
|
+
"legend": {
|
|
110
|
+
"hide": false,
|
|
111
|
+
"behavior": "isolate",
|
|
112
|
+
"singleRow": false,
|
|
113
|
+
"colorCode": "",
|
|
114
|
+
"reverseLabelOrder": false,
|
|
115
|
+
"description": "",
|
|
116
|
+
"dynamicLegend": false,
|
|
117
|
+
"dynamicLegendDefaultText": "Show All",
|
|
118
|
+
"dynamicLegendItemLimit": 5,
|
|
119
|
+
"dynamicLegendItemLimitMessage": "Dynamic Legend Item Limit Hit.",
|
|
120
|
+
"dynamicLegendChartMessage": "Select Options from the Legend",
|
|
121
|
+
"lineMode": false,
|
|
122
|
+
"verticalSorted": false,
|
|
123
|
+
"highlightOnHover": false
|
|
124
|
+
},
|
|
125
|
+
"brush": {
|
|
126
|
+
"height": 25,
|
|
127
|
+
"data": [],
|
|
128
|
+
"active": false
|
|
129
|
+
},
|
|
130
|
+
"exclusions": {
|
|
131
|
+
"active": true,
|
|
132
|
+
"keys": ["all_causes"]
|
|
133
|
+
},
|
|
134
|
+
"palette": "qualitative-soft",
|
|
135
|
+
"isPaletteReversed": false,
|
|
136
|
+
"twoColor": {
|
|
137
|
+
"palette": "monochrome-1",
|
|
138
|
+
"isPaletteReversed": false
|
|
139
|
+
},
|
|
140
|
+
"labels": false,
|
|
141
|
+
"dataFormat": {
|
|
142
|
+
"commas": false,
|
|
143
|
+
"prefix": "",
|
|
144
|
+
"suffix": "",
|
|
145
|
+
"abbreviated": false,
|
|
146
|
+
"bottomSuffix": "",
|
|
147
|
+
"bottomPrefix": "",
|
|
148
|
+
"bottomAbbreviated": false,
|
|
149
|
+
"roundTo": 1
|
|
150
|
+
},
|
|
151
|
+
"confidenceKeys": {},
|
|
152
|
+
"visual": {
|
|
153
|
+
"border": true,
|
|
154
|
+
"accent": true,
|
|
155
|
+
"background": true,
|
|
156
|
+
"verticalHoverLine": false,
|
|
157
|
+
"horizontalHoverLine": false
|
|
158
|
+
},
|
|
159
|
+
"useLogScale": false,
|
|
160
|
+
"filterBehavior": "Filter Change",
|
|
161
|
+
"highlightedBarValues": [],
|
|
162
|
+
"series": [
|
|
163
|
+
{
|
|
164
|
+
"dataKey": "males",
|
|
165
|
+
"axis": "Left",
|
|
166
|
+
"tooltip": true
|
|
167
|
+
}
|
|
168
|
+
],
|
|
169
|
+
"tooltips": {
|
|
170
|
+
"opacity": 90,
|
|
171
|
+
"singleSeries": false
|
|
172
|
+
},
|
|
173
|
+
"dashboard": {
|
|
174
|
+
"theme": "theme-blue",
|
|
175
|
+
"title": "ARDI"
|
|
176
|
+
},
|
|
177
|
+
"animateReplay": true,
|
|
178
|
+
"aspectRatio": 1,
|
|
179
|
+
"validated": 4.23,
|
|
180
|
+
"visualizationType": "Pie",
|
|
181
|
+
"pieType": "Donut",
|
|
182
|
+
"filters": [
|
|
183
|
+
{
|
|
184
|
+
"values": ["age", "sex"],
|
|
185
|
+
"active": "age",
|
|
186
|
+
"filterStyle": "dropdown",
|
|
187
|
+
"order": "asc",
|
|
188
|
+
"columnName": "data_group"
|
|
189
|
+
}
|
|
190
|
+
]
|
|
191
|
+
}
|