@cdc/chart 1.3.3 → 9.22.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 (42) hide show
  1. package/dist/cdcchart.js +6 -6
  2. package/examples/cutoff-example-config.json +2 -0
  3. package/examples/cutoff-example-data.json +1 -1
  4. package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json +198 -0
  5. package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json +241 -0
  6. package/examples/gallery/bar-chart-horizontal/horizontal-stacked.json +248 -0
  7. package/examples/gallery/bar-chart-vertical/combo-line-chart.json +137 -0
  8. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json +80 -0
  9. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json +81 -0
  10. package/examples/gallery/bar-chart-vertical/vertical-bar-chart-with-confidence.json +68 -0
  11. package/examples/gallery/bar-chart-vertical/vertical-bar-chart.json +111 -0
  12. package/examples/gallery/lollipop/lollipop-style-horizontal.json +220 -0
  13. package/examples/gallery/paired-bar/paired-bar-chart.json +196 -0
  14. package/examples/horizontal-chart.json +3 -0
  15. package/examples/paired-bar-data.json +1 -1
  16. package/examples/paired-bar-example.json +2 -0
  17. package/examples/planet-combo-example-config.json +2 -0
  18. package/examples/planet-example-config.json +2 -2
  19. package/examples/planet-example-data.json +1 -1
  20. package/examples/planet-pie-example-config.json +2 -0
  21. package/examples/private/line-test-data.json +22 -0
  22. package/examples/private/line-test-two.json +216 -0
  23. package/examples/private/line-test.json +102 -0
  24. package/examples/stacked-vertical-bar-example.json +228 -0
  25. package/package.json +3 -3
  26. package/src/CdcChart.tsx +79 -47
  27. package/src/components/BarChart.tsx +82 -39
  28. package/src/components/DataTable.tsx +17 -10
  29. package/src/components/EditorPanel.js +233 -169
  30. package/src/components/LineChart.tsx +3 -0
  31. package/src/components/LinearChart.tsx +171 -77
  32. package/src/components/PairedBarChart.tsx +139 -42
  33. package/src/components/PieChart.tsx +31 -6
  34. package/src/components/SparkLine.js +4 -1
  35. package/src/components/useIntersectionObserver.tsx +32 -0
  36. package/src/data/initial-state.js +17 -7
  37. package/src/hooks/useReduceData.ts +50 -23
  38. package/src/index.html +5 -9
  39. package/src/scss/editor-panel.scss +34 -4
  40. package/src/scss/main.scss +165 -5
  41. package/LICENSE +0 -201
  42. package/src/components/BarStackVertical.js +0 -0
@@ -13,8 +13,8 @@ import { BarStackHorizontal } from '@visx/shape';
13
13
 
14
14
 
15
15
 
16
- export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getXAxisData, getYAxisData }) {
17
- const { transformedData: data, colorScale, seriesHighlight, config, formatNumber, updateConfig, setParentConfig, colorPalettes,formatDate,parseDate } = useContext<any>(Context);
16
+ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getXAxisData, getYAxisData, animatedChart, visible }) {
17
+ const { transformedData: data, colorScale, seriesHighlight, config, formatNumber, updateConfig, setParentConfig, colorPalettes, formatDate, parseDate } = useContext<any>(Context);
18
18
  const { orientation, visualizationSubType } = config;
19
19
  const isHorizontal = orientation === 'horizontal';
20
20
 
@@ -33,11 +33,12 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
33
33
  const tipRounding = config.tipRounding ;
34
34
  const radius = config.roundingStyle ==='standard' ? '8px' : config.roundingStyle ==='shallow' ? '5px': config.roundingStyle ==='finger' ? '15px':'0px';
35
35
  const stackCount = config.runtime.seriesKeys.length;
36
-
36
+ const barBorderWidth = 1;
37
+
37
38
  const applyRadius = (index:number)=>{
38
39
  if(index === undefined || index === null || !isRounded) return;
39
40
  let style = {};
40
-
41
+
41
42
  if((isStacked && index+1 === stackCount) || !isStacked){
42
43
  style = isHorizontal ? {borderRadius:`0 ${radius} ${radius} 0`} : {borderRadius:`${radius} ${radius} 0 0`};
43
44
  };
@@ -45,9 +46,9 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
45
46
  style = isHorizontal ? {borderRadius:`${radius} 0 0 ${radius}`} : {borderRadius:`0 0 ${radius} ${radius}`};
46
47
  };
47
48
  if(tipRounding === 'full' && ((isStacked && index === 0 && stackCount === 1) || !isStacked)){
48
- style = {borderRadius:radius};
49
+ style = {borderRadius:radius};
49
50
  };
50
-
51
+
51
52
  return style;
52
53
  }
53
54
 
