@cdc/chart 4.24.7 → 4.24.9

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 (51) hide show
  1. package/dist/cdcchart.js +40313 -37543
  2. package/examples/cases-year.json +13379 -0
  3. package/examples/gallery/bar-chart-vertical/combo-line-chart.json +76 -15
  4. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json +5 -5
  5. package/index.html +17 -8
  6. package/package.json +2 -2
  7. package/src/CdcChart.tsx +383 -133
  8. package/src/_stories/Chart.Legend.Gradient.tsx +19 -0
  9. package/src/_stories/_mock/legend.gradient_mock.json +236 -0
  10. package/src/components/Annotations/components/AnnotationDraggable.tsx +64 -11
  11. package/src/components/Axis/Categorical.Axis.tsx +145 -0
  12. package/src/components/BarChart/components/BarChart.Horizontal.tsx +4 -3
  13. package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +1 -1
  14. package/src/components/BarChart/components/BarChart.StackedVertical.tsx +2 -5
  15. package/src/components/BarChart/components/BarChart.Vertical.tsx +17 -8
  16. package/src/components/BarChart/helpers/index.ts +5 -16
  17. package/src/components/BrushChart.tsx +205 -0
  18. package/src/components/EditorPanel/EditorPanel.tsx +1766 -509
  19. package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +19 -5
  20. package/src/components/EditorPanel/components/Panels/Panel.General.tsx +190 -37
  21. package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +43 -7
  22. package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +4 -4
  23. package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +1 -11
  24. package/src/components/EditorPanel/editor-panel.scss +16 -3
  25. package/src/components/EditorPanel/{useEditorPermissions.js → useEditorPermissions.ts} +90 -19
  26. package/src/components/Legend/Legend.Component.tsx +185 -193
  27. package/src/components/Legend/Legend.Suppression.tsx +146 -0
  28. package/src/components/Legend/Legend.tsx +21 -5
  29. package/src/components/Legend/helpers/index.ts +33 -3
  30. package/src/components/LegendWrapper.tsx +26 -0
  31. package/src/components/LineChart/LineChartProps.ts +1 -18
  32. package/src/components/LineChart/components/LineChart.BumpCircle.tsx +103 -0
  33. package/src/components/LineChart/components/LineChart.Circle.tsx +47 -8
  34. package/src/components/LineChart/helpers.ts +55 -11
  35. package/src/components/LineChart/index.tsx +113 -38
  36. package/src/components/LinearChart.tsx +1366 -0
  37. package/src/components/PieChart/PieChart.tsx +74 -17
  38. package/src/components/Sankey/index.tsx +22 -16
  39. package/src/components/Sparkline/components/SparkLine.tsx +2 -2
  40. package/src/data/initial-state.js +13 -3
  41. package/src/hooks/useLegendClasses.ts +52 -15
  42. package/src/hooks/useMinMax.ts +4 -4
  43. package/src/hooks/useScales.ts +34 -24
  44. package/src/hooks/useTooltip.tsx +85 -22
  45. package/src/scss/DataTable.scss +2 -1
  46. package/src/scss/main.scss +107 -14
  47. package/src/types/ChartConfig.ts +34 -8
  48. package/src/types/ChartContext.ts +5 -4
  49. package/examples/feature/line/line-chart.json +0 -449
  50. package/src/components/BrushHandle.jsx +0 -17
  51. package/src/components/LineChart/index.scss +0 -1
@@ -16,6 +16,7 @@ import useRightAxis from '../../hooks/useRightAxis'
16
16
  // Local helpers and components
17
17
  import { filterCircles, createStyles, createDataSegments } from './helpers'
18
18
  import LineChartCircle from './components/LineChart.Circle'
19
+ import LineChartBumpCircle from './components/LineChart.BumpCircle'
19
20
 
20
21
  // Types
21
22
  import { type ChartContext } from '../../types/ChartContext'
