@cdc/chart 4.22.10 → 4.22.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +5 -5
  2. package/dist/cdcchart.js +4 -4
  3. package/examples/age-adjusted-rates.json +1486 -1218
  4. package/examples/case-rate-example-config.json +1 -1
  5. package/examples/covid-confidence-example-config.json +33 -33
  6. package/examples/covid-example-config.json +34 -34
  7. package/examples/covid-example-data-confidence.json +30 -30
  8. package/examples/covid-example-data.json +20 -20
  9. package/examples/cutoff-example-config.json +36 -36
  10. package/examples/cutoff-example-data.json +36 -36
  11. package/examples/date-exclusions-config.json +1 -1
  12. package/examples/dynamic-legends.json +124 -124
  13. package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json +191 -197
  14. package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json +230 -240
  15. package/examples/gallery/bar-chart-horizontal/horizontal-stacked.json +239 -247
  16. package/examples/gallery/bar-chart-vertical/combo-line-chart.json +136 -136
  17. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json +79 -79
  18. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json +80 -80
  19. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-with-confidence.json +67 -67
  20. package/examples/gallery/bar-chart-vertical/vertical-bar-chart.json +110 -110
  21. package/examples/gallery/lollipop/lollipop-style-horizontal.json +215 -219
  22. package/examples/gallery/paired-bar/paired-bar-chart.json +195 -195
  23. package/examples/horizontal-chart.json +35 -35
  24. package/examples/horizontal-stacked-bar-chart.json +34 -34
  25. package/examples/line-chart.json +75 -75
  26. package/examples/paired-bar-data.json +16 -14
  27. package/examples/paired-bar-example.json +48 -48
  28. package/examples/paired-bar-formatted.json +36 -36
  29. package/examples/planet-chart-horizontal-example-config.json +33 -33
  30. package/examples/planet-combo-example-config.json +34 -31
  31. package/examples/planet-example-config.json +35 -33
  32. package/examples/planet-example-data.json +56 -56
  33. package/examples/planet-pie-example-config.json +28 -28
  34. package/examples/private/filters.json +170 -0
  35. package/examples/private/line-test-data.json +21 -21
  36. package/examples/private/line-test-two.json +209 -215
  37. package/examples/private/line-test.json +101 -101
  38. package/examples/private/new.json +48800 -0
  39. package/examples/private/shawn.json +1105 -1295
  40. package/examples/private/test.json +10123 -10123
  41. package/examples/private/yaxis-test.json +4 -3
  42. package/examples/private/yaxis.json +26 -26
  43. package/examples/stacked-vertical-bar-example.json +1 -1
  44. package/examples/temp-example-config.json +61 -54
  45. package/examples/temp-example-data.json +1 -1
  46. package/package.json +2 -2
  47. package/src/CdcChart.tsx +339 -380
  48. package/src/components/BarChart.tsx +425 -469
  49. package/src/components/DataTable.tsx +164 -195
  50. package/src/components/EditorPanel.js +1009 -710
  51. package/src/components/Legend.js +279 -329
  52. package/src/components/LineChart.tsx +90 -79
  53. package/src/components/LinearChart.tsx +376 -434
  54. package/src/components/PairedBarChart.tsx +197 -213
  55. package/src/components/PieChart.tsx +95 -151
  56. package/src/components/SparkLine.js +179 -201
  57. package/src/components/useIntersectionObserver.tsx +17 -20
  58. package/src/context.tsx +3 -3
  59. package/src/data/initial-state.js +37 -16
  60. package/src/hooks/useActiveElement.js +13 -13
  61. package/src/hooks/useChartClasses.js +34 -28
  62. package/src/hooks/useColorPalette.ts +56 -63
  63. package/src/hooks/useLegendClasses.js +18 -10
  64. package/src/hooks/useReduceData.ts +62 -78
  65. package/src/hooks/useRightAxis.js +25 -0
  66. package/src/hooks/useTopAxis.js +6 -0
  67. package/src/index.html +45 -45
  68. package/src/index.tsx +13 -16
  69. package/src/scss/DataTable.scss +5 -4
  70. package/src/scss/editor-panel.scss +71 -69
  71. package/src/scss/main.scss +157 -114
  72. package/src/scss/variables.scss +1 -1
@@ -1,160 +1,166 @@
1
- import React, { Fragment, useContext, useEffect, useRef, useState } from 'react';
2
- import ReactTooltip from 'react-tooltip';
3
-
4
- import { Group } from '@visx/group';
5
- import { Line } from '@visx/shape';
6
- import { Text } from '@visx/text';
7
- import { scaleLinear, scalePoint } from '@visx/scale';
8
- import { AxisLeft, AxisBottom } from '@visx/axis';
9
-
10
- import BarChart from './BarChart';
11
- import LineChart from './LineChart';
12
- import Context from '../context';
13
- import PairedBarChart from './PairedBarChart';
14
- import useIntersectionObserver from "./useIntersectionObserver";
15
- import SparkLine from './SparkLine';
16
-
17
- import ErrorBoundary from '@cdc/core/components/ErrorBoundary';
1
+ import React, { Fragment, useContext, useEffect, useRef, useState } from 'react'
2
+ import ReactTooltip from 'react-tooltip'
3
+
4
+ import { Group } from '@visx/group'
5
+ import { Line } from '@visx/shape'
6
+ import { Text } from '@visx/text'
7
+ import { scaleLinear, scalePoint } from '@visx/scale'
8
+ import { AxisLeft, AxisBottom, AxisRight, AxisTop } from '@visx/axis'
9
+
10
+ import BarChart from './BarChart'
11
+ import LineChart from './LineChart'
12
+ import Context from '../context'
13
+ import PairedBarChart from './PairedBarChart'
14
+ import useIntersectionObserver from './useIntersectionObserver'
15
+ import SparkLine from './SparkLine'
16
+
17
+ import ErrorBoundary from '@cdc/core/components/ErrorBoundary'
18
18
  import numberFromString from '@cdc/core/helpers/numberFromString'
19
- import '../scss/LinearChart.scss';
20
- import useReduceData from '../hooks/useReduceData';
19
+ import '../scss/LinearChart.scss'
20
+ import useReduceData from '../hooks/useReduceData'
21
+ import useRightAxis from '../hooks/useRightAxis'
22
+ import useTopAxis from '../hooks/useTopAxis'
23
+
24
+ // TODO: Move scaling functions into hooks to manage complexity
21
25
 