@@ -81,6 +82,15 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
81
82
  })
82
83
  }
83
84
  }, []);
85
+
86
+ useEffect(()=>{
87
+ if(config.barStyle==='lollipop' && !config.isLollipopChart ){
88
+ updateConfig({ ...config, isLollipopChart:true })
89
+ }
90
+ if( isRounded || config.barStyle==='flat' ){
91
+ updateConfig({ ...config, isLollipopChart:false })
92
+ }
93
+ },[config.barStyle])
84
94
 
85
95
  // config.runtime.seriesKeys.sort().reverse();
86
96
 
@@ -113,8 +123,20 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
113
123
  let barThickness = xMax / barStack.bars.length;
114
124
  let barThicknessAdjusted = barThickness * (config.barThickness || 0.8);
115
125
  let offset = barThickness * (1 - (config.barThickness || 0.8)) / 2;
126
+ const style = applyRadius(barStack.index)
127
+
116
128
  return (
117
- <Group key={`bar-stack-${barStack.index}-${bar.index}`}>
129
+ <>
130
+ <style>
131
+ {`
132
+ #barStack${barStack.index}-${bar.index} rect,
133
+ #barStack${barStack.index}-${bar.index} foreignObject{
134
+ animation-delay: ${barStack.index}.2s;
135
+ transform-origin: ${barThicknessAdjusted/2}px ${bar.y + bar.height}px
136
+ }
137
+ `}
138
+ </style>
139
+ <Group key={`bar-stack-${barStack.index}-${bar.index}`} id={`barStack${barStack.index}-${bar.index}`} className='stack vertical'>
118
140
  <Text
119
141
  display={config.labels && displayBar ? 'block' : 'none'}
120
142
  opacity={transparentBar ? 0.5 : 1}
@@ -124,21 +146,20 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
124
146
  textAnchor="middle">
125
147
  {formatNumber(bar.bar ? bar.bar.data[bar.key] : 0)}
126
148
  </Text>
127
- <rect
128
- key={`bar-stack-${barStack.index}-${bar.index}`}
129
- x={barThickness * bar.index + offset}
130
- y={bar.y}
131
- height={bar.height}
132
- width={barThicknessAdjusted}
133
- fill={bar.color}
134
- stroke="#333"
135
- strokeWidth={config.barBorderThickness || 1}
136
- opacity={transparentBar ? 0.5 : 1}
137
- display={displayBar ? 'block' : 'none'}
138
- data-tip={tooltip}
139
- data-for={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
140
- />
149
+ <foreignObject
150
+ key={`bar-stack-${barStack.index}-${bar.index}`}
151
+ x={barThickness * bar.index + offset}
152
+ y={bar.y}
153
+ width={barThicknessAdjusted}
154
+ height={bar.height}
155
+ style={{background:bar.color,border:`${config.barHasBorder==='true' ? barBorderWidth: 0 }px solid #333`,...style}}
156
+ opacity={transparentBar ? 0.5 : 1}
157
+ display={displayBar ? 'block' : 'none'}
158
+ data-tip={tooltip}
159
+ data-for={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
160
+ > </foreignObject>
141
161
  </Group>
162
+ </>
142
163
  )}
143
164
  ))}
144
165
  </BarStack>
@@ -163,6 +184,8 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
163
184
  const xAxisValue = config.runtime.yAxis.type==='date' ? formatDate(parseDate(data[bar.index][config.runtime.originalXAxis.dataKey])) : data[bar.index][config.runtime.originalXAxis.dataKey]
164
185
  let yAxisTooltip = config.yAxis.label ? `${config.yAxis.label}: ${formatNumber(data[bar.index][bar.key])}` : `${bar.key}: ${formatNumber(data[bar.index][bar.key])}`
165
186
  let xAxisTooltip = config.xAxis.label ? `${config.xAxis.label}: ${xAxisValue}` : xAxisValue
187
+ // let yAxisTooltip = config.yAxis.label ? `${config.yAxis.label}: ${data[bar.index][bar.key]}` : `${bar.key}: ${data[bar.index][bar.key]}`
188
+ // let xAxisTooltip = config.xAxis.label ? `${config.xAxis.label}: ${data[bar.index][config.runtime.originalXAxis.dataKey]}` :`${data[bar.index].name}`
166
189
 