@@ -56,15 +57,29 @@ const LineChart = (props: LineChartProps) => {
56
57
  {' '}
57
58
  {/* left - expects a number not a string */}
58
59
  {(config.runtime.lineSeriesKeys || config.runtime.seriesKeys).map((seriesKey, index) => {
59
- let lineType = config.series.filter(item => item.dataKey === seriesKey)[0].type
60
- const seriesData = config.series.filter(item => item.dataKey === seriesKey)
60
+ let lineType = config.runtime.series.filter(item => item.dataKey === seriesKey)[0].type
61
+ const seriesData = config.runtime.series.filter(item => item.dataKey === seriesKey)
61
62
  const seriesAxis = seriesData[0].axis ? seriesData[0].axis : 'left'
62
- let displayArea = legend.behavior === 'highlight' || seriesHighlight.length === 0 || seriesHighlight.indexOf(seriesKey) !== -1
63
+ let displayArea =
64
+ legend.behavior === 'highlight' || seriesHighlight.length === 0 || seriesHighlight.indexOf(seriesKey) !== -1
63
65
  const circleData = filterCircles(config?.preliminaryData, tableD, seriesKey)
64
66
  // styles for preliminary Data items
65
- let styles = createStyles({ preliminaryData: config.preliminaryData, data: tableD, stroke: colorScale(config.runtime.seriesLabels[seriesKey]), strokeWidth: seriesData[0].weight || 2, handleLineType, lineType, seriesKey })
66
- const suppressedSegments = createDataSegments(tableData, seriesKey, config.preliminaryData, config.xAxis.dataKey)
67
-
67
+ let styles = createStyles({
68
+ preliminaryData: config.preliminaryData,
69
+ data: tableD,
70
+ stroke: colorScale(config.runtime.seriesLabels[seriesKey]),
71
+ strokeWidth: seriesData[0].weight || 2,
72
+ handleLineType,
73
+ lineType,
74
+ seriesKey
75
+ })
76
+ const suppressedSegments = createDataSegments(
77
+ tableData,
78
+ seriesKey,
79
+ config.preliminaryData,
80
+ config.xAxis.dataKey
81
+ )
82
+ const splittedData = config?.preliminaryData?.filter(pd => pd.style && !pd.style.includes('Circles'))
68
83
  let xPos = d => {
69
84
  return xScale(getXAxisData(d)) + (xScale.bandwidth ? xScale.bandwidth() / 2 : 0)
70
85
  }
@@ -72,36 +87,56 @@ const LineChart = (props: LineChartProps) => {
72
87
  return (
73
88
  <Group
74
89
  key={`series-${seriesKey}`}
75
- opacity={legend.behavior === 'highlight' && seriesHighlight.length > 0 && seriesHighlight.indexOf(seriesKey) === -1 ? 0.5 : 1}
76
- display={legend.behavior === 'highlight' || (seriesHighlight.length === 0 && !legend.dynamicLegend) || seriesHighlight.indexOf(seriesKey) !== -1 ? 'block' : 'none'}
90
+ opacity={
91
+ legend.behavior === 'highlight' &&
92
+ seriesHighlight.length > 0 &&
93
+ seriesHighlight.indexOf(seriesKey) === -1
94
+ ? 0.5
95
+ : 1
96
+ }
97
+ display={
98
+ legend.behavior === 'highlight' ||
99
+ (seriesHighlight.length === 0 && !legend.dynamicLegend) ||
100
+ seriesHighlight.indexOf(seriesKey) !== -1
101
+ ? 'block'
102
+ : 'none'
103
+ }
77
104
  >
105
+ {/* tooltips */}
106
+ <Bar
107
+ key={'bars'}
108
+ width={Number(xMax)}
109
+ height={Number(yMax)}
110
+ fill={DEBUG ? 'red' : 'transparent'}
111
+ fillOpacity={0.05}
112
+ onMouseMove={e => handleTooltipMouseOver(e, tableData)}
113
+ onMouseOut={handleTooltipMouseOff}
114
+ onClick={e => handleTooltipClick(e, data)}
115
+ />
78
116
  {data.map((d, dataIndex) => {
79
- // Find the series object from the config.series array that has a dataKey matching the seriesKey variable.
80
- const series = config.series.find(({ dataKey }) => dataKey === seriesKey)
81
- const { axis } = series
82
-
83
- const hasMultipleSeries = Object.keys(config.runtime.seriesLabels).length > 1
84
- const labeltype = axis === 'Right' ? 'rightLabel' : 'label'
85
- let label = config.runtime.yAxis[labeltype]
86
-
87
- // if has muiltiple series dont show legend value on tooltip
88
- if (!hasMultipleSeries) label = config.isLegendValue ? config.runtime.seriesLabels[seriesKey] : label
89
-
90
117
  return (
91
118
  d[seriesKey] !== undefined &&
92
119
  d[seriesKey] !== '' &&
93
120
  d[seriesKey] !== null &&
94
121
  isNumber(d[seriesKey]) && (
95
- <Group key={`series-${seriesKey}-point-${dataIndex}`} className='checkwidth'>
96
- {/* tooltips */}
97
- <Bar key={'bars'} width={Number(xMax)} height={Number(yMax)} fill={DEBUG ? 'red' : 'transparent'} fillOpacity={0.05} onMouseMove={e => handleTooltipMouseOver(e, tableData)} onMouseOut={handleTooltipMouseOff} onClick={e => handleTooltipClick(e, data)} />
98
-
99
- {/* Render legend */}
100
- <Text display={config.labels ? 'block' : 'none'} x={xPos(d)} y={seriesAxis === 'Right' ? yScaleRight(getYAxisData(d, seriesKey)) : yScale(getYAxisData(d, seriesKey))} fill={'#000'} textAnchor='middle'>
101
- {formatNumber(d[seriesKey], 'left')}
102
- </Text>
122
+ <React.Fragment key={`series-${seriesKey}-point-${dataIndex}`}>
123
+ {/* Render label */}
124
+ {config.labels && (
125
+ <Text
126
+ x={xPos(d)}
127
+ y={
128
+ seriesAxis === 'Right'
129
+ ? yScaleRight(getYAxisData(d, seriesKey))
130
+ : yScale(getYAxisData(d, seriesKey))
131
+ }
132
+ fill={'#000'}
133
+ textAnchor='middle'
134
+ >
135
+ {formatNumber(d[seriesKey], 'left')}
136
+ </Text>
137
+ )}
103
138
 
104
- {(lineDatapointStyle === 'hidden' || lineDatapointStyle === 'always show') && (
139
+ {lineDatapointStyle === 'always show' && (
105
140
  <LineChartCircle
106
141
  mode='ALWAYS_SHOW_POINTS'
107
142
  dataIndex={dataIndex}
@@ -142,7 +177,7 @@ const LineChart = (props: LineChartProps) => {
142
177
  seriesAxis={seriesAxis}
143
178
  key={`isolated-circle-${dataIndex}`}
144
179
  />
145
- </Group>
180
+ </React.Fragment>
146
181
  )
147
182
  )
148
183
  })}
@@ -168,14 +203,18 @@ const LineChart = (props: LineChartProps) => {
168
203
  )}
169
204
  </>
170
205
  {/* SPLIT LINE */}
171
- {config?.preliminaryData?.some(pd => pd.value && pd.type) ? (
206
+ {splittedData.length > 0 ? (
172
207
  <>
173
208
  <SplitLinePath
174
209
  curve={allCurves[seriesData[0].lineType]}
175
210
  segments={data.map(d => [d])}
176
211
  segmentation='x'
177
212
  x={d => xPos(d)}
178
- y={d => (seriesAxis === 'Right' ? yScaleRight(getYAxisData(d, seriesKey)) : yScale(Number(getYAxisData(d, seriesKey))))}
213
+ y={d =>
214
+ seriesAxis === 'Right'
215
+ ? yScaleRight(getYAxisData(d, seriesKey))
216
+ : yScale(Number(getYAxisData(d, seriesKey)))
217
+ }
179
218
  styles={styles}
180
219
  defined={(item, i) => {
181
220
  return item[seriesKey] !== '' && item[seriesKey] !== null && item[seriesKey] !== undefined
@@ -188,7 +227,11 @@ const LineChart = (props: LineChartProps) => {
188
227
  key={index}
189
228
  data={segment.data}
190
229
  x={d => xPos(d)}
191
- y={d => (seriesAxis === 'Right' ? yScaleRight(getYAxisData(d, seriesKey)) : yScale(Number(getYAxisData(d, seriesKey))))}
230
+ y={d =>
231
+ seriesAxis === 'Right'
232
+ ? yScaleRight(getYAxisData(d, seriesKey))
233
+ : yScale(Number(getYAxisData(d, seriesKey)))
234
+ }
192
235
  stroke={colorScale(config.runtime.seriesLabels[seriesKey])}
193
236
  strokeWidth={seriesData[0].weight || 2}
194
237
  strokeOpacity={1}
@@ -207,7 +250,9 @@ const LineChart = (props: LineChartProps) => {
207
250
  <LinePath
208
251
  curve={allCurves[seriesData[0].lineType]}
209
252
  data={
210
- config.xAxis.type === 'date-time' || config.xAxis.type === 'date'
253
+ config.visualizationType == 'Bump Chart'
254
+ ? data
255
+ : config.xAxis.type === 'date-time' || config.xAxis.type === 'date'
211
256
  ? data.sort((d1, d2) => {
212
257
  let x1 = getXAxisData(d1)
213
258
  let x2 = getXAxisData(d2)
@@ -218,7 +263,11 @@ const LineChart = (props: LineChartProps) => {
218
263
  : data
219
264
  }
220
265
  x={d => xPos(d)}
221
- y={d => (seriesAxis === 'Right' ? yScaleRight(getYAxisData(d, seriesKey)) : yScale(Number(getYAxisData(d, seriesKey))))}
266
+ y={d =>
267
+ seriesAxis === 'Right'
268
+ ? yScaleRight(getYAxisData(d, seriesKey))
269
+ : yScale(Number(getYAxisData(d, seriesKey)))
270
+ }
222
271
  stroke={colorScale(config.runtime.seriesLabels[seriesKey])}
223
272
  strokeWidth={seriesData[0].weight || 2}
224
273
  strokeOpacity={1}
@@ -237,11 +286,21 @@ const LineChart = (props: LineChartProps) => {
237
286
  <circle
238
287
  key={i}
239
288
  cx={xPos(item.data)}
240
- cy={seriesAxis === 'Right' ? yScaleRight(getYAxisData(item.data, seriesKey)) : yScale(Number(getYAxisData(item.data, seriesKey)))}
289
+ cy={
290
+ seriesAxis === 'Right'
291
+ ? yScaleRight(getYAxisData(item.data, seriesKey))
292
+ : yScale(Number(getYAxisData(item.data, seriesKey)))
293
+ }
241
294
  r={item.size}
242
295
  strokeWidth={seriesData[0].weight || 2}
243
296
  stroke={colorScale ? colorScale(config.runtime.seriesLabels[seriesKey]) : '#000'}
244
- fill={item.isFilled ? (colorScale ? colorScale(config.runtime.seriesLabels[seriesKey]) : '#000') : '#fff'}
297
+ fill={
298
+ item.isFilled
299
+ ? colorScale
300
+ ? colorScale(config.runtime.seriesLabels[seriesKey])
301
+ : '#000'
302
+ : '#fff'
303
+ }
245
304
  />
246
305
  )
247
306
  })}
@@ -253,7 +312,11 @@ const LineChart = (props: LineChartProps) => {
253
312
  curve={allCurves[seriesData[0].lineType]}
254
313
  data={data}
255
314
  x={d => xPos(d)}
256
- y={d => (seriesAxis === 'Right' ? yScaleRight(getYAxisData(d, seriesKey)) : yScale(Number(getYAxisData(d, seriesKey))))}
315
+ y={d =>
316
+ seriesAxis === 'Right'
317
+ ? yScaleRight(getYAxisData(d, seriesKey))
318
+ : yScale(Number(getYAxisData(d, seriesKey)))
319
+ }
257
320
  stroke='#fff'
258
321
  strokeWidth={3}
259
322
  strokeOpacity={1}
@@ -278,7 +341,16 @@ const LineChart = (props: LineChartProps) => {
278
341
  return <></>
279
342
  }
280
343
  return (
281
- <text x={xPos(lastDatum) + 5} y={yScale(getYAxisData(lastDatum, seriesKey))} alignmentBaseline='middle' fill={config.colorMatchLineSeriesLabels && colorScale ? colorScale(config.runtime.seriesLabels[seriesKey] || seriesKey) : 'black'}>
344
+ <text
345
+ x={xPos(lastDatum) + 5}
346
+ y={yScale(getYAxisData(lastDatum, seriesKey))}
347
+ alignmentBaseline='middle'
348
+ fill={
349
+ config.colorMatchLineSeriesLabels && colorScale
350
+ ? colorScale(config.runtime.seriesLabels[seriesKey] || seriesKey)
351
+ : 'black'
352
+ }
353
+ >
282
354
  {config.runtime.seriesLabels[seriesKey] || seriesKey}
283
355
  </text>
284
356
  )
@@ -293,6 +365,9 @@ const LineChart = (props: LineChartProps) => {
293
365
  </Text>
294
366
  )}
295
367
  </Group>
368
+ {config.visualizationType === 'Bump Chart' && (
369
+ <LineChartBumpCircle config={config} xScale={xScale} yScale={yScale} />
370
+ )}
296
371
  </ErrorBoundary>
297
372
  )
298
373
  }