@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.
Files changed (52) hide show
  1. package/dist/cdcchart.js +54532 -696
  2. package/examples/Barchart_with_negative.json +34 -0
  3. package/examples/box-plot.json +2 -2
  4. package/examples/dynamic-legends.json +1 -1
  5. package/examples/example-bar-chart-nonnumeric.json +36 -0
  6. package/examples/example-bar-chart.json +33 -0
  7. package/examples/example-combo-bar-nonnumeric.json +105 -0
  8. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json +1 -1
  9. package/examples/gallery/bar-chart-vertical/vertical-bar-chart.json +2 -2
  10. package/examples/gallery/paired-bar/paired-bar-chart.json +65 -13
  11. package/examples/line-chart-nonnumeric.json +32 -0
  12. package/examples/line-chart.json +21 -63
  13. package/examples/newdata.json +1 -1
  14. package/examples/planet-combo-example-config.json +143 -20
  15. package/examples/planet-example-data-nonnumeric.json +56 -0
  16. package/examples/planet-example-data.json +2 -2
  17. package/examples/planet-pie-example-config-nonnumeric.json +30 -0
  18. package/examples/scatterplot-continuous.csv +17 -0
  19. package/examples/scatterplot.json +136 -0
  20. package/examples/sparkline-chart-nonnumeric.json +76 -0
  21. package/examples/stacked-vertical-bar-example-negative.json +154 -0
  22. package/examples/stacked-vertical-bar-example-nonnumerics.json +154 -0
  23. package/index.html +74 -0
  24. package/package.json +29 -23
  25. package/src/{CdcChart.tsx → CdcChart.jsx} +74 -56
  26. package/src/components/{BarChart.tsx → BarChart.jsx} +99 -91
  27. package/src/components/BoxPlot.jsx +88 -0
  28. package/src/components/{DataTable.tsx → DataTable.jsx} +102 -25
  29. package/src/components/{EditorPanel.js → EditorPanel.jsx} +228 -14
  30. package/src/components/{Filters.js → Filters.jsx} +6 -12
  31. package/src/components/{Legend.js → Legend.jsx} +120 -108
  32. package/src/components/{LineChart.tsx → LineChart.jsx} +26 -12
  33. package/src/components/{LinearChart.tsx → LinearChart.jsx} +67 -47
  34. package/src/components/{PairedBarChart.tsx → PairedBarChart.jsx} +45 -78
  35. package/src/components/{PieChart.tsx → PieChart.jsx} +17 -32
  36. package/src/components/ScatterPlot.jsx +48 -0
  37. package/src/components/{SparkLine.js → SparkLine.jsx} +49 -18
  38. package/src/components/{useIntersectionObserver.tsx → useIntersectionObserver.jsx} +1 -1
  39. package/src/data/initial-state.js +33 -3
  40. package/src/hooks/{useColorPalette.ts → useColorPalette.js} +10 -28
  41. package/src/hooks/{useReduceData.ts → useReduceData.js} +25 -14
  42. package/src/hooks/useRightAxis.js +3 -1
  43. package/src/index.jsx +16 -0
  44. package/src/scss/DataTable.scss +22 -0
  45. package/src/scss/main.scss +30 -10
  46. package/vite.config.js +4 -0
  47. package/dist/495.js +0 -3
  48. package/dist/703.js +0 -1
  49. package/src/components/BoxPlot.js +0 -92
  50. package/src/index.html +0 -67
  51. package/src/index.tsx +0 -18
  52. /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 Context from '../context'
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(Context)
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
- if (data) {
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 = data.map(d => getXAxisData(d))
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
- {data.map((d, dataIndex) => {
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-tip={tooltip}
137
- data-for={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
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={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
- marker-end={`url(#${'arrow'}--${index})`}
183
+ markerEnd={`url(#${'arrow'}--${index})`}
153
184
  />
154
185
  <MarkerArrow
155
186
  id={`arrow--${index}`}
156
187
  refX={2}
157
188
  size={6}
158
- marker-end={`url(#${'arrow'}--${index})`}
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<any>()
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: State = {
9
+ const initialState = {
23
10
  filteredPallets: [],
24
11
  isPaletteReversed: false,
25
12
  filteredQualitative: [],
26
13
  paletteName: undefined
27
14
  }
28
15
 
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 = ''
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: string) => String(name).startsWith('qualitative') && !String(name).endsWith('reverse'))
39
- const sequential = palletNamesArr.filter((name: string) => String(name).startsWith('sequential') && !String(name).endsWith('reverse'))
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: 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'))
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<T, Y extends Keyable>(colorPalettes: T, configState: Y) {
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
- }, [] as number[])
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 = (): boolean => {
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 ,isAllLine}
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: [0, max],
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
+ )
@@ -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
 
@@ -1,8 +1,8 @@
1
- @import '~@cdc/core/styles/base';
2
- @import '~@cdc/core/styles/heading-colors';
1
+ @import '@cdc/core/styles/base';
2
+ @import '@cdc/core/styles/heading-colors';
3
3
  @import 'mixins';
4
4
  @import 'variables';
5
- @import '~@cdc/core/styles/v2/themes/color-definitions';
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
- background-color: #fff;
236
- border: rgba(0, 0, 0, 0.3) 1px solid !important;
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
@@ -0,0 +1,4 @@
1
+ import GenerateViteConfig from '../../generateViteConfig.js'
2
+ import { moduleName } from './package.json'
3
+
4
+ export default GenerateViteConfig(moduleName)
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()}()}}]);