167
190
  const tooltip = `<div>
168
191
  ${yAxisTooltip}<br />
@@ -175,7 +198,8 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
175
198
  let barPadding = barHeight;
176
199
 
177
200
  config.barHeight = Number(config.barHeight)
178
-
201
+ const style = applyRadius(barStack.index);
202
+
179
203
  if (orientation=== "horizontal") {
180
204
 
181
205
  if(isLabelBelowBar || isLabelMissing || isLabelOnYAxis) {
@@ -201,20 +225,19 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
201
225
 
202
226
  return (
203
227
  <Group key={index}>
204
- <rect
228
+ <foreignObject
205
229
  key={`barstack-horizontal-${barStack.index}-${bar.index}-${index}`}
230
+ className={`animated-chart group ${animatedChart ? 'animated' : ''}`}
206
231
  x={bar.x}
207
232
  y={ bar.y - config.barPadding/2 - config.barHeight/2 }
208
233
  width={bar.width}
209
234
  height={config.barHeight}
210
- fill={bar.color}
211
- stroke="#333"
212
- strokeWidth={config.barBorderThickness || 1}
235
+ style={{background:bar.color,border:`${config.barHasBorder==='true' ? barBorderWidth: 0 }px solid #333`,...style}}
213
236
  opacity={transparentBar ? 0.5 : 1}
214
237
  display={displayBar ? 'block' : 'none'}
215
238
  data-tip={tooltip}