22
26
  // TODO: remove unused imports/variables
23
27
  // TODO: consider moving logic into hooks
24
28
  // TODO: formatting
25
29
  export default function LinearChart() {
26
- const { transformedData: data, dimensions, config, parseDate, formatDate, currentViewport, formatNumber, handleChartAriaLabels } = useContext<any>(Context);
27
- let [ width ] = dimensions;
28
- const {minValue,maxValue,existPositiveValue} = useReduceData(config,data)
29
- const [animatedChart, setAnimatedChart] = useState<boolean>(false);
30
- const [animatedChartPlayed, setAnimatedChartPlayed] = useState<boolean>(false);
30
+ const { transformedData: data, dimensions, config, parseDate, formatDate, currentViewport, formatNumber, handleChartAriaLabels, updateConfig } = useContext<any>(Context)
31
+ let [width] = dimensions
32
+ const { minValue, maxValue, existPositiveValue } = useReduceData(config, data)
33
+ const [animatedChart, setAnimatedChart] = useState<boolean>(false)
34
+ const [animatedChartPlayed, setAnimatedChartPlayed] = useState<boolean>(false)
31
35
 
32
- const triggerRef = useRef();
36
+ const triggerRef = useRef()
33
37
  const dataRef = useIntersectionObserver(triggerRef, {
34
38
  freezeOnceVisible: false
35
- });
39
+ })
36
40
  // If the chart is in view and set to animate and it has not already played
37
- useEffect( () => {
38
- if( dataRef?.isIntersecting === true && config.animate ) {
41
+ useEffect(() => {
42
+ if (dataRef?.isIntersecting === true && config.animate) {
39
43
  setTimeout(() => {
40
- setAnimatedChart(prevState => true);
41
- }, 500);
44
+ setAnimatedChart(prevState => true)
45
+ }, 500)
42
46
  }
43
- }, [dataRef?.isIntersecting, config.animate]);
47
+ }, [dataRef?.isIntersecting, config.animate])
44
48
 
