@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.
- package/dist/cdcchart.js +40313 -37543
- package/examples/cases-year.json +13379 -0
- package/examples/gallery/bar-chart-vertical/combo-line-chart.json +76 -15
- package/examples/gallery/bar-chart-vertical/vertical-bar-chart-stacked.json +5 -5
- package/index.html +17 -8
- package/package.json +2 -2
- package/src/CdcChart.tsx +383 -133
- package/src/_stories/Chart.Legend.Gradient.tsx +19 -0
- package/src/_stories/_mock/legend.gradient_mock.json +236 -0
- package/src/components/Annotations/components/AnnotationDraggable.tsx +64 -11
- package/src/components/Axis/Categorical.Axis.tsx +145 -0
- package/src/components/BarChart/components/BarChart.Horizontal.tsx +4 -3
- package/src/components/BarChart/components/BarChart.StackedHorizontal.tsx +1 -1
- package/src/components/BarChart/components/BarChart.StackedVertical.tsx +2 -5
- package/src/components/BarChart/components/BarChart.Vertical.tsx +17 -8
- package/src/components/BarChart/helpers/index.ts +5 -16
- package/src/components/BrushChart.tsx +205 -0
- package/src/components/EditorPanel/EditorPanel.tsx +1766 -509
- package/src/components/EditorPanel/components/Panels/Panel.Annotate.tsx +19 -5
- package/src/components/EditorPanel/components/Panels/Panel.General.tsx +190 -37
- package/src/components/EditorPanel/components/Panels/Panel.Sankey.tsx +43 -7
- package/src/components/EditorPanel/components/Panels/Panel.Series.tsx +4 -4
- package/src/components/EditorPanel/components/Panels/Panel.Visual.tsx +1 -11
- package/src/components/EditorPanel/editor-panel.scss +16 -3
- package/src/components/EditorPanel/{useEditorPermissions.js → useEditorPermissions.ts} +90 -19
- package/src/components/Legend/Legend.Component.tsx +185 -193
- package/src/components/Legend/Legend.Suppression.tsx +146 -0
- package/src/components/Legend/Legend.tsx +21 -5
- package/src/components/Legend/helpers/index.ts +33 -3
- package/src/components/LegendWrapper.tsx +26 -0
- package/src/components/LineChart/LineChartProps.ts +1 -18
- package/src/components/LineChart/components/LineChart.BumpCircle.tsx +103 -0
- package/src/components/LineChart/components/LineChart.Circle.tsx +47 -8
- package/src/components/LineChart/helpers.ts +55 -11
- package/src/components/LineChart/index.tsx +113 -38
- package/src/components/LinearChart.tsx +1366 -0
- package/src/components/PieChart/PieChart.tsx +74 -17
- package/src/components/Sankey/index.tsx +22 -16
- package/src/components/Sparkline/components/SparkLine.tsx +2 -2
- package/src/data/initial-state.js +13 -3
- package/src/hooks/useLegendClasses.ts +52 -15
- package/src/hooks/useMinMax.ts +4 -4
- package/src/hooks/useScales.ts +34 -24
- package/src/hooks/useTooltip.tsx +85 -22
- package/src/scss/DataTable.scss +2 -1
- package/src/scss/main.scss +107 -14
- package/src/types/ChartConfig.ts +34 -8
- package/src/types/ChartContext.ts +5 -4
- package/examples/feature/line/line-chart.json +0 -449
- package/src/components/BrushHandle.jsx +0 -17
- 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 =
|
|
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({
|
|
66
|
-
|
|
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={
|
|
76
|
-
|
|
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
|
-
<
|
|
96
|
-
{/*
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
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
|
-
{
|
|
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
|
-
</
|
|
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
|
-
{
|
|
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 =>
|
|
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 =>
|
|
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.
|
|
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 =>
|
|
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={
|
|
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={
|
|
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 =>
|
|
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
|
|
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
|
}
|