216
239
  data-for={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
217
- />
240
+ ></foreignObject>
218
241
 
219
242
  {(orientation === 'horizontal' && visualizationSubType === 'stacked') && isLabelBelowBar && barStack.index === 0 && !config.yAxis.hideLabel &&
220
243
  <Text
@@ -272,11 +295,12 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
272
295
  color={() => {return '';}}
273
296
  >
274
297
  {(barGroups) => {
275
-
298
+ let barType = 'vertical';
276
299
  if (orientation=== "horizontal") {
277
300
  const barsPerGroup = config.series.length;
278
301
  let barHeight = config.barHeight ? config.barHeight : 25;
279
302
  let barPadding = barHeight;
303
+ barType = 'horizontal';
280
304
 
281
305
  if(isLabelBelowBar || isLabelMissing || isLabelOnYAxis) {
282
306
  if(barHeight < 40) {
@@ -297,7 +321,7 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
297
321
 
298
322
  return barGroups.map((barGroup, index) => (
299
323
  <Group
300
- className={`bar-group-${barGroup.index}-${barGroup.x0}--${index}`}
324
+ className={`bar-group-${barGroup.index}-${barGroup.x0}--${index} ${barType}`}
301
325
  key={`bar-group-${barGroup.index}-${barGroup.x0}--${index}`}
302
326
  top={config.runtime.horizontal ? yMax / barGroups.length * barGroup.index : 0}
303
327
  left={config.runtime.horizontal ? 0 : xMax / barGroups.length * barGroup.index}>
@@ -351,7 +375,19 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
351
375
  ${yAxisTooltip}<br />
352
376
  ${xAxisTooltip}<br />
353
377
  ${config.seriesLabel ? `${config.seriesLabel}: ${bar.key}` : ''}`
378
+ const style = applyRadius(index)
379
+
354
380
  return (
381
+ <>
382
+ {/* This feels gross but inline transition was not working well*/}
383
+ <style>
384
+ {`
385
+ .linear #barGroup${barGroup.index},
386
+ .Combo #barGroup${barGroup.index} {
387
+ transform-origin: 0 ${barY + barHeight}px;
388
+ }
389
+ `}
390
+ </style>
355
391
  <Group key={`bar-sub-group-${barGroup.index}-${barGroup.x0}-${barY}--${index}`}>
356
392
  <Text
357
393
  display={config.labels && displayBar ? 'block' : 'none'}
@@ -362,23 +398,27 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
362
398
  textAnchor="middle">
363
399
  {formatNumber(bar.value)}
364
400
  </Text>
365
- <rect
401
+ <foreignObject
402
+ id={`barGroup${barGroup.index}`}
403
+ className="tets"
366
404
  key={`bar-group-bar-${barGroup.index}-${bar.index}-${bar.value}-${bar.key}`}
367
405
  x={ config.runtime.horizontal ? 0 : barWidth * (barGroup.bars.length - bar.index - 1) + offset }
368
406
  y={config.runtime.horizontal ? barWidth * (barGroup.bars.length - bar.index - 1) + (config.isLollipopChart && isLabelOnYAxis ? offset : 0) : barY }
369
407
  width={config.runtime.horizontal ? bar.y : barWidth}
370
408
  height={config.runtime.horizontal ? barWidth : barHeight}
371
- fill={config.isLollipopChart && config.lollipopColorStyle === 'regular' ? barColor :
372
- config.isLollipopChart && config.lollipopColorStyle === 'two-tone' ? chroma(barColor).brighten(1) : barColor }
373
- stroke="#333"
374
- strokeWidth={config.isLollipopChart ? 0 : config.barBorderThickness || 1}
409
+ style={{
410
+ background:config.isLollipopChart && config.lollipopColorStyle === 'regular' ? barColor :
411
+ config.isLollipopChart && config.lollipopColorStyle === 'two-tone' ? chroma(barColor).brighten(1) : barColor ,
412
+ border:`${config.isLollipopChart ? 0 :config.barHasBorder==='true' ? barBorderWidth: 0 }px solid #333`,
413
+ ...style
414
+ }}
375
415
  opacity={transparentBar ? 0.5 : 1}
376
416
  display={displayBar ? 'block' : 'none'}
377
417
  data-tip={tooltip}
378
418
  data-for={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
379
- />
419
+ ></foreignObject>
380
420
  {config.isLollipopChart && config.lollipopShape === 'circle' &&
381
- <circle
421
+ <circle
382
422
  cx={orientation === 'horizontal' ? bar.y : barWidth * (barGroup.bars.length - bar.index - 1) + (isLabelBelowBar && orientation === 'horizontal' ? 0 : offset) + lollipopShapeSize/3.5}
383
423
  cy={orientation === 'horizontal' ? lollipopShapeSize/3.5 + (isLabelBelowBar && orientation === 'horizontal' ? 0: offset) : bar.y}
384
424
  r={lollipopShapeSize/2}
@@ -386,11 +426,11 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
386
426
  key={`circle--${bar.index}`}
387
427
  data-tip={tooltip}
388
428
  data-for={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
389
- style={{ 'opacity': 1, filter: 'unset' }}
429
+ style={{ 'opacity': `${config.animate ? 0 : 1}`, filter: 'unset' }}
390
430
  />
391
431
  }
392
432
  {config.isLollipopChart && config.lollipopShape === 'square' &&
393
- <rect
433
+ <rect
394
434
  x={
395
435
  (orientation === 'horizontal' && bar.y > 10) ? bar.y - lollipopShapeSize / 2 : (orientation === 'horizontal' && bar.y < 10) ? 0 :
396
436
  (orientation !== 'horizontal') ? offset - lollipopBarWidth / 2 : barWidth * (barGroup.bars.length - bar.index - 1) + offset - 5.25
@@ -404,7 +444,9 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
404
444
  data-tip={tooltip}
405
445
  data-for={`cdc-open-viz-tooltip-${config.runtime.uniqueId}`}
406
446
  style={{ 'opacity': 1, filter: 'unset' }}
407
- />
447
+ >
448
+ <animate attributeName="height" values={`0, ${lollipopShapeSize}`} dur="2.5s"/>
449
+ </rect>
408
450
  }
409
451
  {orientation === "horizontal" && textWidth + 100 < bar.y ?
410
452
  config.yAxis.labelPlacement === "On Bar" &&
@@ -541,6 +583,7 @@ export default function BarChart({ xScale, yScale, seriesScale, xMax, yMax, getX
541
583
  </>
542
584
  }
543
585
  </Group>
586
+ </>
544
587
  )}
545
588
  )}
546
589
  </Group>
@@ -141,13 +141,17 @@ export default function DataTable() {
141
141
  >
142
142
  {config.table.label}
143
143
  </div>
144
- <div className="table-container">
144
+ <div
145
+ className="table-container"
146
+ style={ { maxHeight: config.table.limitHeight && `${config.table.height}px`, overflowY: 'scroll' } }
147
+ >
145
148
  <table
146
149
  className={tableExpanded ? 'data-table' : 'data-table cdcdataviz-sr-only'}
147
150
  hidden={!tableExpanded}
148
151
  {...getTableProps()}
149
152
  aria-rowcount={ config?.series?.length ? config?.series?.length : '-1' }
150
153
  >
154
+ <caption className='cdcdataviz-sr-only'>{config.table.caption ? config.table.caption : "" }</caption>
151
155
  <caption className="visually-hidden">{config.table.label}</caption>
152
156
  <thead>
153
157
  {headerGroups.map((headerGroup,index) => (
@@ -182,15 +186,18 @@ export default function DataTable() {
182
186
  prepareRow(row);
183
187
  return (
184
188
  <tr {...row.getRowProps()} key={`tbody__tr-${index}`}>
185
- {row.cells.map((cell, index) => (
186
- <td
187
- tabIndex="0"
188
- {...cell.getCellProps()}
189
- key={`tbody__tr__td-${index}`}
190
- role="gridcell">
191
- {cell.render('Cell')}
192
- </td>
193
- ))}
189
+ {row.cells.map((cell, index) => {
190
+ return (
191
+ <td
192
+ tabIndex="0"
193
+ {...cell.getCellProps()}
194
+ key={`tbody__tr__td-${index}`}
195
+ role="gridcell">
196
+ { cell.render('Cell') }
197
+ </td>
198
+ )
199
+ }
200
+ )}
194
201
  </tr>
195
202
  );
196
203
  })}