@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.
- package/dist/cdcchart.js +6 -6
- package/examples/cutoff-example-config.json +2 -0
- package/examples/cutoff-example-data.json +1 -1
- package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart-with-numbers-on-bar.json +198 -0
- package/examples/gallery/bar-chart-horizontal/horizontal-bar-chart.json +241 -0
- package/examples/gallery/bar-chart-horizontal/horizontal-stacked.json +248 -0
- package/examples/gallery/bar-chart-vertical/combo-line-chart.json +137 -0
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-categorical.json +80 -0
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json +81 -0
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-with-confidence.json +68 -0
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart.json +111 -0
- package/examples/gallery/lollipop/lollipop-style-horizontal.json +220 -0
- package/examples/gallery/paired-bar/paired-bar-chart.json +196 -0
- package/examples/horizontal-chart.json +3 -0
- package/examples/paired-bar-data.json +1 -1
- package/examples/paired-bar-example.json +2 -0
- package/examples/planet-combo-example-config.json +2 -0
- package/examples/planet-example-config.json +2 -2
- package/examples/planet-example-data.json +1 -1
- package/examples/planet-pie-example-config.json +2 -0
- package/examples/private/line-test-data.json +22 -0
- package/examples/private/line-test-two.json +216 -0
- package/examples/private/line-test.json +102 -0
- package/examples/stacked-vertical-bar-example.json +228 -0
- package/package.json +3 -3
- package/src/CdcChart.tsx +79 -47
- package/src/components/BarChart.tsx +82 -39
- package/src/components/DataTable.tsx +17 -10
- package/src/components/EditorPanel.js +233 -169
- package/src/components/LineChart.tsx +3 -0
- package/src/components/LinearChart.tsx +171 -77
- package/src/components/PairedBarChart.tsx +139 -42
- package/src/components/PieChart.tsx +31 -6
- package/src/components/SparkLine.js +4 -1
- package/src/components/useIntersectionObserver.tsx +32 -0
- package/src/data/initial-state.js +17 -7
- package/src/hooks/useReduceData.ts +50 -23
- package/src/index.html +5 -9
- package/src/scss/editor-panel.scss +34 -4
- package/src/scss/main.scss +165 -5
- package/LICENSE +0 -201
- 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
|
-
|
|
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
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
<
|
|
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
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
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
|
})}
|