45
- if(config && config.legend && !config.legend.hide && (currentViewport === 'lg' || currentViewport === 'md')) {
46
- width = width * 0.73;
49
+ if (config && config.legend && !config.legend.hide && config.legend.position !== 'bottom' && (currentViewport === 'lg' || currentViewport === 'md')) {
50
+ width = width * 0.73
47
51
  }
48
52
 
49
- const height = config.aspectRatio ? (width * config.aspectRatio) : config.height;
53
+ const height = config.aspectRatio ? width * config.aspectRatio : config.height
54
+ const xMax = width - config.runtime.yAxis.size - config.yAxis.rightAxisSize
55
+ const yMax = height - config.runtime.xAxis.size
50
56
 
51
- const xMax = width - config.runtime.yAxis.size;
52
- const yMax = height - config.runtime.xAxis.size;
57
+ const { yScaleRight, hasRightAxis } = useRightAxis({ config, yMax, data, updateConfig })
58
+ const { hasTopAxis } = useTopAxis(config)
53
59
 
54
- const getXAxisData = (d: any) => config.runtime.xAxis.type === 'date' ? (parseDate(d[config.runtime.originalXAxis.dataKey])).getTime() : d[config.runtime.originalXAxis.dataKey];
55
- const getYAxisData = (d: any, seriesKey: string) => d[seriesKey];
60
+ const getXAxisData = (d: any) => (config.runtime.xAxis.type === 'date' ? parseDate(d[config.runtime.originalXAxis.dataKey]).getTime() : d[config.runtime.originalXAxis.dataKey])
61
+ const getYAxisData = (d: any, seriesKey: string) => d[seriesKey]
56
62
 
57
- let xScale;
58
- let yScale;
59
- let seriesScale;
63
+ let xScale
64
+ let yScale
65
+ let seriesScale
60
66
 
61
- const {max:enteredMaxValue,min:enteredMinValue} = config.runtime.yAxis;
62
- const isMaxValid = existPositiveValue ? numberFromString(enteredMaxValue) >= numberFromString(maxValue) : numberFromString(enteredMaxValue) >= 0;
63
- const isMinValid = ((numberFromString(enteredMinValue) <= 0 && numberFromString(minValue) >=0) || (numberFromString(enteredMinValue) <= minValue && minValue < 0));
67
+ const { max: enteredMaxValue, min: enteredMinValue } = config.runtime.yAxis
68
+ const isMaxValid = existPositiveValue ? numberFromString(enteredMaxValue) >= numberFromString(maxValue) : numberFromString(enteredMaxValue) >= 0
69
+ const isMinValid = (numberFromString(enteredMinValue) <= 0 && numberFromString(minValue) >= 0) || (numberFromString(enteredMinValue) <= minValue && minValue < 0)
64
70
 
65
71
  if (data) {
66
- let min = enteredMinValue && isMinValid ? enteredMinValue : minValue;
67
- let max = enteredMaxValue && isMaxValid ? enteredMaxValue : Number.MIN_VALUE;
72
+ let min = enteredMinValue && isMinValid ? enteredMinValue : minValue
73
+ let max = enteredMaxValue && isMaxValid ? enteredMaxValue : Number.MIN_VALUE
68
74
 
69
- if((config.visualizationType === 'Bar' || config.visualizationType === 'Combo') && min > 0) {
70
- min = 0;
75
+ if ((config.visualizationType === 'Bar' || config.visualizationType === 'Combo') && min > 0) {
76
+ min = 0
71
77
  }
72
- if(config.visualizationType === 'Line' ){
78
+ if (config.visualizationType === 'Line') {
73
79
  const isMinValid = Number(enteredMinValue) < Number(minValue)
74
- min = (enteredMinValue && isMinValid) ? Number(enteredMinValue) : minValue;
80
+ min = enteredMinValue && isMinValid ? Number(enteredMinValue) : minValue
75
81
  }
76
82
  //If data value max wasn't provided, calculate it
77
- if(max === Number.MIN_VALUE){
83
+ if (max === Number.MIN_VALUE) {
78
84
  // if all values in data are negative set max = 0
79
- max = existPositiveValue ? maxValue : 0;
85
+ max = existPositiveValue ? maxValue : 0
80
86
  }
81
-
87
+
82
88
  //Adds Y Axis data padding if applicable
83
- if(config.runtime.yAxis.paddingPercent) {
84
- let paddingValue = (max - min) * config.runtime.yAxis.paddingPercent;
85
- min -= paddingValue;
86
- max += paddingValue;
89
+ if (config.runtime.yAxis.paddingPercent) {
90
+ let paddingValue = (max - min) * config.runtime.yAxis.paddingPercent
91
+ min -= paddingValue
92
+ max += paddingValue
87
93
  }
88
94
 
89
- let xAxisDataMapped = data.map(d => getXAxisData(d));
95
+ let xAxisDataMapped = data.map(d => getXAxisData(d))
90
96
 
91
97
  if (config.isLollipopChart && config.yAxis.displayNumbersOnBar) {
92
- const dataKey = data.map((item) => item[config.series[0].dataKey]);
93
- const maxDataVal = Math.max(...dataKey).toString().length;
98
+ const dataKey = data.map(item => item[config.series[0].dataKey])
99
+ const maxDataVal = Math.max(...dataKey).toString().length
94
100
 
95
101
  switch (true) {
96
102
  case maxDataVal > 8 && maxDataVal <= 12:
97
- max = max * 1.3;
98
- break;
103
+ max = max * 1.3
104
+ break
99
105
  case maxDataVal > 4 && maxDataVal <= 7:
100
- max = max * 1.1;
101
- break;
106
+ max = max * 1.1
107
+ break
102
108
  }
103
109
  }
104
110
 
105
- if (config.runtime.horizontal) {
106
- xScale = scaleLinear<number>({
107
- domain: [min, max],
108
- range: [0, xMax],
109
- });
110
-
111
- yScale =
112
- config.runtime.xAxis.type === "date"
113
- ? scaleLinear<number>({
114
- domain: [
115
- Math.min(...xAxisDataMapped),
116
- Math.max(...xAxisDataMapped),
117
- ],
118
- })
119
- : scalePoint<string>({ domain: xAxisDataMapped, padding: 0.5 });
120
-
121
- seriesScale = scalePoint<string>({
122
- domain: config.runtime.barSeriesKeys || config.runtime.seriesKeys,
123
- range: [0, yMax],
124
- });
125
-
126
- yScale.rangeRound([0, yMax]);
127
- } else {
128
- min = min < 0 ? min * 1.11 : min;
129
-
130
- yScale = scaleLinear<number>({
131
- domain: [min, max],
132
- range: [yMax, 0],
133
- });
134
-
135
- xScale = scalePoint<string>({
136
- domain: xAxisDataMapped,
137
- range: [0, xMax],
138
- padding: 0.5,
139
- });
140
-
141
- seriesScale = scalePoint<string>({
142
- domain: config.runtime.barSeriesKeys || config.runtime.seriesKeys,
143
- range: [0, xMax],
144
- });
145
- }
111
+ if (config.runtime.horizontal) {
112
+ xScale = scaleLinear<number>({
113
+ domain: [min, max],
114
+ range: [0, xMax]
115
+ })
116
+
117
+ yScale =
118
+ config.runtime.xAxis.type === 'date'
119
+ ? scaleLinear<number>({
120
+ domain: [Math.min(...xAxisDataMapped), Math.max(...xAxisDataMapped)]
121
+ })
122
+ : scalePoint<string>({ domain: xAxisDataMapped, padding: 0.5 })
123
+
124
+ seriesScale = scalePoint<string>({
125
+ domain: config.runtime.barSeriesKeys || config.runtime.seriesKeys,
126
+ range: [0, yMax]
127
+ })
128
+
129
+ yScale.rangeRound([0, yMax])
130
+ } else {
131
+ min = min < 0 ? min * 1.11 : min
132
+
133
+ yScale = scaleLinear<number>({
134
+ domain: [min, max],
135
+ range: [yMax, 0]
136
+ })
137
+
138
+ xScale = scalePoint<string>({
139
+ domain: xAxisDataMapped,
140
+ range: [0, xMax],
141
+ padding: 0.5
142
+ })
146
143
 
147
-
148
- if(config.visualizationType === 'Paired Bar') {
149
-
144
+ seriesScale = scalePoint<string>({
145
+ domain: config.runtime.barSeriesKeys || config.runtime.seriesKeys,
146
+ range: [0, xMax]
147
+ })
148
+ }
150
149
 
151
- let groupOneMax = Math.max.apply(Math, data.map(d => d[config.series[0].dataKey]))
152
- let groupTwoMax = Math.max.apply(Math, data.map(d => d[config.series[1].dataKey]))
150
+ if (config.visualizationType === 'Paired Bar') {
151
+ let groupOneMax = Math.max.apply(
152
+ Math,
153
+ data.map(d => d[config.series[0].dataKey])
154
+ )
155
+ let groupTwoMax = Math.max.apply(
156
+ Math,
157
+ data.map(d => d[config.series[1].dataKey])
158
+ )
153
159
 
154
160
  // group one
155
161
  var g1xScale = scaleLinear<number>({
156
- domain: [0, Math.max(groupOneMax,groupTwoMax) ],
157
- range: [xMax/2, 0]
162
+ domain: [0, Math.max(groupOneMax, groupTwoMax)],
163
+ range: [xMax / 2, 0]
158
164
  })
159
165
 
160
166
  // group 2
@@ -162,391 +168,327 @@ export default function LinearChart() {
162
168
  domain: g1xScale.domain(),
163
169
  range: [xMax / 2, xMax]
164
170
  })
165
-
166
171
  }
167
172
  }
168
173
 
169
-
174
+
175
+ const countNumOfTicks = (axis)=>{
176
+ // function get number of ticks based on bar type & users value
177
+ const isHorizontal = config.orientation ==='horizontal';
178
+ const {numTicks} = config.runtime[axis];
179
+ let tickCount = undefined;
180
+
181
+ if(axis === 'yAxis'){
182
+ tickCount = (
183
+ (isHorizontal && !numTicks) ? data.length
184
+ : (isHorizontal && numTicks) ? numTicks
185
+ :(!isHorizontal && !numTicks) ? undefined
186
+ :(!isHorizontal && numTicks) && numTicks
187
+ );
188
+ };
189
+
190
+ if(axis === 'xAxis'){
191
+ tickCount = (
192
+ (isHorizontal && !numTicks) ? undefined
193
+ : (isHorizontal && numTicks) ? numTicks
194
+ :(!isHorizontal && !numTicks) ? undefined
195
+ :(!isHorizontal && numTicks) && numTicks
196
+ );
197
+ };
198
+ return tickCount;
199
+ };
170
200
 
171
201
  useEffect(() => {
172
- ReactTooltip.rebuild();
173
- });
174
-
175
- return isNaN(width) ? <></> : (
176
- <ErrorBoundary component="LinearChart">
177
- <svg
178
- width={width}
179
- height={height}
180
- className={`linear ${(config.animate) ? 'animated' : ''} ${animatedChart && config.animate ? 'animate' : ''}`}
181
- role="img"
182
- aria-label={handleChartAriaLabels(config)}
183
- tabIndex={0}
184
- >
185
- {/* Higlighted regions */}
186
- { config.regions ? config.regions.map((region) => {
187
- if(!Object.keys(region).includes('from') || !Object.keys(region).includes('to')) return null
188
-
189
- const from = xScale((parseDate(region.from)).getTime());
190
- const to = xScale((parseDate(region.to)).getTime());
191
- const width = to - from;
192
-
193
- return (
194
- <Group className="regions" left={config.runtime.yAxis.size} key={region.label}>
195
- <path stroke="#333" d={`M${from} -5
202
+ ReactTooltip.rebuild()
203
+ })
204
+
205
+ return isNaN(width) ? (
206
+ <></>
207
+ ) : (
208
+ <ErrorBoundary component='LinearChart'>
209
+ <svg width={width} height={height} className={`linear ${config.animate ? 'animated' : ''} ${animatedChart && config.animate ? 'animate' : ''}`} role='img' aria-label={handleChartAriaLabels(config)} tabIndex={0}>
210
+ {/* Higlighted regions */}
211
+ {config.regions
212
+ ? config.regions.map(region => {
213
+ if (!Object.keys(region).includes('from') || !Object.keys(region).includes('to')) return null
214
+
215
+ const from = xScale(parseDate(region.from).getTime())
216
+ const to = xScale(parseDate(region.to).getTime())
217
+ const width = to - from
218
+
219
+ return (
220
+ <Group className='regions' left={config.runtime.yAxis.size} key={region.label}>
221
+ <path
222
+ stroke='#333'
223
+ d={`M${from} -5
196
224
  L${from} 5
197
225
  M${from} 0
198
226
  L${to} 0
199
227
  M${to} -5
200
- L${to} 5`} />
201
- <rect
202
- x={from}
203
- y={0}
204
- width={width}
205
- height={yMax}
206
- fill={region.background}
207
- opacity={0.3} />
208
- <Text
209
- x={from + (width / 2)}
210
- y={5}
211
- fill={region.color}
212
- verticalAnchor="start"
213
- textAnchor="middle">
228
+ L${to} 5`}
229
+ />
230
+ <rect x={from} y={0} width={width} height={yMax} fill={region.background} opacity={0.3} />
231
+ <Text x={from + width / 2} y={5} fill={region.color} verticalAnchor='start' textAnchor='middle'>
214
232
  {region.label}
215
- </Text>
216
- </Group>
217
- )
218
- }) : '' }
219
-
220
- {/* Y axis */}
221
- {config.visualizationType !== "Spark Line" &&
222
- <AxisLeft
233
+ </Text>
234
+ </Group>
235
+ )
236
+ })
237
+ : ''}
238
+
239
+ {/* Y axis */}
240
+ {config.visualizationType !== 'Spark Line' && (
241
+ <AxisLeft
223
242
  scale={yScale}
224
243
  left={config.runtime.yAxis.size}
225
244
  label={config.runtime.yAxis.label}
226
- stroke="#333"
227
- tickFormat={(tick)=> config.runtime.yAxis.type ==='date' ? formatDate(parseDate(tick)) : config.orientation==='vertical' ? formatNumber(tick) : tick }
228
- numTicks={config.runtime.yAxis.numTicks || undefined}
245
+ stroke='#333'
246
+ tickFormat={tick => (config.runtime.yAxis.type === 'date' ? formatDate(parseDate(tick)) : config.orientation === 'vertical' ? formatNumber(tick) : tick)}
247
+ numTicks={countNumOfTicks('yAxis')}
229
248
  >
230
249
  {props => {
231
- const lollipopShapeSize = config.lollipopSize === 'large' ? 14 : config.lollipopSize === 'medium' ? 12 : 10;
232
- const axisCenter = config.runtime.horizontal ? (props.axisToPoint.y - props.axisFromPoint.y) / 2 : (props.axisFromPoint.y - props.axisToPoint.y) / 2;
233
- const horizontalTickOffset = yMax / props.ticks.length / 2 - (yMax / props.ticks.length * (1 - config.barThickness)) + 5;
234
- const belowBarPaddingFromTop = 9;
250
+ const lollipopShapeSize = config.lollipopSize === 'large' ? 14 : config.lollipopSize === 'medium' ? 12 : 10
251
+ const axisCenter = config.runtime.horizontal ? (props.axisToPoint.y - props.axisFromPoint.y) / 2 : (props.axisFromPoint.y - props.axisToPoint.y) / 2
252
+ const horizontalTickOffset = yMax / props.ticks.length / 2 - (yMax / props.ticks.length) * (1 - config.barThickness) + 5
253
+ const belowBarPaddingFromTop = 9
235
254
  return (
236
- <Group className="left-axis">
255
+ <Group className='left-axis'>
237
256
  {props.ticks.map((tick, i) => {
238
257
  return (
239
- <Group
240
- key={`vx-tick-${tick.value}-${i}`}
241
- className={'vx-axis-tick'}
242
- >
243
- {!config.runtime.yAxis.hideTicks && (
244
- <Line
245
- from={tick.from}
246
- to={tick.to}
247
- stroke="#333"
248
- display={config.runtime.horizontal ? 'none' : 'block'}
249
- />
250
- )}
258
+ <Group key={`vx-tick-${tick.value}-${i}`} className={'vx-axis-tick'}>
259
+ {!config.runtime.yAxis.hideTicks && <Line from={tick.from} to={tick.to} stroke={config.yAxis.tickColor} display={config.runtime.horizontal ? 'none' : 'block'} />}
260
+
261
+ {config.runtime.yAxis.gridLines ? <Line from={{ x: tick.from.x + xMax, y: tick.from.y }} to={tick.from} stroke='rgba(0,0,0,0.3)' /> : ''}
251
262
 
252
- { config.runtime.yAxis.gridLines ? (
253
- <Line
254
- from={{x: tick.from.x + xMax, y: tick.from.y}}
255
- to={tick.from}
256
- stroke="rgba(0,0,0,0.3)"
257
- />
258
- ) : ''
259
- }
260
-
261
- {( config.orientation === "horizontal" && config.visualizationSubType !== 'stacked') && (config.yAxis.labelPlacement === 'On Date/Category Axis' ) && !config.yAxis.hideLabel &&
262
- // 17 is a magic number from the offset in barchart.
263
- <Fragment>
264
- <Text
265
- transform={`translate(${tick.to.x - 5}, ${ config.isLollipopChart ? tick.from.y : tick.from.y - 17 }) rotate(-${config.runtime.horizontal ? config.runtime.yAxis.tickRotation : 0})`}
266
- verticalAnchor={ config.isLollipopChart ? "middle" : "middle"}
267
- textAnchor={"end"}
268
- >{tick.formattedValue}</Text>
269
- </Fragment>
270
- }
271
-
272
- { (config.orientation === "horizontal" && config.visualizationSubType === 'stacked') && (config.yAxis.labelPlacement === 'On Date/Category Axis' ) && !config.yAxis.hideLabel &&
273
- // 17 is a magic number from the offset in barchart.
274
- <Text
275
- transform={`translate(${tick.to.x - 5}, ${ tick.from.y - config.barHeight / 2 - 3 }) rotate(-${config.runtime.horizontal ? config.runtime.yAxis.tickRotation : 0})`}
276
- verticalAnchor={ config.isLollipopChart ? "middle" : "middle"}
277
- textAnchor={"end"}
278
- >{tick.formattedValue}</Text>
279
- }
280
-
281
- { (config.orientation === "horizontal" && config.visualizationType === 'Paired Bar') && !config.yAxis.hideLabel &&
282
- // 17 is a magic number from the offset in barchart.
283
- <Text
284
- transform={`translate(${-15}, ${ tick.from.y }) rotate(-${config.runtime.horizontal ? config.runtime.yAxis.tickRotation : 0})`}
285
- verticalAnchor={ config.isLollipopChart ? "middle" : "middle"}
286
- textAnchor={"end"}
287
- >{tick.formattedValue}</Text>
288
- }
289
-
290
- { (config.orientation === "horizontal" && config.visualizationType === 'Paired Bar') && !config.yAxis.hideLabel &&
291
- // 17 is a magic number from the offset in barchart.
292
- <Text
293
- transform={`translate(${-15}, ${ tick.from.y }) rotate(-${config.runtime.horizontal ? config.runtime.yAxis.tickRotation : 0})`}
294
- verticalAnchor={ config.isLollipopChart ? "middle" : "middle"}
295
- textAnchor={"end"}
296
- >{formatNumber(tick.formattedValue)}</Text>
297
- }
298
-
299
-
300
- { config.orientation !== "horizontal" && config.visualizationType !== 'Paired Bar' && !config.yAxis.hideLabel &&
301
- <Text
302
- x={config.runtime.horizontal ? tick.from.x + 2 : tick.to.x}
303
- y={tick.to.y + (config.runtime.horizontal ? horizontalTickOffset : 0)}
304
- verticalAnchor={config.runtime.horizontal ? "start" : "middle"}
305
- textAnchor={config.runtime.horizontal ? 'start' : 'end'}
306
- >
263
+ {config.orientation === 'horizontal' && config.visualizationSubType !== 'stacked' && config.yAxis.labelPlacement === 'On Date/Category Axis' && !config.yAxis.hideLabel && (
264
+ // 17 is a magic number from the offset in barchart.
265
+ <Fragment>
266
+ <Text transform={`translate(${tick.to.x - 5}, ${config.isLollipopChart ? tick.from.y : tick.from.y - 17}) rotate(-${config.runtime.horizontal ? config.runtime.yAxis.tickRotation : 0})`} verticalAnchor={config.isLollipopChart ? 'middle' : 'middle'} textAnchor={'end'}>
307
267
  {tick.formattedValue}
308
268
  </Text>
309
- }
269
+ </Fragment>
270
+ )}
310
271
 
311
- </Group>
312
- );
313
- })}
314
- {!config.yAxis.hideAxis && (
315
- <Line
316
- from={props.axisFromPoint}
317
- to={props.axisToPoint}
318
- stroke="#333"
319
- />
320
- )}
321
- { yScale.domain()[0] < 0 && (
322
- <Line
323
- from={{x: props.axisFromPoint.x, y: yScale(0)}}
324
- to={{x: xMax, y: yScale(0)}}
325
- stroke="#333"
326
- />
327
- )}
328
- <Text
329
- className="y-label"
330
- textAnchor="middle"
331
- verticalAnchor="start"
332
- transform={`translate(${-1 * config.runtime.yAxis.size}, ${axisCenter}) rotate(-90)`}
333
- fontWeight="bold"
334
- >
335
- {props.label}
336
- </Text>
337
- </Group>
338
- );
339
- }}
340
- </AxisLeft>
341
- }
272
+ {config.orientation === 'horizontal' && config.visualizationSubType === 'stacked' && config.yAxis.labelPlacement === 'On Date/Category Axis' && !config.yAxis.hideLabel && (
273
+ // 17 is a magic number from the offset in barchart.
274
+ <Text transform={`translate(${tick.to.x - 5}, ${tick.from.y - config.barHeight / 2 - 3}) rotate(-${config.runtime.horizontal ? config.runtime.yAxis.tickRotation : 0})`} verticalAnchor={config.isLollipopChart ? 'middle' : 'middle'} textAnchor={'end'}>
275
+ {tick.formattedValue}
276
+ </Text>
277
+ )}
342
278
 
343
- {/* X axis */}
344
- {config.visualizationType !== 'Paired Bar' && config.visualizationType !== "Spark Line" && (
345
- <AxisBottom
346
- top={yMax}
347
- left={config.runtime.yAxis.size}
348
- label={config.runtime.xAxis.label}
349
- tickFormat={tick=> config.runtime.xAxis.type === 'date' ? formatDate(tick) : config.orientation ==='horizontal' ? formatNumber(tick) : tick}
350
- scale={xScale}
351
- stroke="#333"
352
- tickStroke="#333"
353
- numTicks={config.runtime.xAxis.numTicks || undefined}
354
- >
355
- {props => {
356
- const axisCenter = (props.axisToPoint.x - props.axisFromPoint.x) / 2;
357
- return (
358
- <Group className="bottom-axis">
359
- {props.ticks.map((tick, i) => {
360
- const tickWidth = xMax / props.ticks.length;
361
- return (
362
- <Group
363
- key={`vx-tick-${tick.value}-${i}`}
364
- className={'vx-axis-tick'}
365
- >
366
- {!config.xAxis.hideTicks && (
367
- <Line
368
- from={tick.from}
369
- to={tick.to}
370
- stroke="#333"
371
- />
279
+ {config.orientation === 'horizontal' && config.visualizationType === 'Paired Bar' && !config.yAxis.hideLabel && (
280
+ // 17 is a magic number from the offset in barchart.
281
+ <Text transform={`translate(${-15}, ${tick.from.y}) rotate(-${config.runtime.horizontal ? config.runtime.yAxis.tickRotation : 0})`} verticalAnchor={config.isLollipopChart ? 'middle' : 'middle'} textAnchor={'end'}>
282
+ {tick.formattedValue}
283
+ </Text>
372
284
  )}
373
- {!config.xAxis.hideLabel && (
374
- <Text
375
- transform={`translate(${tick.to.x}, ${tick.to.y}) rotate(-${!config.runtime.horizontal ? config.runtime.xAxis.tickRotation : 0})`}
376
- verticalAnchor="start"
377
- textAnchor={config.runtime.xAxis.tickRotation && config.runtime.xAxis.tickRotation !== '0' ? 'end' : 'middle'}
378
- width={config.runtime.xAxis.tickRotation && config.runtime.xAxis.tickRotation !== '0' ? undefined : tickWidth}
379
- >
380
- {tick.formattedValue}
381
- </Text>
285
+
286
+ {config.orientation === 'horizontal' && config.visualizationType === 'Paired Bar' && !config.yAxis.hideLabel && (
287
+ // 17 is a magic number from the offset in barchart.
288
+ <Text transform={`translate(${-15}, ${tick.from.y}) rotate(-${config.runtime.horizontal ? config.runtime.yAxis.tickRotation : 0})`} verticalAnchor={config.isLollipopChart ? 'middle' : 'middle'} textAnchor={'end'}>
289
+ {formatNumber(tick.formattedValue)}
290
+ </Text>
382
291
  )}
383
292
 
293
+ {config.orientation !== 'horizontal' && config.visualizationType !== 'Paired Bar' && !config.yAxis.hideLabel && (
294
+ <Text
295
+ x={config.runtime.horizontal ? tick.from.x + 2 : tick.to.x}
296
+ y={tick.to.y + (config.runtime.horizontal ? horizontalTickOffset : 0)}
297
+ verticalAnchor={config.runtime.horizontal ? 'start' : 'middle'}
298
+ textAnchor={config.runtime.horizontal ? 'start' : 'end'}
299
+ fill={config.yAxis.tickLabelColor}
300
+ >
301
+ {tick.formattedValue}
302
+ </Text>
303
+ )}
384
304
  </Group>
385
- );
305
+ )
386
306
  })}
387
- {!config.xAxis.hideAxis && (
388
- <Line
389
- from={props.axisFromPoint}
390
- to={props.axisToPoint}
391
- stroke="#333"
392
- />
393
- )}
394
- <Text
395
- x={axisCenter}
396
- y={config.runtime.xAxis.size}
397
- textAnchor="middle"
398
- verticalAnchor="end"
399
- fontWeight="bold"
400
- >
307
+ {!config.yAxis.hideAxis && <Line from={props.axisFromPoint} to={props.axisToPoint} stroke='#333' />}
308
+ {yScale.domain()[0] < 0 && <Line from={{ x: props.axisFromPoint.x, y: yScale(0) }} to={{ x: xMax, y: yScale(0) }} stroke='#333' />}
309
+ <Text className='y-label' textAnchor='middle' verticalAnchor='start' transform={`translate(${-1 * config.runtime.yAxis.size}, ${axisCenter}) rotate(-90)`} fontWeight='bold' fill={config.yAxis.labelColor}>
401
310
  {props.label}
402
311
  </Text>
403
312
  </Group>
404
- );
313
+ )
405
314
  }}
406
- </AxisBottom>
407
- )}
315
+ </AxisLeft>
316
+ )}
408
317
 
409
- {config.visualizationType === 'Paired Bar' &&
410
- <>
411
- <AxisBottom
412
- top={yMax}
413
- left={config.runtime.yAxis.size}
414
- label={config.runtime.xAxis.label}
415
- tickFormat={config.runtime.xAxis.type === 'date' ? formatDate :formatNumber}
416
- scale={g1xScale}
417
- stroke="#333"
418
- tickStroke="#333"
419
- numTicks={config.runtime.xAxis.numTicks || undefined}
420
- >
318
+ {/* Right Axis */}
319
+ {hasRightAxis && (
320
+ <AxisRight scale={yScaleRight} left={width - config.yAxis.rightAxisSize} label={config.yAxis.rightLabel} tickFormat={tick => formatNumber(tick, 'right')} numTicks={config.runtime.yAxis.rightNumTicks || undefined} labelOffset={45}>
421
321
  {props => {
422
- const axisCenter = (props.axisToPoint.x - props.axisFromPoint.x) / 2;
322
+ const axisCenter = config.runtime.horizontal ? (props.axisToPoint.y - props.axisFromPoint.y) / 2 : (props.axisFromPoint.y - props.axisToPoint.y) / 2
323
+ const horizontalTickOffset = yMax / props.ticks.length / 2 - (yMax / props.ticks.length) * (1 - config.barThickness) + 5
423
324
  return (
424
- <Group className="bottom-axis">
325
+ <Group className='right-axis'>
425
326
  {props.ticks.map((tick, i) => {
426
- const tickWidth = xMax / props.ticks.length;
427
327
  return (
428
- <Group
429
- key={`vx-tick-${tick.value}-${i}`}
430
- className={'vx-axis-tick'}
431
- >
432
- {!config.runtime.yAxis.hideTicks &&
433
- <Line
434
- from={tick.from}
435
- to={tick.to}
436
- stroke="#333"
437
- />
438
- }
439
- {!config.runtime.yAxis.hideLabel &&
440
- <Text
441
- transform={`translate(${tick.to.x}, ${tick.to.y}) rotate(-${60})`}
442
- verticalAnchor="start"
443
- textAnchor={'end'}
444
- width={config.runtime.xAxis.tickRotation && config.runtime.xAxis.tickRotation !== '0' ? undefined : tickWidth}
445
- >
446
- {formatNumber(tick.formattedValue)}
328
+ <Group key={`vx-tick-${tick.value}-${i}`} className='vx-axis-tick'>
329
+ {!config.runtime.yAxis.rightHideTicks && <Line from={tick.from} to={tick.to} display={config.runtime.horizontal ? 'none' : 'block'} stroke={config.yAxis.rightAxisTickColor} />}
330
+
331
+ {config.runtime.yAxis.rightGridLines ? <Line from={{ x: tick.from.x + xMax, y: tick.from.y }} to={tick.from} stroke='rgba(0,0,0,0.3)' /> : ''}
332
+
333
+ {!config.yAxis.rightHideLabel && (
334
+ <Text x={tick.to.x} y={tick.to.y + (config.runtime.horizontal ? horizontalTickOffset : 0)} verticalAnchor={config.runtime.horizontal ? 'start' : 'middle'} textAnchor={'start'} fill={config.yAxis.rightAxisTickLabelColor}>
335
+ {tick.formattedValue}
447
336
  </Text>
448
- }
337
+ )}
449
338
  </Group>
450
- );
339
+ )
451
340
  })}
452
- {!config.runtime.yAxis.hideAxis &&
453
- <Line
454
- from={props.axisFromPoint}
455
- to={props.axisToPoint}
456
- stroke="#333"
457
- />
458
- }
341
+ {!config.yAxis.rightHideAxis && <Line from={props.axisFromPoint} to={props.axisToPoint} stroke='#333' />}
342
+ <Text className='y-label' textAnchor='middle' verticalAnchor='start' transform={`translate(${config.yAxis.rightLabelOffsetSize ? config.yAxis.rightLabelOffsetSize : 0}, ${axisCenter}) rotate(90)`} fontWeight='bold' fill={config.yAxis.rightAxisLabelColor}>
343
+ {props.label}
344
+ </Text>
459
345
  </Group>
460
- );
346
+ )
461
347
  }}
462
- </AxisBottom>
348
+ </AxisRight>
349
+ )}
350
+
351
+ {hasTopAxis && config.topAxis.hasLine && (
352
+ <AxisTop
353
+ stroke='#333'
354
+ left={config.runtime.yAxis.size}
355
+ scale={xScale}
356
+ hideTicks
357
+ hideZero
358
+ tickLabelProps={() => ({
359
+ fill: 'transparent'
360
+ })}
361
+ />
362
+ )}
363
+
364
+ {/* X axis */}
365
+ {config.visualizationType !== 'Paired Bar' && config.visualizationType !== 'Spark Line' && (
463
366
  <AxisBottom
464
367
  top={yMax}
465
368
  left={config.runtime.yAxis.size}
466
369
  label={config.runtime.xAxis.label}
467
- tickFormat={config.runtime.xAxis.type === 'date' ? formatDate : config.runtime.xAxis.dataKey !=='Year'? formatNumber : (tick)=>tick}
468
- scale={g2xScale}
469
- stroke="#333"
470
- tickStroke="#333"
471
- numTicks={config.runtime.xAxis.numTicks || undefined}
370
+ tickFormat={tick => (config.runtime.xAxis.type === 'date' ? formatDate(tick) : config.orientation === 'horizontal' ? formatNumber(tick) : tick)}
371
+ scale={xScale}
372
+ stroke='#333'
373
+ tickStroke='#333'
374
+ numTicks={countNumOfTicks('xAxis')}
472
375
  >
473
376
  {props => {
474
- const axisCenter = (props.axisToPoint.x - props.axisFromPoint.x) / 2;
377
+ const axisCenter = (props.axisToPoint.x - props.axisFromPoint.x) / 2
475
378
  return (
476
- <>
477
- <Group className="bottom-axis">
379
+ <Group className='bottom-axis'>
478
380
  {props.ticks.map((tick, i) => {
479
- const tickWidth = xMax / props.ticks.length;
381
+ const tickWidth = xMax / props.ticks.length
480
382
  return (
481
- <Group
482
- key={`vx-tick-${tick.value}-${i}`}
483
- className={'vx-axis-tick'}
484
- >
485
- {!config.runtime.yAxis.hideTicks &&
486
- <Line
487
- from={tick.from}
488
- to={tick.to}
489
- stroke="#333"
490
- />
491
- }
492
- {!config.runtime.yAxis.hideLabel &&
383
+ <Group key={`vx-tick-${tick.value}-${i}`} className={'vx-axis-tick'}>
384
+ {!config.xAxis.hideTicks && <Line from={tick.from} to={tick.to} stroke={config.xAxis.tickColor} />}
385
+ {!config.xAxis.hideLabel && (
493
386
  <Text
494
- transform={`translate(${tick.to.x}, ${tick.to.y}) rotate(-${60})`}
495
- verticalAnchor="start"
496
- textAnchor={'end'}
387
+ transform={`translate(${tick.to.x}, ${tick.to.y}) rotate(-${!config.runtime.horizontal ? config.runtime.xAxis.tickRotation : 0})`}
388
+ verticalAnchor='start'
389
+ textAnchor={config.runtime.xAxis.tickRotation && config.runtime.xAxis.tickRotation !== '0' ? 'end' : 'middle'}
497
390
  width={config.runtime.xAxis.tickRotation && config.runtime.xAxis.tickRotation !== '0' ? undefined : tickWidth}
391
+ fill={config.xAxis.tickLabelColor}
498
392
  >
499
393
  {tick.formattedValue}
500
394
  </Text>
501
- }
395
+ )}
502
396
  </Group>
503
- );
397
+ )
504
398
  })}
505
- {!config.runtime.yAxis.hideAxis &&
506
- <Line
507
- from={props.axisFromPoint}
508
- to={props.axisToPoint}
509
- stroke="#333"
510
- />
511
- }
399
+ {!config.xAxis.hideAxis && <Line from={props.axisFromPoint} to={props.axisToPoint} stroke='#333' />}
400
+ <Text x={axisCenter} y={config.runtime.xAxis.size} textAnchor='middle' verticalAnchor='end' fontWeight='bold' fill={config.xAxis.labelColor}>
401
+ {props.label}
402
+ </Text>
512
403
  </Group>
513
- <Group>
514
- <Text
515
- transform={`translate(${xMax/2}, ${config.height - yMax + 20}) rotate(-${0})`}
516
- verticalAnchor="start"
517
- textAnchor={'middle'}
518
- stroke="#333"
519
- >
520
- {config.runtime.xAxis.label}
521
- </Text>
522
- </Group>
523
- </>
524
- );
404
+ )
525
405
  }}
526
406
  </AxisBottom>
407
+ )}
408
+
409
+ {config.visualizationType === 'Paired Bar' && (
410
+ <>
411
+ <AxisBottom top={yMax} left={config.runtime.yAxis.size} label={config.runtime.xAxis.label} tickFormat={config.runtime.xAxis.type === 'date' ? formatDate : formatNumber} scale={g1xScale} stroke='#333' tickStroke='#333' numTicks={config.runtime.xAxis.numTicks || undefined}>
412
+ {props => {
413
+ const axisCenter = (props.axisToPoint.x - props.axisFromPoint.x) / 2
414
+ return (
415
+ <Group className='bottom-axis'>
416
+ {props.ticks.map((tick, i) => {
417
+ const tickWidth = xMax / props.ticks.length
418
+ return (
419
+ <Group key={`vx-tick-${tick.value}-${i}`} className={'vx-axis-tick'}>
420
+ {!config.runtime.yAxis.hideTicks && <Line from={tick.from} to={tick.to} stroke='#333' />}
421
+ {!config.runtime.yAxis.hideLabel && (
422
+ <Text transform={`translate(${tick.to.x}, ${tick.to.y}) rotate(-${60})`} verticalAnchor='start' textAnchor={'end'} width={config.runtime.xAxis.tickRotation && config.runtime.xAxis.tickRotation !== '0' ? undefined : tickWidth}>
423
+ {formatNumber(tick.formattedValue)}
424
+ </Text>
425
+ )}
426
+ </Group>
427
+ )
428
+ })}
429
+ {!config.runtime.yAxis.hideAxis && <Line from={props.axisFromPoint} to={props.axisToPoint} stroke='#333' />}
430
+ </Group>
431
+ )
432
+ }}
433
+ </AxisBottom>
434
+ <AxisBottom
435
+ top={yMax}
436
+ left={config.runtime.yAxis.size}
437
+ label={config.runtime.xAxis.label}
438
+ tickFormat={config.runtime.xAxis.type === 'date' ? formatDate : config.runtime.xAxis.dataKey !== 'Year' ? formatNumber : tick => tick}
439
+ scale={g2xScale}
440
+ stroke='#333'
441
+ tickStroke='#333'
442
+ numTicks={config.runtime.xAxis.numTicks || undefined}
443
+ >
444
+ {props => {
445
+ const axisCenter = (props.axisToPoint.x - props.axisFromPoint.x) / 2
446
+ return (
447
+ <>
448
+ <Group className='bottom-axis'>
449
+ {props.ticks.map((tick, i) => {
450
+ const tickWidth = xMax / props.ticks.length
451
+ return (
452
+ <Group key={`vx-tick-${tick.value}-${i}`} className={'vx-axis-tick'}>
453
+ {!config.runtime.yAxis.hideTicks && <Line from={tick.from} to={tick.to} stroke='#333' />}
454
+ {!config.runtime.yAxis.hideLabel && (
455
+ <Text transform={`translate(${tick.to.x}, ${tick.to.y}) rotate(-${60})`} verticalAnchor='start' textAnchor={'end'} width={config.runtime.xAxis.tickRotation && config.runtime.xAxis.tickRotation !== '0' ? undefined : tickWidth}>
456
+ {tick.formattedValue}
457
+ </Text>
458
+ )}
459
+ </Group>
460
+ )
461
+ })}
462
+ {!config.runtime.yAxis.hideAxis && <Line from={props.axisFromPoint} to={props.axisToPoint} stroke='#333' />}
463
+ </Group>
464
+ <Group>
465
+ <Text transform={`translate(${xMax / 2}, ${config.height - yMax + 20}) rotate(-${0})`} verticalAnchor='start' textAnchor={'middle'} stroke='#333'>
466
+ {config.runtime.xAxis.label}
467
+ </Text>
468
+ </Group>
469
+ </>
470
+ )
471
+ }}
472
+ </AxisBottom>
473
+ </>
474
+ )}
475
+ {config.visualizationType === 'Paired Bar' && <PairedBarChart width={xMax} height={yMax} />}
476
+
477
+ {/* Bar chart */}
478
+ {config.visualizationType !== 'Line' && config.visualizationType !== 'Paired Bar' && (
479
+ <>
480
+ <BarChart xScale={xScale} yScale={yScale} seriesScale={seriesScale} xMax={xMax} yMax={yMax} getXAxisData={getXAxisData} getYAxisData={getYAxisData} animatedChart={animatedChart} visible={animatedChart} />
481
+ </>
482
+ )}
483
+
484
+ {/* Line chart */}
485
+ {config.visualizationType !== 'Bar' && config.visualizationType !== 'Paired Bar' && (
486
+ <>
487
+ <LineChart xScale={xScale} yScale={yScale} getXAxisData={getXAxisData} getYAxisData={getYAxisData} xMax={xMax} yMax={yMax} seriesStyle={config.series} />
527
488
  </>
528
- }
529
- { config.visualizationType === 'Paired Bar' && (
530
- <PairedBarChart width={xMax} height={yMax} />
531
- ) }
532
-
533
- {/* Bar chart */}
534
- { (config.visualizationType !== 'Line' && config.visualizationType !== 'Paired Bar') && (
535
- <>
536
- <BarChart xScale={xScale} yScale={yScale} seriesScale={seriesScale} xMax={xMax} yMax={yMax} getXAxisData={getXAxisData} getYAxisData={getYAxisData} animatedChart={animatedChart} visible={animatedChart} />
537
- </>
538
-
539
- )}
540
-
541
- {/* Line chart */}
542
- { (config.visualizationType !== 'Bar' && config.visualizationType !== 'Paired Bar') && (
543
- <>
544
- <LineChart xScale={xScale} yScale={yScale} getXAxisData={getXAxisData} getYAxisData={getYAxisData} xMax={xMax} yMax={yMax} seriesStyle={config.series} />
545
- </>
546
-
547
- )}
489
+ )}
548
490
  </svg>
549
- <ReactTooltip id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`} html={true} type="light" arrowColor="rgba(0,0,0,0)" className="tooltip"/>
491
+ <ReactTooltip id={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`} html={true} type='light' arrowColor='rgba(0,0,0,0)' className='tooltip' />
550
492
  <div className='animation-trigger' ref={triggerRef} />
551
493
  </ErrorBoundary>
552
494
  )