@cdc/chart 4.22.10 → 4.23.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/README.md +5 -5
- package/dist/495.js +3 -0
- package/dist/703.js +1 -0
- package/dist/cdcchart.js +723 -6
- package/examples/age-adjusted-rates.json +1486 -1218
- package/examples/box-plot-data.json +71 -0
- package/examples/box-plot.csv +5 -0
- package/examples/{private/yaxis-test.json → box-plot.json} +46 -54
- package/examples/case-rate-example-config.json +1 -1
- package/examples/covid-confidence-example-config.json +33 -33
- package/examples/covid-example-config.json +34 -34
- package/examples/covid-example-data-confidence.json +30 -30
- package/examples/covid-example-data.json +20 -20
- package/examples/cutoff-example-config.json +36 -36
- package/examples/cutoff-example-data.json +36 -36
- package/examples/date-exclusions-config.json +1 -1
- package/examples/dynamic-legends.json +124 -124
- package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json +191 -197
- package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json +230 -240
- package/examples/gallery/bar-chart-horizontal/horizontal-stacked.json +239 -247
- package/examples/gallery/bar-chart-vertical/combo-line-chart.json +138 -136
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json +79 -79
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json +80 -80
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-with-confidence.json +67 -67
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart.json +179 -110
- package/examples/gallery/lollipop/lollipop-style-horizontal.json +215 -219
- package/examples/gallery/paired-bar/paired-bar-chart.json +195 -195
- package/examples/horizontal-chart.json +35 -35
- package/examples/horizontal-stacked-bar-chart.json +34 -34
- package/examples/line-chart.json +75 -75
- package/examples/new-data.csv +17 -0
- package/examples/newdata.json +90 -0
- package/examples/paired-bar-data.json +16 -14
- package/examples/paired-bar-example.json +48 -48
- package/examples/paired-bar-formatted.json +36 -36
- package/examples/planet-chart-horizontal-example-config.json +33 -33
- package/examples/planet-combo-example-config.json +34 -31
- package/examples/planet-example-config.json +35 -33
- package/examples/planet-example-data.json +56 -56
- package/examples/planet-pie-example-config.json +28 -28
- package/examples/stacked-vertical-bar-example.json +1 -1
- package/examples/temp-example-config.json +61 -54
- package/examples/temp-example-data.json +1 -1
- package/package.json +3 -2
- package/src/CdcChart.tsx +449 -434
- package/src/components/BarChart.tsx +383 -497
- package/src/components/BoxPlot.js +92 -0
- package/src/components/DataTable.tsx +182 -197
- package/src/components/EditorPanel.js +1068 -722
- package/src/components/Filters.js +131 -0
- package/src/components/Legend.js +286 -329
- package/src/components/LineChart.tsx +143 -81
- package/src/components/LinearChart.tsx +432 -451
- package/src/components/PairedBarChart.tsx +197 -213
- package/src/components/PieChart.tsx +105 -151
- package/src/components/SparkLine.js +179 -201
- package/src/components/useIntersectionObserver.tsx +19 -20
- package/src/context.tsx +3 -3
- package/src/data/initial-state.js +44 -17
- package/src/hooks/useActiveElement.js +13 -13
- package/src/hooks/useChartClasses.js +34 -28
- package/src/hooks/useColorPalette.ts +56 -63
- package/src/hooks/useLegendClasses.js +18 -10
- package/src/hooks/useReduceData.ts +64 -77
- package/src/hooks/useRightAxis.js +25 -0
- package/src/hooks/useTopAxis.js +6 -0
- package/src/index.html +19 -19
- package/src/index.tsx +13 -16
- package/src/scss/DataTable.scss +6 -5
- package/src/scss/editor-panel.scss +71 -69
- package/src/scss/main.scss +188 -114
- package/src/scss/variables.scss +1 -1
- package/examples/private/line-test-data.json +0 -22
- package/examples/private/line-test-two.json +0 -216
- package/examples/private/line-test.json +0 -102
- package/examples/private/newtest.csv +0 -101
- package/examples/private/shawn.json +0 -1296
- package/examples/private/test.json +0 -10124
- package/examples/private/yaxis-testing.csv +0 -27
- package/examples/private/yaxis.json +0 -28
|
@@ -1,35 +1,41 @@
|
|
|
1
1
|
export default function useChartClasses(config) {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
let lineDatapointClass = ''
|
|
3
|
+
let barBorderClass = ''
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
if (config.lineDatapointStyle === 'hover') {
|
|
6
|
+
lineDatapointClass = ' chart-line--hover'
|
|
7
|
+
}
|
|
8
|
+
if (config.lineDatapointStyle === 'always show') {
|
|
9
|
+
lineDatapointClass = ' chart-line--always'
|
|
10
|
+
}
|
|
11
|
+
if (config.barHasBorder === 'false') {
|
|
12
|
+
barBorderClass = ' chart-bar--no-border'
|
|
13
|
+
}
|
|
8
14
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
15
|
+
let innerContainerClasses = ['cove-component__inner']
|
|
16
|
+
config.title && innerContainerClasses.push('component--has-title')
|
|
17
|
+
config.subtext && innerContainerClasses.push('component--has-subtext')
|
|
18
|
+
config.biteStyle && innerContainerClasses.push(`bite__style--${config.biteStyle}`)
|
|
19
|
+
config.general?.isCompactStyle && innerContainerClasses.push(`component--isCompactStyle`)
|
|
14
20
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
21
|
+
let contentClasses = ['cove-component__content']
|
|
22
|
+
config.visualizationType === 'Spark Line' && contentClasses.push('sparkline')
|
|
23
|
+
!config.visual?.border && contentClasses.push('no-borders')
|
|
24
|
+
config.visual?.borderColorTheme && contentClasses.push('component--has-borderColorTheme')
|
|
25
|
+
config.visual?.accent && contentClasses.push('component--has-accent')
|
|
26
|
+
config.visual?.background && contentClasses.push('component--has-background')
|
|
27
|
+
config.visual?.hideBackgroundColor && contentClasses.push('component--hideBackgroundColor')
|
|
22
28
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
let sparkLineStyles = {
|
|
30
|
+
width: '100%',
|
|
31
|
+
height: '100px'
|
|
32
|
+
}
|
|
27
33
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
34
|
+
return {
|
|
35
|
+
barBorderClass,
|
|
36
|
+
lineDatapointClass,
|
|
37
|
+
contentClasses,
|
|
38
|
+
innerContainerClasses,
|
|
39
|
+
sparkLineStyles
|
|
40
|
+
}
|
|
35
41
|
}
|
|
@@ -1,83 +1,76 @@
|
|
|
1
|
-
import { useEffect, useReducer } from 'react'
|
|
1
|
+
import { useEffect, useReducer } from 'react'
|
|
2
2
|
|
|
3
|
-
// constants
|
|
4
|
-
const SEQUENTIAL = 'SEQUENTIAL'
|
|
5
|
-
const SEQUENTIAL_REVERSE = 'SEQUENTIAL_REVERSE'
|
|
6
|
-
export const GET_PALETTE = 'GET_PALETTE'
|
|
3
|
+
// constants
|
|
4
|
+
const SEQUENTIAL = 'SEQUENTIAL'
|
|
5
|
+
const SEQUENTIAL_REVERSE = 'SEQUENTIAL_REVERSE'
|
|
6
|
+
export const GET_PALETTE = 'GET_PALETTE'
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
// types & interfaces
|
|
8
|
+
// types & interfaces
|
|
10
9
|
interface State {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
payload: Palettes;
|
|
22
|
-
paletteName?:string
|
|
23
|
-
};
|
|
10
|
+
readonly filteredPallets: string[]
|
|
11
|
+
readonly filteredQualitative: string[]
|
|
12
|
+
readonly isPaletteReversed: boolean
|
|
13
|
+
paletteName: string | undefined
|
|
14
|
+
}
|
|
15
|
+
interface Action<Palettes> {
|
|
16
|
+
type: 'SEQUENTIAL' | 'SEQUENTIAL_REVERSE' | 'GET_PALETTE'
|
|
17
|
+
payload: Palettes
|
|
18
|
+
paletteName?: string
|
|
19
|
+
}
|
|
24
20
|
|
|
25
21
|
// create initial state
|
|
26
|
-
const initialState:State = {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
22
|
+
const initialState: State = {
|
|
23
|
+
filteredPallets: [],
|
|
24
|
+
isPaletteReversed: false,
|
|
25
|
+
filteredQualitative: [],
|
|
26
|
+
paletteName: undefined
|
|
27
|
+
}
|
|
32
28
|
|
|
33
|
-
function reducer<T>
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
29
|
+
function reducer<T>(state: State, action: Action<T>): State {
|
|
30
|
+
// <T> refers to generic type
|
|
31
|
+
const palletNamesArr: string[] = Object.keys(action.payload) // action.payload === colorPalettes object
|
|
32
|
+
let paletteName: string = ''
|
|
33
|
+
switch (action.type) {
|
|
37
34
|
case GET_PALETTE:
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return { ...state, filteredPallets: sequential,filteredQualitative:qualitative, paletteName:paletteName,isPaletteReversed:false};
|
|
35
|
+
return { ...state, paletteName: action.paletteName }
|
|
36
|
+
case SEQUENTIAL:
|
|
37
|
+
paletteName = state.paletteName && state.paletteName.endsWith('reverse') ? String(state.paletteName).substring(0, state.paletteName.length - 7) : String(state.paletteName)
|
|
38
|
+
const qualitative = palletNamesArr.filter((name: string) => String(name).startsWith('qualitative') && !String(name).endsWith('reverse'))
|
|
39
|
+
const sequential = palletNamesArr.filter((name: string) => String(name).startsWith('sequential') && !String(name).endsWith('reverse'))
|
|
40
|
+
return { ...state, filteredPallets: sequential, filteredQualitative: qualitative, paletteName: paletteName, isPaletteReversed: false }
|
|
45
41
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
42
|
+
case SEQUENTIAL_REVERSE:
|
|
43
|
+
paletteName = palletNamesArr.find((name: string) => name === String(state.paletteName).concat('reverse') || name === String(state.paletteName).concat('-reverse'))
|
|
44
|
+
const qualitativeReverse: string[] = palletNamesArr.filter((name: string) => String(name).startsWith('qualitative') && String(name).endsWith('reverse'))
|
|
45
|
+
const sequentialReverse: string[] = palletNamesArr.filter((name: string) => String(name).startsWith('sequential') && String(name).endsWith('reverse'))
|
|
46
|
+
return { ...state, filteredQualitative: qualitativeReverse, filteredPallets: sequentialReverse, paletteName: paletteName, isPaletteReversed: true }
|
|
47
|
+
default:
|
|
48
|
+
return state
|
|
52
49
|
}
|
|
53
|
-
}
|
|
50
|
+
}
|
|
54
51
|
|
|
55
52
|
interface Keyable {
|
|
56
|
-
palette:string
|
|
57
|
-
isPaletteReversed:boolean
|
|
53
|
+
palette: string
|
|
54
|
+
isPaletteReversed: boolean
|
|
58
55
|
}
|
|
59
|
-
function init(initialState){
|
|
56
|
+
function init(initialState) {
|
|
60
57
|
return initialState
|
|
61
58
|
}
|
|
62
59
|
|
|
63
|
-
export function useColorPalette<T,Y extends Keyable>(colorPalettes:T,configState:Y){
|
|
64
|
-
const [state, dispatch] = useReducer(reducer, initialState,init)
|
|
65
|
-
const {paletteName,isPaletteReversed,filteredPallets,filteredQualitative} = state
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
60
|
+
export function useColorPalette<T, Y extends Keyable>(colorPalettes: T, configState: Y) {
|
|
61
|
+
const [state, dispatch] = useReducer(reducer, initialState, init)
|
|
62
|
+
const { paletteName, isPaletteReversed, filteredPallets, filteredQualitative } = state
|
|
69
63
|
|
|
70
64
|
useEffect(() => {
|
|
71
|
-
dispatch({ type: SEQUENTIAL, payload: colorPalettes })
|
|
72
|
-
|
|
73
|
-
|
|
65
|
+
dispatch({ type: SEQUENTIAL, payload: colorPalettes })
|
|
66
|
+
}, [])
|
|
74
67
|
|
|
75
|
-
useEffect(()=>{
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
if (configState.isPaletteReversed) {
|
|
70
|
+
dispatch({ type: 'SEQUENTIAL_REVERSE', payload: colorPalettes })
|
|
71
|
+
return () => dispatch({ type: 'SEQUENTIAL', payload: colorPalettes })
|
|
79
72
|
}
|
|
80
|
-
|
|
73
|
+
}, [configState.isPaletteReversed, dispatch, colorPalettes])
|
|
81
74
|
|
|
82
|
-
|
|
83
|
-
}
|
|
75
|
+
return { paletteName, isPaletteReversed, filteredPallets, filteredQualitative, dispatch }
|
|
76
|
+
}
|
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
export default function useLegendClasses(config) {
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
let containerClasses = ['legend-container']
|
|
3
|
+
let innerClasses = ['legend-container__inner']
|
|
4
4
|
|
|
5
5
|
// Legend Positioning
|
|
6
6
|
if (config.legend.position === "left") {
|
|
7
7
|
containerClasses.push('left')
|
|
8
8
|
}
|
|
9
|
+
if (config.legend.position === "bottom") {
|
|
10
|
+
containerClasses.push('bottom')
|
|
11
|
+
innerClasses.push('bottom')
|
|
12
|
+
}
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
innerClasses.push('d-flex')
|
|
13
|
-
innerClasses.push('flex-column-reverse')
|
|
14
|
+
if(config.legend.position==='bottom' && config.legend.singleRow){
|
|
15
|
+
innerClasses.push('single-row')
|
|
14
16
|
}
|
|
15
17
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
// Legend > Item Ordering
|
|
19
|
+
if (config.legend.reverseLabelOrder) {
|
|
20
|
+
innerClasses.push('d-flex')
|
|
21
|
+
innerClasses.push('flex-column-reverse')
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
containerClasses,
|
|
26
|
+
innerClasses
|
|
27
|
+
}
|
|
20
28
|
}
|
|
@@ -1,91 +1,78 @@
|
|
|
1
|
+
function useReduceData(config, data) {
|
|
2
|
+
// for combo charts check if all Data Series selected to Bar;
|
|
3
|
+
const isBar = config?.series?.every(element => element?.type === 'Bar')
|
|
4
|
+
// for combo charts check if all Data series selected Line or dashed-md/sm/lg.
|
|
5
|
+
const isAllLine = config?.series?.every(el => el.type === 'Line' || el.type=== 'dashed-sm'|| el.type=== 'dashed-md' || el.type=== 'dashed-lg');
|
|
1
6
|
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
7
|
+
const getMaxValueFromData = () => {
|
|
8
|
+
let max // will hold max number from data.
|
|
9
|
+
if ((config.visualizationType === 'Bar' || (config.visualizationType === 'Combo' && isBar)) && config.visualizationSubType === 'stacked') {
|
|
10
|
+
const yTotals = data.reduce((allTotals, xValue) => {
|
|
11
|
+
const totalYValues = config.runtime.seriesKeys.reduce((yTotal, k) => {
|
|
12
|
+
yTotal += Number(xValue[k])
|
|
13
|
+
return yTotal
|
|
14
|
+
}, 0)
|
|
5
15
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const yTotals = data.reduce((allTotals, xValue) => {
|
|
13
|
-
const totalYValues = config.runtime.seriesKeys.reduce((yTotal, k) => {
|
|
14
|
-
yTotal += Number(xValue[k]);
|
|
15
|
-
return yTotal;
|
|
16
|
-
}, 0);
|
|
16
|
+
allTotals.push(totalYValues)
|
|
17
|
+
if (totalYValues > max) {
|
|
18
|
+
max = totalYValues
|
|
19
|
+
}
|
|
20
|
+
return allTotals
|
|
21
|
+
}, [] as number[])
|
|
17
22
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
23
|
+
max = Math.max(...yTotals)
|
|
24
|
+
} else if (config.visualizationType === 'Bar' && config.series && config.series.dataKey) {
|
|
25
|
+
max = Math.max(...data.map(d => Number(d[config.series.dataKey])))
|
|
26
|
+
} else if (config.visualizationType === 'Combo' && config.visualizationSubType === 'stacked' && !isBar) {
|
|
27
|
+
let total = []
|
|
28
|
+
|
|
29
|
+
if (config.runtime.barSeriesKeys && config.runtime.lineSeriesKeys) {
|
|
30
|
+
// get barSeries max Values added to each other
|
|
31
|
+
data.map(function (d, index) {
|
|
32
|
+
const totalYValues = config.runtime.barSeriesKeys.reduce((yTotal, k) => {
|
|
33
|
+
yTotal += Number(d[k])
|
|
34
|
+
return yTotal
|
|
35
|
+
}, 0)
|
|
36
|
+
total.push(totalYValues)
|
|
37
|
+
})
|
|
38
|
+
// get lineSeries largest values
|
|
39
|
+
const lineMax = Math.max(...data.map(d => Math.max(...config.runtime.lineSeriesKeys.map(key => Number(d[key])))))
|
|
24
40
|
|
|
25
|
-
|
|
26
|
-
} else if (
|
|
27
|
-
config.visualizationType === "Bar" &&
|
|
28
|
-
config.series &&
|
|
29
|
-
config.series.dataKey
|
|
30
|
-
) {
|
|
31
|
-
max = Math.max(...data.map((d) => Number(d[config.series.dataKey])));
|
|
41
|
+
const barMax = Math.max(...total)
|
|
32
42
|
|
|
33
|
-
|
|
34
|
-
|
|
43
|
+
max = Number(barMax) > Number(lineMax) ? barMax : lineMax
|
|
44
|
+
}
|
|
45
|
+
} else {
|
|
46
|
+
max = Math.max(...data.map(d => Math.max(...config.runtime.seriesKeys.map(key => Number(d[key])))))
|
|
47
|
+
}
|
|
35
48
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
data.map(function (d,index) {
|
|
39
|
-
const totalYValues =config.runtime.barSeriesKeys.reduce((yTotal, k) => {
|
|
40
|
-
yTotal += Number(d[k]);
|
|
41
|
-
return yTotal;
|
|
42
|
-
}, 0);
|
|
43
|
-
total.push(totalYValues)
|
|
44
|
-
|
|
45
|
-
});
|
|
46
|
-
// get lineSeries largest values
|
|
47
|
-
const lineMax = Math.max(...data.map((d) =>Math.max(...config.runtime.lineSeriesKeys.map((key) => Number(d[key])))));
|
|
49
|
+
return max
|
|
50
|
+
}
|
|
48
51
|
|
|
49
|
-
|
|
52
|
+
const getMinValueFromData = () => {
|
|
53
|
+
let min
|
|
54
|
+
const minNumberFromData = Math.min(...data.map(d => Math.min(...config.runtime.seriesKeys.map(key => Number(d[key])))))
|
|
55
|
+
min = String(minNumberFromData)
|
|
50
56
|
|
|
51
|
-
|
|
57
|
+
return min
|
|
52
58
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
+
|
|
60
|
+
const findPositiveNum = (): boolean => {
|
|
61
|
+
// loop throught provided data to find positve number in arr based on series keys.
|
|
62
|
+
let existPositiveValue = false
|
|
63
|
+
if (config.runtime.seriesKeys) {
|
|
64
|
+
for (let i = 0; i < config.runtime.seriesKeys.length; i++) {
|
|
65
|
+
existPositiveValue = data.some(d => d[config.runtime.seriesKeys[i]] >= 0)
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return existPositiveValue
|
|
59
69
|
}
|
|
60
70
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const getMinValueFromData = ()=> {
|
|
65
|
-
let min;
|
|
66
|
-
const minNumberFromData = Math.min(...data.map((d) => Math.min(...config.runtime.seriesKeys.map((key) => Number(d[key])))));
|
|
67
|
-
min = String(minNumberFromData)
|
|
68
|
-
|
|
69
|
-
return min;
|
|
70
|
-
};
|
|
71
|
+
const maxValue = Number(getMaxValueFromData());
|
|
72
|
+
const minValue = Number(getMinValueFromData());
|
|
73
|
+
const existPositiveValue = findPositiveNum();
|
|
71
74
|
|
|
72
|
-
|
|
73
|
-
// loop throught provided data to find positve number in arr based on series keys.
|
|
74
|
-
let existPositiveValue = false;
|
|
75
|
-
if (config.runtime.seriesKeys) {
|
|
76
|
-
for(let i = 0; i < config.runtime.seriesKeys.length; i++) {
|
|
77
|
-
existPositiveValue = data.some(d => d[config.runtime.seriesKeys[i]] >= 0);
|
|
78
|
-
};
|
|
79
|
-
};
|
|
80
|
-
return existPositiveValue;
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const maxValue = getMaxValueFromData();
|
|
86
|
-
const minValue = getMinValueFromData();
|
|
87
|
-
const existPositiveValue = findPositiveNum();
|
|
88
|
-
return {minValue,maxValue,existPositiveValue};
|
|
75
|
+
return {minValue, maxValue, existPositiveValue ,isAllLine}
|
|
89
76
|
}
|
|
90
77
|
|
|
91
|
-
export default useReduceData
|
|
78
|
+
export default useReduceData
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { scaleLinear } from '@visx/scale'
|
|
2
|
+
|
|
3
|
+
export default function useRightAxis({ config, yMax = 0, data = [], updateConfig }) {
|
|
4
|
+
const hasRightAxis = config.visualizationType === 'Combo' && config.orientation === 'vertical'
|
|
5
|
+
const rightSeriesKeys = config.series && config.series.filter(series => series.axis === 'Right').map(key => key.dataKey)
|
|
6
|
+
|
|
7
|
+
const allRightAxisData = rightSeriesKeys => {
|
|
8
|
+
if (!rightSeriesKeys) return [0]
|
|
9
|
+
let rightAxisData = []
|
|
10
|
+
rightSeriesKeys.map((key, index) => {
|
|
11
|
+
return (rightAxisData = [...rightAxisData, ...data.map(item => Number(item[key]))])
|
|
12
|
+
})
|
|
13
|
+
return rightAxisData
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const min = Math.min.apply(null, allRightAxisData(rightSeriesKeys))
|
|
17
|
+
const max = Math.max.apply(null, allRightAxisData(rightSeriesKeys))
|
|
18
|
+
|
|
19
|
+
const yScaleRight = scaleLinear({
|
|
20
|
+
domain: [0, max],
|
|
21
|
+
range: [yMax, 0]
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
return { yScaleRight, hasRightAxis }
|
|
25
|
+
}
|
package/src/index.html
CHANGED
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
|
-
|
|
4
|
-
<head>
|
|
3
|
+
<head>
|
|
5
4
|
<meta charset="utf-8" />
|
|
6
5
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
|
7
6
|
<style>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
body {
|
|
8
|
+
/* max-width: 1000px; */
|
|
9
|
+
margin: 0 auto !important;
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
}
|
|
15
14
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
.react-container + .react-container {
|
|
16
|
+
margin-top: 3rem;
|
|
17
|
+
}
|
|
19
18
|
</style>
|
|
20
|
-
</head>
|
|
19
|
+
</head>
|
|
21
20
|
|
|
22
|
-
<body>
|
|
21
|
+
<body>
|
|
23
22
|
<!-- <div class="react-container" data-config="/examples/temp-example-config.json"></div> -->
|
|
24
23
|
|
|
25
24
|
<!-- <select id="cove_select">
|
|
@@ -28,13 +27,15 @@
|
|
|
28
27
|
<option value="Hispanic or Latino">Test 2</option>
|
|
29
28
|
</select> -->
|
|
30
29
|
|
|
30
|
+
<!-- <div class="react-container" data-config="/examples/private/filters.json"></div> -->
|
|
31
|
+
<!-- <div class="react-container" data-config="/examples/private/yaxis-test.json"></div> -->
|
|
31
32
|
<!-- <div class="react-container" data-config="/examples/dynamic-legends.json"></div> -->
|
|
32
33
|
<!-- <div class="react-container" data-config="/examples/cutoff-example-config.json"></div> -->
|
|
33
34
|
<!-- <div class="react-container" data-config="/examples/covid-confidence-example-config.json"></div> -->
|
|
34
35
|
<!-- <div class="react-container" data-config="/examples/planet-example-config.json"></div> -->
|
|
35
36
|
<!-- <div class="react-container" data-config="/examples/planet-chart-horizontal-example-config.json"></div> -->
|
|
36
|
-
<!--
|
|
37
|
-
|
|
37
|
+
<!-- <div class="react-container" data-config="/examples/planet-combo-example-config.json"></div>-->
|
|
38
|
+
<!-- <div class="react-container" data-config="/examples/planet-pie-example-config.json"></div>-->
|
|
38
39
|
<!-- <div class="react-container" data-config="/examples/date-exclusions-config.json"></div> -->
|
|
39
40
|
<!--<div class="react-container" data-config="/examples/case-rate-example-config.json"></div>-->
|
|
40
41
|
<!-- <div class="react-container" data-config="/examples/private/textelements.json"></div> -->
|
|
@@ -47,13 +48,13 @@
|
|
|
47
48
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json"></div> -->
|
|
48
49
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-horizontal/horizontal-stacked.json"></div> -->
|
|
49
50
|
|
|
50
|
-
|
|
51
51
|
<!-- VERTICAL BAR CHARTS -->
|
|
52
52
|
<div class="react-container" data-config="/examples/gallery/bar-chart-vertical/combo-line-chart.json"></div>
|
|
53
53
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json"></div> -->
|
|
54
54
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json"></div> -->
|
|
55
55
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-with-confidence.json"></div> -->
|
|
56
56
|
<!-- <div class="react-container" data-config="/examples/gallery/bar-chart-vertical/vertical-bar-chart.json"></div> -->
|
|
57
|
+
<!-- <div class="react-container" data-config="/examples/box-plot.json"></div> -->
|
|
57
58
|
|
|
58
59
|
<!-- LOLLIPOP CHARTS -->
|
|
59
60
|
<!-- <div class="react-container" data-config="/examples/gallery/lollipop/lollipop-style-horizontal.json"></div> -->
|
|
@@ -62,6 +63,5 @@
|
|
|
62
63
|
<!-- <div class="react-container" data-config="/examples/gallery/paired-bar/paired-bar-chart.json"></div> -->
|
|
63
64
|
|
|
64
65
|
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
65
|
-
</body>
|
|
66
|
-
|
|
66
|
+
</body>
|
|
67
67
|
</html>
|
package/src/index.tsx
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
|
-
import { publish, subscribe } from '@cdc/core/helpers/events'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import { render } from 'react-dom'
|
|
1
|
+
import { publish, subscribe } from '@cdc/core/helpers/events'
|
|
2
|
+
import React from 'react'
|
|
3
|
+
import { render } from 'react-dom'
|
|
4
4
|
|
|
5
|
-
import CdcChart from './CdcChart'
|
|
5
|
+
import CdcChart from './CdcChart'
|
|
6
6
|
|
|
7
|
-
const domContainers = document.querySelectorAll('.react-container')
|
|
7
|
+
const domContainers = document.querySelectorAll('.react-container')
|
|
8
8
|
|
|
9
|
-
let isEditor = window.location.href.includes('editor=true')
|
|
9
|
+
let isEditor = window.location.href.includes('editor=true')
|
|
10
10
|
|
|
11
|
-
domContainers.forEach(
|
|
12
|
-
render(
|
|
11
|
+
domContainers.forEach(domContainer => {
|
|
12
|
+
render(
|
|
13
13
|
<React.StrictMode>
|
|
14
|
-
<CdcChart
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
domContainer,
|
|
20
|
-
);
|
|
21
|
-
});
|
|
14
|
+
<CdcChart configUrl={domContainer.attributes['data-config'].value} isEditor={isEditor} />
|
|
15
|
+
</React.StrictMode>,
|
|
16
|
+
domContainer
|
|
17
|
+
)
|
|
18
|
+
})
|
package/src/scss/DataTable.scss
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
@include breakpointClass(md) {
|
|
2
2
|
.data-table-container {
|
|
3
|
-
margin: 1em;
|
|
3
|
+
margin: 5px 1em;
|
|
4
4
|
}
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
.data-table-container {
|
|
8
8
|
.region-table {
|
|
9
9
|
display: table;
|
|
10
|
-
|
|
11
|
-
thead,
|
|
10
|
+
|
|
11
|
+
thead,
|
|
12
|
+
tbody {
|
|
12
13
|
display: table-row-group;
|
|
13
|
-
|
|
14
|
+
|
|
14
15
|
tr {
|
|
15
16
|
display: table-row;
|
|
16
17
|
|
|
@@ -20,4 +21,4 @@
|
|
|
20
21
|
}
|
|
21
22
|
}
|
|
22
23
|
}
|
|
23
|
-
}
|
|
24
|
+
}
|