@cdc/chart 4.23.1 → 4.23.2
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 +54532 -696
- package/examples/Barchart_with_negative.json +34 -0
- package/examples/box-plot.json +2 -2
- package/examples/dynamic-legends.json +1 -1
- package/examples/example-bar-chart-nonnumeric.json +36 -0
- package/examples/example-bar-chart.json +33 -0
- package/examples/example-combo-bar-nonnumeric.json +105 -0
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json +1 -1
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart.json +2 -2
- package/examples/gallery/paired-bar/paired-bar-chart.json +65 -13
- package/examples/line-chart-nonnumeric.json +32 -0
- package/examples/line-chart.json +21 -63
- package/examples/newdata.json +1 -1
- package/examples/planet-combo-example-config.json +143 -20
- package/examples/planet-example-data-nonnumeric.json +56 -0
- package/examples/planet-example-data.json +2 -2
- package/examples/planet-pie-example-config-nonnumeric.json +30 -0
- package/examples/scatterplot-continuous.csv +17 -0
- package/examples/scatterplot.json +136 -0
- package/examples/sparkline-chart-nonnumeric.json +76 -0
- package/examples/stacked-vertical-bar-example-negative.json +154 -0
- package/examples/stacked-vertical-bar-example-nonnumerics.json +154 -0
- package/index.html +74 -0
- package/package.json +29 -23
- package/src/{CdcChart.tsx → CdcChart.jsx} +74 -56
- package/src/components/{BarChart.tsx → BarChart.jsx} +99 -91
- package/src/components/BoxPlot.jsx +88 -0
- package/src/components/{DataTable.tsx → DataTable.jsx} +102 -25
- package/src/components/{EditorPanel.js → EditorPanel.jsx} +228 -14
- package/src/components/{Filters.js → Filters.jsx} +6 -12
- package/src/components/{Legend.js → Legend.jsx} +120 -108
- package/src/components/{LineChart.tsx → LineChart.jsx} +26 -12
- package/src/components/{LinearChart.tsx → LinearChart.jsx} +67 -47
- package/src/components/{PairedBarChart.tsx → PairedBarChart.jsx} +45 -78
- package/src/components/{PieChart.tsx → PieChart.jsx} +17 -32
- package/src/components/ScatterPlot.jsx +48 -0
- package/src/components/{SparkLine.js → SparkLine.jsx} +49 -18
- package/src/components/{useIntersectionObserver.tsx → useIntersectionObserver.jsx} +1 -1
- package/src/data/initial-state.js +33 -3
- package/src/hooks/{useColorPalette.ts → useColorPalette.js} +10 -28
- package/src/hooks/{useReduceData.ts → useReduceData.js} +25 -14
- package/src/hooks/useRightAxis.js +3 -1
- package/src/index.jsx +16 -0
- package/src/scss/DataTable.scss +22 -0
- package/src/scss/main.scss +30 -10
- package/vite.config.js +4 -0
- package/dist/495.js +0 -3
- package/dist/703.js +0 -1
- package/src/components/BoxPlot.js +0 -92
- package/src/index.html +0 -67
- package/src/index.tsx +0 -18
- /package/src/{context.tsx → ConfigContext.jsx} +0 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import React, { useContext } from 'react'
|
|
2
|
+
import ConfigContext from '../ConfigContext'
|
|
3
|
+
import { Group } from '@visx/group'
|
|
4
|
+
|
|
5
|
+
const CoveScatterPlot = ({ xScale, yScale, getXAxisData, getYAxisData }) => {
|
|
6
|
+
const { colorScale, transformedData: data, config } = useContext(ConfigContext)
|
|
7
|
+
|
|
8
|
+
// copied from line chart
|
|
9
|
+
// should probably be a constant somewhere.
|
|
10
|
+
let circleRadii = 4.5
|
|
11
|
+
|
|
12
|
+
let pointStyles = {
|
|
13
|
+
filter: 'unset',
|
|
14
|
+
opacity: 1,
|
|
15
|
+
stroke: 'black'
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const handleTooltip = (item, s) => `<div>
|
|
19
|
+
${config.xAxis.label}: ${item[config.xAxis.dataKey]} <br/>
|
|
20
|
+
${config.yAxis.label}: ${item[s]}
|
|
21
|
+
</div>`
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<Group className='scatter-plot' left={config.yAxis.size}>
|
|
25
|
+
{data.map((item, dataIndex) => {
|
|
26
|
+
// prettier-ignore
|
|
27
|
+
return config.runtime.seriesKeys.map(s => {
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<circle
|
|
31
|
+
key={`${dataIndex}`}
|
|
32
|
+
r={circleRadii}
|
|
33
|
+
cx={xScale(item[config.xAxis.dataKey])}
|
|
34
|
+
cy={yScale(item[s])}
|
|
35
|
+
fillOpacity={1}
|
|
36
|
+
opacity={1}
|
|
37
|
+
style={pointStyles}
|
|
38
|
+
fill={colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[s] : s) : '#000'}
|
|
39
|
+
data-tooltip-html={handleTooltip(item, s)}
|
|
40
|
+
data-tooltip-id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
|
|
41
|
+
/>
|
|
42
|
+
)
|
|
43
|
+
})
|
|
44
|
+
})}
|
|
45
|
+
</Group>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
48
|
+
export default CoveScatterPlot
|
|
@@ -10,16 +10,14 @@ import { MarkerArrow } from '@visx/marker'
|
|
|
10
10
|
|
|
11
11
|
import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
|
|
12
12
|
|
|
13
|
-
import ReactTooltip from 'react-tooltip'
|
|
14
|
-
|
|
15
13
|
import useReduceData from '../hooks/useReduceData'
|
|
16
14
|
|
|
17
|
-
import
|
|
15
|
+
import ConfigContext from '../ConfigContext'
|
|
18
16
|
|
|
19
17
|
export default function SparkLine({ width: parentWidth, height: parentHeight }) {
|
|
20
|
-
const { transformedData: data, dimensions, config, parseDate, formatDate, currentViewport, seriesHighlight, formatNumber, colorScale, handleChartAriaLabels } = useContext(
|
|
18
|
+
const { transformedData: data, dimensions, config, parseDate, formatDate, currentViewport, seriesHighlight, formatNumber, colorScale, isNumber, handleChartAriaLabels } = useContext(ConfigContext)
|
|
21
19
|
let width = parentWidth
|
|
22
|
-
const { minValue, maxValue } = useReduceData(config, data)
|
|
20
|
+
const { minValue, maxValue } = useReduceData(config, data, ConfigContext)
|
|
23
21
|
|
|
24
22
|
const margin = { top: 5, right: 10, bottom: 10, left: 10 }
|
|
25
23
|
const height = parentHeight
|
|
@@ -37,7 +35,44 @@ export default function SparkLine({ width: parentWidth, height: parentHeight })
|
|
|
37
35
|
const isMaxValid = Number(enteredMaxValue) >= Number(maxValue)
|
|
38
36
|
const isMinValid = Number(enteredMinValue) <= Number(minValue)
|
|
39
37
|
|
|
40
|
-
|
|
38
|
+
|
|
39
|
+
// REMOVE bad data points from the data set
|
|
40
|
+
// Examples: NA, N/A, "1,234", "anystring"
|
|
41
|
+
// - if you dont call this on data into LineGroup below, for example
|
|
42
|
+
// then entire data series are removed because of the defined statement
|
|
43
|
+
// i.e. if a series has any bad data points the entire series wont plot
|
|
44
|
+
const cleanData = (data, testing = false) => {
|
|
45
|
+
let cleanedup = []
|
|
46
|
+
if (testing) console.log('## Data to clean=', data)
|
|
47
|
+
data.forEach(function (d, i) {
|
|
48
|
+
let cleanedSeries = {}
|
|
49
|
+
Object.keys(d).forEach(function (key) {
|
|
50
|
+
if (key === 'Date') {
|
|
51
|
+
// pass thru the dates
|
|
52
|
+
cleanedSeries[key] = d[key]
|
|
53
|
+
} else {
|
|
54
|
+
// remove comma and dollar signs
|
|
55
|
+
let tmp = d[key] != null && d[key] != '' ? d[key].replace(/[,\$]/g, '') : ''
|
|
56
|
+
if (testing) console.log("tmp no comma or $", tmp)
|
|
57
|
+
if ((tmp !== '' && tmp !== null && !isNaN(tmp)) || (tmp !== '' && tmp !== null && /\d+\.?\d*/.test(tmp))) {
|
|
58
|
+
cleanedSeries[key] = tmp
|
|
59
|
+
} else {
|
|
60
|
+
// return nothing to skip bad data point
|
|
61
|
+
cleanedSeries[key] = '' // returning blank fixes broken chart draw
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
cleanedup.push(cleanedSeries)
|
|
66
|
+
})
|
|
67
|
+
if (testing) console.log('## cleanedData =', cleanedup)
|
|
68
|
+
return cleanedup
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Just do this once up front otherwise we end up
|
|
72
|
+
// calling clean several times on same set of data (TT)
|
|
73
|
+
const cleanedData = cleanData(data, config.xAxis.dataKey);
|
|
74
|
+
|
|
75
|
+
if (cleanedData) {
|
|
41
76
|
let min = enteredMinValue && isMinValid ? enteredMinValue : minValue
|
|
42
77
|
let max = enteredMaxValue && isMaxValid ? enteredMaxValue : Number.MIN_VALUE
|
|
43
78
|
|
|
@@ -52,7 +87,7 @@ export default function SparkLine({ width: parentWidth, height: parentHeight })
|
|
|
52
87
|
max += paddingValue
|
|
53
88
|
}
|
|
54
89
|
|
|
55
|
-
let xAxisDataMapped =
|
|
90
|
+
let xAxisDataMapped = cleanedData.map(d => getXAxisData(d))
|
|
56
91
|
|
|
57
92
|
if (config.runtime.horizontal) {
|
|
58
93
|
xScale = scaleLinear({
|
|
@@ -90,10 +125,6 @@ export default function SparkLine({ width: parentWidth, height: parentHeight })
|
|
|
90
125
|
|
|
91
126
|
const handleSparkLineTicks = [xScale.domain()[0], xScale.domain()[xScale.domain().length - 1]]
|
|
92
127
|
|
|
93
|
-
useEffect(() => {
|
|
94
|
-
ReactTooltip.rebuild()
|
|
95
|
-
})
|
|
96
|
-
|
|
97
128
|
return (
|
|
98
129
|
<ErrorBoundary component='SparkLine'>
|
|
99
130
|
<svg role='img' aria-label={handleChartAriaLabels(config)} width={width} height={height} className={'sparkline'} tabIndex={0}>
|
|
@@ -108,14 +139,14 @@ export default function SparkLine({ width: parentWidth, height: parentHeight })
|
|
|
108
139
|
opacity={config.legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(seriesKey) === -1 ? 0.5 : 1}
|
|
109
140
|
display={config.legend.behavior === 'highlight' || seriesHighlight.length === 0 || seriesHighlight.indexOf(seriesKey) !== -1 ? 'block' : 'none'}
|
|
110
141
|
>
|
|
111
|
-
{
|
|
142
|
+
{cleanedData.map((d, dataIndex) => {
|
|
112
143
|
let yAxisTooltip = config.runtime.yAxis.label ? `${config.runtime.yAxis.label}: ${formatNumber(getYAxisData(d, seriesKey))}` : formatNumber(getYAxisData(d, seriesKey))
|
|
113
144
|
let xAxisTooltip = config.runtime.xAxis.label ? `${config.runtime.xAxis.label}: ${d[config.runtime.xAxis.dataKey]}` : d[config.runtime.xAxis.dataKey]
|
|
114
145
|
|
|
115
146
|
const tooltip = `<div>
|
|
116
147
|
${yAxisTooltip}<br />
|
|
117
148
|
${xAxisTooltip}<br />
|
|
118
|
-
${config.seriesLabel ? `${config.seriesLabel}: ${seriesKey}` : ''}
|
|
149
|
+
${config.seriesLabel ? `${config.seriesLabel}: ${seriesKey}` : ''}
|
|
119
150
|
</div>`
|
|
120
151
|
|
|
121
152
|
let circleRadii = 4.5
|
|
@@ -133,8 +164,8 @@ export default function SparkLine({ width: parentWidth, height: parentHeight })
|
|
|
133
164
|
cy={yScale(getYAxisData(d, seriesKey))}
|
|
134
165
|
fill={colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000'}
|
|
135
166
|
style={{ fill: colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000' }}
|
|
136
|
-
data-
|
|
137
|
-
data-
|
|
167
|
+
data-tooltip-html={tooltip}
|
|
168
|
+
data-tooltip-id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
|
|
138
169
|
/>
|
|
139
170
|
)}
|
|
140
171
|
</Group>
|
|
@@ -142,20 +173,20 @@ export default function SparkLine({ width: parentWidth, height: parentHeight })
|
|
|
142
173
|
})}
|
|
143
174
|
<LinePath
|
|
144
175
|
curve={allCurves.curveLinear}
|
|
145
|
-
data={
|
|
176
|
+
data={cleanedData}
|
|
146
177
|
x={d => xScale(getXAxisData(d))}
|
|
147
178
|
y={d => yScale(getYAxisData(d, seriesKey))}
|
|
148
179
|
stroke={colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000'}
|
|
149
180
|
strokeWidth={2}
|
|
150
181
|
strokeOpacity={1}
|
|
151
182
|
shapeRendering='geometricPrecision'
|
|
152
|
-
|
|
183
|
+
markerEnd={`url(#${'arrow'}--${index})`}
|
|
153
184
|
/>
|
|
154
185
|
<MarkerArrow
|
|
155
186
|
id={`arrow--${index}`}
|
|
156
187
|
refX={2}
|
|
157
188
|
size={6}
|
|
158
|
-
|
|
189
|
+
markerEnd={`url(#${'arrow'}--${index})`}
|
|
159
190
|
strokeOpacity={1}
|
|
160
191
|
fillOpacity={1}
|
|
161
192
|
// stroke={colorScale ? colorScale(config.runtime.seriesLabels ? config.runtime.seriesLabels[seriesKey] : seriesKey) : '#000'}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { useEffect, useState } from 'react'
|
|
2
2
|
|
|
3
3
|
export default function useIntersectionObserver(elementRef, { threshold = 0, root = null, rootMargin = '0%', freezeOnceVisible = false }) {
|
|
4
|
-
const [entry, setEntry] = useState
|
|
4
|
+
const [entry, setEntry] = useState()
|
|
5
5
|
|
|
6
6
|
const frozen = entry?.isIntersecting && freezeOnceVisible
|
|
7
7
|
|
|
@@ -36,9 +36,38 @@ export default {
|
|
|
36
36
|
rightAxisLabelColor: '#333',
|
|
37
37
|
rightAxisTickLabelColor: '#333',
|
|
38
38
|
rightAxisTickColor: '#333',
|
|
39
|
-
numTicks: ''
|
|
39
|
+
numTicks: '',
|
|
40
|
+
axisPadding: 0,
|
|
41
|
+
tickRotation: 0
|
|
42
|
+
},
|
|
43
|
+
boxplot: {
|
|
44
|
+
plots: [],
|
|
45
|
+
borders: 'true',
|
|
46
|
+
firstQuartilePercentage: 25,
|
|
47
|
+
thirdQuartilePercentage: 75,
|
|
48
|
+
boxWidthPercentage: 40,
|
|
49
|
+
plotOutlierValues: false,
|
|
50
|
+
plotNonOutlierValues: true,
|
|
51
|
+
legend: {
|
|
52
|
+
showHowToReadText: false,
|
|
53
|
+
howToReadText: ''
|
|
54
|
+
},
|
|
55
|
+
labels: {
|
|
56
|
+
q1: 'Lower Quartile',
|
|
57
|
+
q2: 'q2',
|
|
58
|
+
q3: 'Upper Quartile',
|
|
59
|
+
q4: 'q4',
|
|
60
|
+
minimum: 'Minimum',
|
|
61
|
+
maximum: 'Maximum',
|
|
62
|
+
mean: 'Mean',
|
|
63
|
+
median: 'Median',
|
|
64
|
+
sd: 'Standard Deviation',
|
|
65
|
+
iqr: 'Interquartile Range',
|
|
66
|
+
count: 'Count',
|
|
67
|
+
outliers: 'Outliers',
|
|
68
|
+
values: 'Values'
|
|
69
|
+
}
|
|
40
70
|
},
|
|
41
|
-
boxplot: [],
|
|
42
71
|
topAxis: {
|
|
43
72
|
hasLine: false
|
|
44
73
|
},
|
|
@@ -63,7 +92,8 @@ export default {
|
|
|
63
92
|
tickLabelColor: '#333',
|
|
64
93
|
tickColor: '#333',
|
|
65
94
|
numTicks: '',
|
|
66
|
-
labelOffset: 65
|
|
95
|
+
labelOffset: 65,
|
|
96
|
+
axisPadding: 0
|
|
67
97
|
},
|
|
68
98
|
table: {
|
|
69
99
|
label: 'Data Table',
|
|
@@ -5,59 +5,41 @@ const SEQUENTIAL = 'SEQUENTIAL'
|
|
|
5
5
|
const SEQUENTIAL_REVERSE = 'SEQUENTIAL_REVERSE'
|
|
6
6
|
export const GET_PALETTE = 'GET_PALETTE'
|
|
7
7
|
|
|
8
|
-
// types & interfaces
|
|
9
|
-
interface State {
|
|
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
|
-
}
|
|
20
|
-
|
|
21
8
|
// create initial state
|
|
22
|
-
const initialState
|
|
9
|
+
const initialState = {
|
|
23
10
|
filteredPallets: [],
|
|
24
11
|
isPaletteReversed: false,
|
|
25
12
|
filteredQualitative: [],
|
|
26
13
|
paletteName: undefined
|
|
27
14
|
}
|
|
28
15
|
|
|
29
|
-
function reducer
|
|
30
|
-
//
|
|
31
|
-
|
|
32
|
-
let paletteName: string = ''
|
|
16
|
+
function reducer(state, action) {
|
|
17
|
+
const palletNamesArr = Object.keys(action.payload) // action.payload === colorPalettes object
|
|
18
|
+
let paletteName = ''
|
|
33
19
|
switch (action.type) {
|
|
34
20
|
case GET_PALETTE:
|
|
35
21
|
return { ...state, paletteName: action.paletteName }
|
|
36
22
|
case SEQUENTIAL:
|
|
37
23
|
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
|
|
39
|
-
const sequential = palletNamesArr.filter((name
|
|
24
|
+
const qualitative = palletNamesArr.filter((name) => String(name).startsWith('qualitative') && !String(name).endsWith('reverse'))
|
|
25
|
+
const sequential = palletNamesArr.filter((name) => String(name).startsWith('sequential') && !String(name).endsWith('reverse'))
|
|
40
26
|
return { ...state, filteredPallets: sequential, filteredQualitative: qualitative, paletteName: paletteName, isPaletteReversed: false }
|
|
41
27
|
|
|
42
28
|
case SEQUENTIAL_REVERSE:
|
|
43
|
-
paletteName = palletNamesArr.find((name
|
|
44
|
-
const qualitativeReverse
|
|
45
|
-
const sequentialReverse
|
|
29
|
+
paletteName = palletNamesArr.find((name) => name === String(state.paletteName).concat('reverse') || name === String(state.paletteName).concat('-reverse'))
|
|
30
|
+
const qualitativeReverse = palletNamesArr.filter((name) => String(name).startsWith('qualitative') && String(name).endsWith('reverse'))
|
|
31
|
+
const sequentialReverse = palletNamesArr.filter((name) => String(name).startsWith('sequential') && String(name).endsWith('reverse'))
|
|
46
32
|
return { ...state, filteredQualitative: qualitativeReverse, filteredPallets: sequentialReverse, paletteName: paletteName, isPaletteReversed: true }
|
|
47
33
|
default:
|
|
48
34
|
return state
|
|
49
35
|
}
|
|
50
36
|
}
|
|
51
37
|
|
|
52
|
-
interface Keyable {
|
|
53
|
-
palette: string
|
|
54
|
-
isPaletteReversed: boolean
|
|
55
|
-
}
|
|
56
38
|
function init(initialState) {
|
|
57
39
|
return initialState
|
|
58
40
|
}
|
|
59
41
|
|
|
60
|
-
export function useColorPalette
|
|
42
|
+
export function useColorPalette(colorPalettes, configState) {
|
|
61
43
|
const [state, dispatch] = useReducer(reducer, initialState, init)
|
|
62
44
|
const { paletteName, isPaletteReversed, filteredPallets, filteredQualitative } = state
|
|
63
45
|
|
|
@@ -1,12 +1,24 @@
|
|
|
1
|
+
import isNumber from '@cdc/core/helpers/isNumber'
|
|
2
|
+
|
|
1
3
|
function useReduceData(config, data) {
|
|
2
4
|
// for combo charts check if all Data Series selected to Bar;
|
|
3
5
|
const isBar = config?.series?.every(element => element?.type === 'Bar')
|
|
4
6
|
// 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')
|
|
6
|
-
|
|
7
|
+
const isAllLine = config?.series?.every(el => el.type === 'Line' || el.type === 'dashed-sm' || el.type === 'dashed-md' || el.type === 'dashed-lg')
|
|
8
|
+
const cleanChars = value => {
|
|
9
|
+
// remove comma and $ signs
|
|
10
|
+
let tmp
|
|
11
|
+
if (typeof value === 'string') {
|
|
12
|
+
tmp = value !== null && value !== '' ? value.replace(/[,\$]/g, '') : ''
|
|
13
|
+
} else {
|
|
14
|
+
tmp = value !== null && value !== '' ? value : ''
|
|
15
|
+
}
|
|
16
|
+
return tmp
|
|
17
|
+
}
|
|
7
18
|
const getMaxValueFromData = () => {
|
|
8
19
|
let max // will hold max number from data.
|
|
9
20
|
if ((config.visualizationType === 'Bar' || (config.visualizationType === 'Combo' && isBar)) && config.visualizationSubType === 'stacked') {
|
|
21
|
+
|
|
10
22
|
const yTotals = data.reduce((allTotals, xValue) => {
|
|
11
23
|
const totalYValues = config.runtime.seriesKeys.reduce((yTotal, k) => {
|
|
12
24
|
yTotal += Number(xValue[k])
|
|
@@ -18,11 +30,12 @@ function useReduceData(config, data) {
|
|
|
18
30
|
max = totalYValues
|
|
19
31
|
}
|
|
20
32
|
return allTotals
|
|
21
|
-
}, []
|
|
33
|
+
}, [])
|
|
22
34
|
|
|
23
35
|
max = Math.max(...yTotals)
|
|
24
36
|
} else if (config.visualizationType === 'Bar' && config.series && config.series.dataKey) {
|
|
25
|
-
max = Math.max(...data.map(d => Number(d[config.series.dataKey])))
|
|
37
|
+
max = Math.max(...data.map(d => (isNumber(d[config.series.dataKey]) ? Number(cleanChars(d[config.series.dataKey])) : 0)))
|
|
38
|
+
//max = Math.max(...data.map(d => Number(d[config.series.dataKey])))
|
|
26
39
|
} else if (config.visualizationType === 'Combo' && config.visualizationSubType === 'stacked' && !isBar) {
|
|
27
40
|
let total = []
|
|
28
41
|
|
|
@@ -36,28 +49,26 @@ function useReduceData(config, data) {
|
|
|
36
49
|
total.push(totalYValues)
|
|
37
50
|
})
|
|
38
51
|
// get lineSeries largest values
|
|
39
|
-
const lineMax = Math.max(...data.map(d => Math.max(...config.runtime.lineSeriesKeys.map(key => Number(d[key])))))
|
|
52
|
+
const lineMax = Math.max(...data.map(d => Math.max(...config.runtime.lineSeriesKeys.map(key => Number(cleanChars(d[key]))))))
|
|
40
53
|
|
|
41
54
|
const barMax = Math.max(...total)
|
|
42
55
|
|
|
43
56
|
max = Number(barMax) > Number(lineMax) ? barMax : lineMax
|
|
44
57
|
}
|
|
45
58
|
} else {
|
|
46
|
-
max = Math.max(...data.map(d => Math.max(...config.runtime.seriesKeys.map(key => Number(d[key])))))
|
|
59
|
+
max = Math.max(...data.map(d => Math.max(...config.runtime.seriesKeys.map(key => (isNumber(d[key]) ? Number(cleanChars(d[key])) : 0)))))
|
|
47
60
|
}
|
|
48
|
-
|
|
49
61
|
return max
|
|
50
62
|
}
|
|
51
63
|
|
|
52
64
|
const getMinValueFromData = () => {
|
|
53
65
|
let min
|
|
54
|
-
const minNumberFromData = Math.min(...data.map(d => Math.min(...config.runtime.seriesKeys.map(key => Number(d[key])))))
|
|
66
|
+
const minNumberFromData = Math.min(...data.map(d => Math.min(...config.runtime.seriesKeys.map(key => (isNumber(d[key]) ? Number(cleanChars(d[key])) : 1000000000)))))
|
|
55
67
|
min = String(minNumberFromData)
|
|
56
|
-
|
|
57
68
|
return min
|
|
58
69
|
}
|
|
59
70
|
|
|
60
|
-
const findPositiveNum = ()
|
|
71
|
+
const findPositiveNum = () => {
|
|
61
72
|
// loop throught provided data to find positve number in arr based on series keys.
|
|
62
73
|
let existPositiveValue = false
|
|
63
74
|
if (config.runtime.seriesKeys) {
|
|
@@ -68,11 +79,11 @@ function useReduceData(config, data) {
|
|
|
68
79
|
return existPositiveValue
|
|
69
80
|
}
|
|
70
81
|
|
|
71
|
-
const maxValue = Number(getMaxValueFromData())
|
|
72
|
-
const minValue = Number(getMinValueFromData())
|
|
73
|
-
const existPositiveValue = findPositiveNum()
|
|
82
|
+
const maxValue = Number(getMaxValueFromData())
|
|
83
|
+
const minValue = Number(getMinValueFromData())
|
|
84
|
+
const existPositiveValue = findPositiveNum()
|
|
74
85
|
|
|
75
|
-
return {minValue, maxValue, existPositiveValue
|
|
86
|
+
return { minValue, maxValue, existPositiveValue, isAllLine }
|
|
76
87
|
}
|
|
77
88
|
|
|
78
89
|
export default useReduceData
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { scaleLinear } from '@visx/scale'
|
|
2
|
+
import useReduceData from '../hooks/useReduceData'
|
|
2
3
|
|
|
3
4
|
export default function useRightAxis({ config, yMax = 0, data = [], updateConfig }) {
|
|
4
5
|
const hasRightAxis = config.visualizationType === 'Combo' && config.orientation === 'vertical'
|
|
5
6
|
const rightSeriesKeys = config.series && config.series.filter(series => series.axis === 'Right').map(key => key.dataKey)
|
|
7
|
+
const { minValue } = useReduceData(config, data)
|
|
6
8
|
|
|
7
9
|
const allRightAxisData = rightSeriesKeys => {
|
|
8
10
|
if (!rightSeriesKeys) return [0]
|
|
@@ -17,7 +19,7 @@ export default function useRightAxis({ config, yMax = 0, data = [], updateConfig
|
|
|
17
19
|
const max = Math.max.apply(null, allRightAxisData(rightSeriesKeys))
|
|
18
20
|
|
|
19
21
|
const yScaleRight = scaleLinear({
|
|
20
|
-
domain: [
|
|
22
|
+
domain: [minValue, max],
|
|
21
23
|
range: [yMax, 0]
|
|
22
24
|
})
|
|
23
25
|
|
package/src/index.jsx
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import ReactDOM from 'react-dom/client'
|
|
3
|
+
|
|
4
|
+
import CdcChart from './CdcChart'
|
|
5
|
+
|
|
6
|
+
import 'react-tooltip/dist/react-tooltip.css'
|
|
7
|
+
|
|
8
|
+
let isEditor = window.location.href.includes('editor=true')
|
|
9
|
+
|
|
10
|
+
let domContainer = document.getElementsByClassName('react-container')[0]
|
|
11
|
+
|
|
12
|
+
ReactDOM.createRoot(domContainer).render(
|
|
13
|
+
<React.StrictMode>
|
|
14
|
+
<CdcChart configUrl={domContainer.attributes['data-config'].value} isEditor={isEditor} />
|
|
15
|
+
</React.StrictMode>,
|
|
16
|
+
)
|
package/src/scss/DataTable.scss
CHANGED
|
@@ -5,6 +5,28 @@
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
.data-table-container {
|
|
8
|
+
// Hides Category Column
|
|
9
|
+
.row-Box-Plot--0 {
|
|
10
|
+
display: none !important;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Highlight Boxplot 5 Number Summary
|
|
14
|
+
.row-Box-Plot--1 > td:first-child,
|
|
15
|
+
.row-Box-Plot--2 > td:first-child,
|
|
16
|
+
.row-Box-Plot--3 > td:first-child,
|
|
17
|
+
.row-Box-Plot--4 > td:first-child,
|
|
18
|
+
.row-Box-Plot--5 > td:first-child {
|
|
19
|
+
background-color: #ffe699;
|
|
20
|
+
}
|
|
21
|
+
// Highlight Boxplot Measures
|
|
22
|
+
.row-Box-Plot--6 > td:first-child,
|
|
23
|
+
.row-Box-Plot--7 > td:first-child,
|
|
24
|
+
.row-Box-Plot--8 > td:first-child,
|
|
25
|
+
.row-Box-Plot--9 > td:first-child,
|
|
26
|
+
.row-Box-Plot--10 > td:first-child,
|
|
27
|
+
.row-Box-Plot--11 > td:first-child {
|
|
28
|
+
background-color: #d9d9d9;
|
|
29
|
+
}
|
|
8
30
|
.region-table {
|
|
9
31
|
display: table;
|
|
10
32
|
|
package/src/scss/main.scss
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
@import '
|
|
2
|
-
@import '
|
|
1
|
+
@import '@cdc/core/styles/base';
|
|
2
|
+
@import '@cdc/core/styles/heading-colors';
|
|
3
3
|
@import 'mixins';
|
|
4
4
|
@import 'variables';
|
|
5
|
-
@import '
|
|
5
|
+
@import '@cdc/core/styles/v2/themes/color-definitions';
|
|
6
6
|
|
|
7
7
|
.form-container {
|
|
8
8
|
overflow-y: auto;
|
|
@@ -232,14 +232,20 @@
|
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
.tooltip {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
box-shadow: rgba(0, 0, 0, 0.1) 3px 3px 7px;
|
|
238
|
-
line-height: 1.4em;
|
|
239
|
-
font-size: 1em !important;
|
|
240
|
-
border-radius: 4px !important;
|
|
241
|
-
padding: 8px 12px !important;
|
|
235
|
+
border: rgba(0,0,0,.3) 1px solid;
|
|
236
|
+
box-shadow: rgba(0,0,0,.1) 3px 3px 7px;
|
|
242
237
|
opacity: 1;
|
|
238
|
+
line-height: 1.4em;
|
|
239
|
+
font-size: 1em;
|
|
240
|
+
border-radius: 4px;
|
|
241
|
+
padding: 8px 12px;
|
|
242
|
+
z-index: 1;
|
|
243
|
+
|
|
244
|
+
.react-tooltip-arrow {
|
|
245
|
+
border-bottom: rgba(0,0,0,.3) 1px solid;
|
|
246
|
+
border-right: rgba(0,0,0,.3) 1px solid;
|
|
247
|
+
backface-visibility: hidden;
|
|
248
|
+
}
|
|
243
249
|
}
|
|
244
250
|
|
|
245
251
|
.region-table {
|
|
@@ -557,6 +563,7 @@
|
|
|
557
563
|
|
|
558
564
|
.horizontal rect,
|
|
559
565
|
.horizontal foreignObject {
|
|
566
|
+
opacity: 0;
|
|
560
567
|
animation: growBarH 0.5s linear forwards;
|
|
561
568
|
animation-play-state: paused;
|
|
562
569
|
}
|
|
@@ -593,13 +600,26 @@
|
|
|
593
600
|
|
|
594
601
|
@keyframes growBarH {
|
|
595
602
|
from {
|
|
603
|
+
opacity: 1;
|
|
596
604
|
transform: scale(0, 1);
|
|
597
605
|
}
|
|
598
606
|
|
|
599
607
|
to {
|
|
608
|
+
opacity: 1;
|
|
600
609
|
transform: scale(1);
|
|
601
610
|
}
|
|
602
611
|
}
|
|
612
|
+
|
|
613
|
+
.fieldset--boxplot {
|
|
614
|
+
padding: 10px;
|
|
615
|
+
border-radius: 5px;
|
|
616
|
+
border: 2px solid rgba(0, 0, 0, 0.2);
|
|
617
|
+
padding: 10px;
|
|
618
|
+
|
|
619
|
+
label {
|
|
620
|
+
margin: 5px 0;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
603
623
|
}
|
|
604
624
|
|
|
605
625
|
.cdc-visualization__paired-bar-chart {
|
package/vite.config.js
ADDED
package/dist/495.js
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
(self.webpackChunkCdcChart=self.webpackChunkCdcChart||[]).push([[495],{16478:function(e){
|
|
2
|
-
/*! @license DOMPurify 2.4.1 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/2.4.1/LICENSE */
|
|
3
|
-
e.exports=function(){"use strict";function e(t){return e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},e(t)}function t(e,n){return t=Object.setPrototypeOf||function(e,t){return e.__proto__=t,e},t(e,n)}function n(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function r(e,o,a){return r=n()?Reflect.construct:function(e,n,r){var o=[null];o.push.apply(o,n);var a=new(Function.bind.apply(e,o));return r&&t(a,r.prototype),a},r.apply(null,arguments)}function o(e){return a(e)||i(e)||l(e)||u()}function a(e){if(Array.isArray(e))return c(e)}function i(e){if("undefined"!=typeof Symbol&&null!=e[Symbol.iterator]||null!=e["@@iterator"])return Array.from(e)}function l(e,t){if(e){if("string"==typeof e)return c(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?c(e,t):void 0}}function c(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n<t;n++)r[n]=e[n];return r}function u(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var s=Object.hasOwnProperty,m=Object.setPrototypeOf,f=Object.isFrozen,p=Object.getPrototypeOf,d=Object.getOwnPropertyDescriptor,h=Object.freeze,g=Object.seal,y=Object.create,b="undefined"!=typeof Reflect&&Reflect,v=b.apply,T=b.construct;v||(v=function(e,t,n){return e.apply(t,n)}),h||(h=function(e){return e}),g||(g=function(e){return e}),T||(T=function(e,t){return r(e,o(t))});var N=L(Array.prototype.forEach),A=L(Array.prototype.pop),E=L(Array.prototype.push),w=L(String.prototype.toLowerCase),S=L(String.prototype.toString),k=L(String.prototype.match),x=L(String.prototype.replace),_=L(String.prototype.indexOf),C=L(String.prototype.trim),O=L(RegExp.prototype.test),D=R(TypeError);function L(e){return function(t){for(var n=arguments.length,r=new Array(n>1?n-1:0),o=1;o<n;o++)r[o-1]=arguments[o];return v(e,t,r)}}function R(e){return function(){for(var t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];return T(e,n)}}function M(e,t,n){n=n||w,m&&m(e,null);for(var r=t.length;r--;){var o=t[r];if("string"==typeof o){var a=n(o);a!==o&&(f(t)||(t[r]=a),o=a)}e[o]=!0}return e}function I(e){var t,n=y(null);for(t in e)v(s,e,[t])&&(n[t]=e[t]);return n}function F(e,t){for(;null!==e;){var n=d(e,t);if(n){if(n.get)return L(n.get);if("function"==typeof n.value)return L(n.value)}e=p(e)}function r(e){return console.warn("fallback value for",e),null}return r}var U=h(["a","abbr","acronym","address","area","article","aside","audio","b","bdi","bdo","big","blink","blockquote","body","br","button","canvas","caption","center","cite","code","col","colgroup","content","data","datalist","dd","decorator","del","details","dfn","dialog","dir","div","dl","dt","element","em","fieldset","figcaption","figure","font","footer","form","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","i","img","input","ins","kbd","label","legend","li","main","map","mark","marquee","menu","menuitem","meter","nav","nobr","ol","optgroup","option","output","p","picture","pre","progress","q","rp","rt","ruby","s","samp","section","select","shadow","small","source","spacer","span","strike","strong","style","sub","summary","sup","table","tbody","td","template","textarea","tfoot","th","thead","time","tr","track","tt","u","ul","var","video","wbr"]),H=h(["svg","a","altglyph","altglyphdef","altglyphitem","animatecolor","animatemotion","animatetransform","circle","clippath","defs","desc","ellipse","filter","font","g","glyph","glyphref","hkern","image","line","lineargradient","marker","mask","metadata","mpath","path","pattern","polygon","polyline","radialgradient","rect","stop","style","switch","symbol","text","textpath","title","tref","tspan","view","vkern"]),z=h(["feBlend","feColorMatrix","feComponentTransfer","feComposite","feConvolveMatrix","feDiffuseLighting","feDisplacementMap","feDistantLight","feFlood","feFuncA","feFuncB","feFuncG","feFuncR","feGaussianBlur","feImage","feMerge","feMergeNode","feMorphology","feOffset","fePointLight","feSpecularLighting","feSpotLight","feTile","feTurbulence"]),P=h(["animate","color-profile","cursor","discard","fedropshadow","font-face","font-face-format","font-face-name","font-face-src","font-face-uri","foreignobject","hatch","hatchpath","mesh","meshgradient","meshpatch","meshrow","missing-glyph","script","set","solidcolor","unknown","use"]),B=h(["math","menclose","merror","mfenced","mfrac","mglyph","mi","mlabeledtr","mmultiscripts","mn","mo","mover","mpadded","mphantom","mroot","mrow","ms","mspace","msqrt","mstyle","msub","msup","msubsup","mtable","mtd","mtext","mtr","munder","munderover"]),j=h(["maction","maligngroup","malignmark","mlongdiv","mscarries","mscarry","msgroup","mstack","msline","msrow","semantics","annotation","annotation-xml","mprescripts","none"]),G=h(["#text"]),W=h(["accept","action","align","alt","autocapitalize","autocomplete","autopictureinpicture","autoplay","background","bgcolor","border","capture","cellpadding","cellspacing","checked","cite","class","clear","color","cols","colspan","controls","controlslist","coords","crossorigin","datetime","decoding","default","dir","disabled","disablepictureinpicture","disableremoteplayback","download","draggable","enctype","enterkeyhint","face","for","headers","height","hidden","high","href","hreflang","id","inputmode","integrity","ismap","kind","label","lang","list","loading","loop","low","max","maxlength","media","method","min","minlength","multiple","muted","name","nonce","noshade","novalidate","nowrap","open","optimum","pattern","placeholder","playsinline","poster","preload","pubdate","radiogroup","readonly","rel","required","rev","reversed","role","rows","rowspan","spellcheck","scope","selected","shape","size","sizes","span","srclang","start","src","srcset","step","style","summary","tabindex","title","translate","type","usemap","valign","value","width","xmlns","slot"]),q=h(["accent-height","accumulate","additive","alignment-baseline","ascent","attributename","attributetype","azimuth","basefrequency","baseline-shift","begin","bias","by","class","clip","clippathunits","clip-path","clip-rule","color","color-interpolation","color-interpolation-filters","color-profile","color-rendering","cx","cy","d","dx","dy","diffuseconstant","direction","display","divisor","dur","edgemode","elevation","end","fill","fill-opacity","fill-rule","filter","filterunits","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","fx","fy","g1","g2","glyph-name","glyphref","gradientunits","gradienttransform","height","href","id","image-rendering","in","in2","k","k1","k2","k3","k4","kerning","keypoints","keysplines","keytimes","lang","lengthadjust","letter-spacing","kernelmatrix","kernelunitlength","lighting-color","local","marker-end","marker-mid","marker-start","markerheight","markerunits","markerwidth","maskcontentunits","maskunits","max","mask","media","method","mode","min","name","numoctaves","offset","operator","opacity","order","orient","orientation","origin","overflow","paint-order","path","pathlength","patterncontentunits","patterntransform","patternunits","points","preservealpha","preserveaspectratio","primitiveunits","r","rx","ry","radius","refx","refy","repeatcount","repeatdur","restart","result","rotate","scale","seed","shape-rendering","specularconstant","specularexponent","spreadmethod","startoffset","stddeviation","stitchtiles","stop-color","stop-opacity","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke","stroke-width","style","surfacescale","systemlanguage","tabindex","targetx","targety","transform","transform-origin","text-anchor","text-decoration","text-rendering","textlength","type","u1","u2","unicode","values","viewbox","visibility","version","vert-adv-y","vert-origin-x","vert-origin-y","width","word-spacing","wrap","writing-mode","xchannelselector","ychannelselector","x","x1","x2","xmlns","y","y1","y2","z","zoomandpan"]),Y=h(["accent","accentunder","align","bevelled","close","columnsalign","columnlines","columnspan","denomalign","depth","dir","display","displaystyle","encoding","fence","frame","height","href","id","largeop","length","linethickness","lspace","lquote","mathbackground","mathcolor","mathsize","mathvariant","maxsize","minsize","movablelimits","notation","numalign","open","rowalign","rowlines","rowspacing","rowspan","rspace","rquote","scriptlevel","scriptminsize","scriptsizemultiplier","selection","separator","separators","stretchy","subscriptshift","supscriptshift","symmetric","voffset","width","xmlns"]),$=h(["xlink:href","xml:id","xlink:title","xml:space","xmlns:xlink"]),K=g(/\{\{[\w\W]*|[\w\W]*\}\}/gm),V=g(/<%[\w\W]*|[\w\W]*%>/gm),X=g(/\${[\w\W]*}/gm),Z=g(/^data-[\-\w.\u00B7-\uFFFF]/),J=g(/^aria-[\-\w]+$/),Q=g(/^(?:(?:(?:f|ht)tps?|mailto|tel|callto|cid|xmpp):|[^a-z]|[a-z+.\-]+(?:[^a-z+.\-:]|$))/i),ee=g(/^(?:\w+script|data):/i),te=g(/[\u0000-\u0020\u00A0\u1680\u180E\u2000-\u2029\u205F\u3000]/g),ne=g(/^html$/i),re=function(){return"undefined"==typeof window?null:window},oe=function(t,n){if("object"!==e(t)||"function"!=typeof t.createPolicy)return null;var r=null,o="data-tt-policy-suffix";n.currentScript&&n.currentScript.hasAttribute(o)&&(r=n.currentScript.getAttribute(o));var a="dompurify"+(r?"#"+r:"");try{return t.createPolicy(a,{createHTML:function(e){return e},createScriptURL:function(e){return e}})}catch(e){return console.warn("TrustedTypes policy "+a+" could not be created."),null}};function ae(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:re(),n=function(e){return ae(e)};if(n.version="2.4.1",n.removed=[],!t||!t.document||9!==t.document.nodeType)return n.isSupported=!1,n;var r=t.document,a=t.document,i=t.DocumentFragment,l=t.HTMLTemplateElement,c=t.Node,u=t.Element,s=t.NodeFilter,m=t.NamedNodeMap,f=void 0===m?t.NamedNodeMap||t.MozNamedAttrMap:m,p=t.HTMLFormElement,d=t.DOMParser,g=t.trustedTypes,y=u.prototype,b=F(y,"cloneNode"),v=F(y,"nextSibling"),T=F(y,"childNodes"),L=F(y,"parentNode");if("function"==typeof l){var R=a.createElement("template");R.content&&R.content.ownerDocument&&(a=R.content.ownerDocument)}var ie=oe(g,r),le=ie?ie.createHTML(""):"",ce=a,ue=ce.implementation,se=ce.createNodeIterator,me=ce.createDocumentFragment,fe=ce.getElementsByTagName,pe=r.importNode,de={};try{de=I(a).documentMode?a.documentMode:{}}catch(e){}var he={};n.isSupported="function"==typeof L&&ue&&void 0!==ue.createHTMLDocument&&9!==de;var ge,ye,be=K,ve=V,Te=X,Ne=Z,Ae=J,Ee=ee,we=te,Se=Q,ke=null,xe=M({},[].concat(o(U),o(H),o(z),o(B),o(G))),_e=null,Ce=M({},[].concat(o(W),o(q),o(Y),o($))),Oe=Object.seal(Object.create(null,{tagNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},attributeNameCheck:{writable:!0,configurable:!1,enumerable:!0,value:null},allowCustomizedBuiltInElements:{writable:!0,configurable:!1,enumerable:!0,value:!1}})),De=null,Le=null,Re=!0,Me=!0,Ie=!1,Fe=!1,Ue=!1,He=!1,ze=!1,Pe=!1,Be=!1,je=!1,Ge=!0,We=!1,qe="user-content-",Ye=!0,$e=!1,Ke={},Ve=null,Xe=M({},["annotation-xml","audio","colgroup","desc","foreignobject","head","iframe","math","mi","mn","mo","ms","mtext","noembed","noframes","noscript","plaintext","script","style","svg","template","thead","title","video","xmp"]),Ze=null,Je=M({},["audio","video","img","source","image","track"]),Qe=null,et=M({},["alt","class","for","id","label","name","pattern","placeholder","role","summary","title","value","style","xmlns"]),tt="http://www.w3.org/1998/Math/MathML",nt="http://www.w3.org/2000/svg",rt="http://www.w3.org/1999/xhtml",ot=rt,at=!1,it=null,lt=M({},[tt,nt,rt],S),ct=["application/xhtml+xml","text/html"],ut="text/html",st=null,mt=a.createElement("form"),ft=function(e){return e instanceof RegExp||e instanceof Function},pt=function(t){st&&st===t||(t&&"object"===e(t)||(t={}),t=I(t),ge=ge=-1===ct.indexOf(t.PARSER_MEDIA_TYPE)?ut:t.PARSER_MEDIA_TYPE,ye="application/xhtml+xml"===ge?S:w,ke="ALLOWED_TAGS"in t?M({},t.ALLOWED_TAGS,ye):xe,_e="ALLOWED_ATTR"in t?M({},t.ALLOWED_ATTR,ye):Ce,it="ALLOWED_NAMESPACES"in t?M({},t.ALLOWED_NAMESPACES,S):lt,Qe="ADD_URI_SAFE_ATTR"in t?M(I(et),t.ADD_URI_SAFE_ATTR,ye):et,Ze="ADD_DATA_URI_TAGS"in t?M(I(Je),t.ADD_DATA_URI_TAGS,ye):Je,Ve="FORBID_CONTENTS"in t?M({},t.FORBID_CONTENTS,ye):Xe,De="FORBID_TAGS"in t?M({},t.FORBID_TAGS,ye):{},Le="FORBID_ATTR"in t?M({},t.FORBID_ATTR,ye):{},Ke="USE_PROFILES"in t&&t.USE_PROFILES,Re=!1!==t.ALLOW_ARIA_ATTR,Me=!1!==t.ALLOW_DATA_ATTR,Ie=t.ALLOW_UNKNOWN_PROTOCOLS||!1,Fe=t.SAFE_FOR_TEMPLATES||!1,Ue=t.WHOLE_DOCUMENT||!1,Pe=t.RETURN_DOM||!1,Be=t.RETURN_DOM_FRAGMENT||!1,je=t.RETURN_TRUSTED_TYPE||!1,ze=t.FORCE_BODY||!1,Ge=!1!==t.SANITIZE_DOM,We=t.SANITIZE_NAMED_PROPS||!1,Ye=!1!==t.KEEP_CONTENT,$e=t.IN_PLACE||!1,Se=t.ALLOWED_URI_REGEXP||Se,ot=t.NAMESPACE||rt,t.CUSTOM_ELEMENT_HANDLING&&ft(t.CUSTOM_ELEMENT_HANDLING.tagNameCheck)&&(Oe.tagNameCheck=t.CUSTOM_ELEMENT_HANDLING.tagNameCheck),t.CUSTOM_ELEMENT_HANDLING&&ft(t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck)&&(Oe.attributeNameCheck=t.CUSTOM_ELEMENT_HANDLING.attributeNameCheck),t.CUSTOM_ELEMENT_HANDLING&&"boolean"==typeof t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements&&(Oe.allowCustomizedBuiltInElements=t.CUSTOM_ELEMENT_HANDLING.allowCustomizedBuiltInElements),Fe&&(Me=!1),Be&&(Pe=!0),Ke&&(ke=M({},o(G)),_e=[],!0===Ke.html&&(M(ke,U),M(_e,W)),!0===Ke.svg&&(M(ke,H),M(_e,q),M(_e,$)),!0===Ke.svgFilters&&(M(ke,z),M(_e,q),M(_e,$)),!0===Ke.mathMl&&(M(ke,B),M(_e,Y),M(_e,$))),t.ADD_TAGS&&(ke===xe&&(ke=I(ke)),M(ke,t.ADD_TAGS,ye)),t.ADD_ATTR&&(_e===Ce&&(_e=I(_e)),M(_e,t.ADD_ATTR,ye)),t.ADD_URI_SAFE_ATTR&&M(Qe,t.ADD_URI_SAFE_ATTR,ye),t.FORBID_CONTENTS&&(Ve===Xe&&(Ve=I(Ve)),M(Ve,t.FORBID_CONTENTS,ye)),Ye&&(ke["#text"]=!0),Ue&&M(ke,["html","head","body"]),ke.table&&(M(ke,["tbody"]),delete De.tbody),h&&h(t),st=t)},dt=M({},["mi","mo","mn","ms","mtext"]),ht=M({},["foreignobject","desc","title","annotation-xml"]),gt=M({},["title","style","font","a","script"]),yt=M({},H);M(yt,z),M(yt,P);var bt=M({},B);M(bt,j);var vt=function(e){var t=L(e);t&&t.tagName||(t={namespaceURI:ot,tagName:"template"});var n=w(e.tagName),r=w(t.tagName);return!!it[e.namespaceURI]&&(e.namespaceURI===nt?t.namespaceURI===rt?"svg"===n:t.namespaceURI===tt?"svg"===n&&("annotation-xml"===r||dt[r]):Boolean(yt[n]):e.namespaceURI===tt?t.namespaceURI===rt?"math"===n:t.namespaceURI===nt?"math"===n&&ht[r]:Boolean(bt[n]):e.namespaceURI===rt?!(t.namespaceURI===nt&&!ht[r])&&!(t.namespaceURI===tt&&!dt[r])&&!bt[n]&&(gt[n]||!yt[n]):!("application/xhtml+xml"!==ge||!it[e.namespaceURI]))},Tt=function(e){E(n.removed,{element:e});try{e.parentNode.removeChild(e)}catch(t){try{e.outerHTML=le}catch(t){e.remove()}}},Nt=function(e,t){try{E(n.removed,{attribute:t.getAttributeNode(e),from:t})}catch(e){E(n.removed,{attribute:null,from:t})}if(t.removeAttribute(e),"is"===e&&!_e[e])if(Pe||Be)try{Tt(t)}catch(e){}else try{t.setAttribute(e,"")}catch(e){}},At=function(e){var t,n;if(ze)e="<remove></remove>"+e;else{var r=k(e,/^[\r\n\t ]+/);n=r&&r[0]}"application/xhtml+xml"===ge&&ot===rt&&(e='<html xmlns="http://www.w3.org/1999/xhtml"><head></head><body>'+e+"</body></html>");var o=ie?ie.createHTML(e):e;if(ot===rt)try{t=(new d).parseFromString(o,ge)}catch(e){}if(!t||!t.documentElement){t=ue.createDocument(ot,"template",null);try{t.documentElement.innerHTML=at?"":o}catch(e){}}var i=t.body||t.documentElement;return e&&n&&i.insertBefore(a.createTextNode(n),i.childNodes[0]||null),ot===rt?fe.call(t,Ue?"html":"body")[0]:Ue?t.documentElement:i},Et=function(e){return se.call(e.ownerDocument||e,e,s.SHOW_ELEMENT|s.SHOW_COMMENT|s.SHOW_TEXT,null,!1)},wt=function(e){return e instanceof p&&("string"!=typeof e.nodeName||"string"!=typeof e.textContent||"function"!=typeof e.removeChild||!(e.attributes instanceof f)||"function"!=typeof e.removeAttribute||"function"!=typeof e.setAttribute||"string"!=typeof e.namespaceURI||"function"!=typeof e.insertBefore||"function"!=typeof e.hasChildNodes)},St=function(t){return"object"===e(c)?t instanceof c:t&&"object"===e(t)&&"number"==typeof t.nodeType&&"string"==typeof t.nodeName},kt=function(e,t,r){he[e]&&N(he[e],(function(e){e.call(n,t,r,st)}))},xt=function(e){var t;if(kt("beforeSanitizeElements",e,null),wt(e))return Tt(e),!0;if(O(/[\u0080-\uFFFF]/,e.nodeName))return Tt(e),!0;var r=ye(e.nodeName);if(kt("uponSanitizeElement",e,{tagName:r,allowedTags:ke}),e.hasChildNodes()&&!St(e.firstElementChild)&&(!St(e.content)||!St(e.content.firstElementChild))&&O(/<[/\w]/g,e.innerHTML)&&O(/<[/\w]/g,e.textContent))return Tt(e),!0;if("select"===r&&O(/<template/i,e.innerHTML))return Tt(e),!0;if(!ke[r]||De[r]){if(!De[r]&&Ct(r)){if(Oe.tagNameCheck instanceof RegExp&&O(Oe.tagNameCheck,r))return!1;if(Oe.tagNameCheck instanceof Function&&Oe.tagNameCheck(r))return!1}if(Ye&&!Ve[r]){var o=L(e)||e.parentNode,a=T(e)||e.childNodes;if(a&&o)for(var i=a.length-1;i>=0;--i)o.insertBefore(b(a[i],!0),v(e))}return Tt(e),!0}return e instanceof u&&!vt(e)?(Tt(e),!0):"noscript"!==r&&"noembed"!==r||!O(/<\/no(script|embed)/i,e.innerHTML)?(Fe&&3===e.nodeType&&(t=e.textContent,t=x(t,be," "),t=x(t,ve," "),t=x(t,Te," "),e.textContent!==t&&(E(n.removed,{element:e.cloneNode()}),e.textContent=t)),kt("afterSanitizeElements",e,null),!1):(Tt(e),!0)},_t=function(e,t,n){if(Ge&&("id"===t||"name"===t)&&(n in a||n in mt))return!1;if(Me&&!Le[t]&&O(Ne,t));else if(Re&&O(Ae,t));else if(!_e[t]||Le[t]){if(!(Ct(e)&&(Oe.tagNameCheck instanceof RegExp&&O(Oe.tagNameCheck,e)||Oe.tagNameCheck instanceof Function&&Oe.tagNameCheck(e))&&(Oe.attributeNameCheck instanceof RegExp&&O(Oe.attributeNameCheck,t)||Oe.attributeNameCheck instanceof Function&&Oe.attributeNameCheck(t))||"is"===t&&Oe.allowCustomizedBuiltInElements&&(Oe.tagNameCheck instanceof RegExp&&O(Oe.tagNameCheck,n)||Oe.tagNameCheck instanceof Function&&Oe.tagNameCheck(n))))return!1}else if(Qe[t]);else if(O(Se,x(n,we,"")));else if("src"!==t&&"xlink:href"!==t&&"href"!==t||"script"===e||0!==_(n,"data:")||!Ze[e])if(Ie&&!O(Ee,x(n,we,"")));else if(n)return!1;return!0},Ct=function(e){return e.indexOf("-")>0},Ot=function(t){var r,o,a,i;kt("beforeSanitizeAttributes",t,null);var l=t.attributes;if(l){var c={attrName:"",attrValue:"",keepAttr:!0,allowedAttributes:_e};for(i=l.length;i--;){var u=r=l[i],s=u.name,m=u.namespaceURI;if(o="value"===s?r.value:C(r.value),a=ye(s),c.attrName=a,c.attrValue=o,c.keepAttr=!0,c.forceKeepAttr=void 0,kt("uponSanitizeAttribute",t,c),o=c.attrValue,!c.forceKeepAttr&&(Nt(s,t),c.keepAttr))if(O(/\/>/i,o))Nt(s,t);else{Fe&&(o=x(o,be," "),o=x(o,ve," "),o=x(o,Te," "));var f=ye(t.nodeName);if(_t(f,a,o)){if(!We||"id"!==a&&"name"!==a||(Nt(s,t),o=qe+o),ie&&"object"===e(g)&&"function"==typeof g.getAttributeType)if(m);else switch(g.getAttributeType(f,a)){case"TrustedHTML":o=ie.createHTML(o);break;case"TrustedScriptURL":o=ie.createScriptURL(o)}try{m?t.setAttributeNS(m,s,o):t.setAttribute(s,o),A(n.removed)}catch(e){}}}}kt("afterSanitizeAttributes",t,null)}},Dt=function e(t){var n,r=Et(t);for(kt("beforeSanitizeShadowDOM",t,null);n=r.nextNode();)kt("uponSanitizeShadowNode",n,null),xt(n)||(n.content instanceof i&&e(n.content),Ot(n));kt("afterSanitizeShadowDOM",t,null)};return n.sanitize=function(o){var a,l,u,s,m,f=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};if((at=!o)&&(o="\x3c!--\x3e"),"string"!=typeof o&&!St(o)){if("function"!=typeof o.toString)throw D("toString is not a function");if("string"!=typeof(o=o.toString()))throw D("dirty is not a string, aborting")}if(!n.isSupported){if("object"===e(t.toStaticHTML)||"function"==typeof t.toStaticHTML){if("string"==typeof o)return t.toStaticHTML(o);if(St(o))return t.toStaticHTML(o.outerHTML)}return o}if(He||pt(f),n.removed=[],"string"==typeof o&&($e=!1),$e){if(o.nodeName){var p=ye(o.nodeName);if(!ke[p]||De[p])throw D("root node is forbidden and cannot be sanitized in-place")}}else if(o instanceof c)1===(l=(a=At("\x3c!----\x3e")).ownerDocument.importNode(o,!0)).nodeType&&"BODY"===l.nodeName||"HTML"===l.nodeName?a=l:a.appendChild(l);else{if(!Pe&&!Fe&&!Ue&&-1===o.indexOf("<"))return ie&&je?ie.createHTML(o):o;if(!(a=At(o)))return Pe?null:je?le:""}a&&ze&&Tt(a.firstChild);for(var d=Et($e?o:a);u=d.nextNode();)3===u.nodeType&&u===s||xt(u)||(u.content instanceof i&&Dt(u.content),Ot(u),s=u);if(s=null,$e)return o;if(Pe){if(Be)for(m=me.call(a.ownerDocument);a.firstChild;)m.appendChild(a.firstChild);else m=a;return _e.shadowroot&&(m=pe.call(r,m,!0)),m}var h=Ue?a.outerHTML:a.innerHTML;return Ue&&ke["!doctype"]&&a.ownerDocument&&a.ownerDocument.doctype&&a.ownerDocument.doctype.name&&O(ne,a.ownerDocument.doctype.name)&&(h="<!DOCTYPE "+a.ownerDocument.doctype.name+">\n"+h),Fe&&(h=x(h,be," "),h=x(h,ve," "),h=x(h,Te," ")),ie&&je?ie.createHTML(h):h},n.setConfig=function(e){pt(e),He=!0},n.clearConfig=function(){st=null,He=!1},n.isValidAttribute=function(e,t,n){st||pt({});var r=ye(e),o=ye(t);return _t(r,o,n)},n.addHook=function(e,t){"function"==typeof t&&(he[e]=he[e]||[],E(he[e],t))},n.removeHook=function(e){if(he[e])return A(he[e])},n.removeHooks=function(e){he[e]&&(he[e]=[])},n.removeAllHooks=function(){he={}},n}return ae()}()}}]);
|