@wavemaker/react-native-echarts 1.0.0-dev.0
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/.npmignore +4 -0
- package/LICENSE +21 -0
- package/README.md +39 -0
- package/area/area-chart.d.ts +12 -0
- package/area/area-chart.d.ts.map +1 -0
- package/area/area-chart.js +404 -0
- package/area/area-chart.props.d.ts +64 -0
- package/area/area-chart.props.d.ts.map +1 -0
- package/area/area-chart.props.js +0 -0
- package/area/index.d.ts +3 -0
- package/area/index.d.ts.map +1 -0
- package/area/index.js +1 -0
- package/axis.d.ts +3 -0
- package/axis.d.ts.map +1 -0
- package/axis.js +16 -0
- package/bar/bar-chart.d.ts +11 -0
- package/bar/bar-chart.d.ts.map +1 -0
- package/bar/bar-chart.js +6 -0
- package/bar/bar-chart.props.d.ts +7 -0
- package/bar/bar-chart.props.d.ts.map +1 -0
- package/bar/bar-chart.props.js +0 -0
- package/bar/index.d.ts +3 -0
- package/bar/index.d.ts.map +1 -0
- package/bar/index.js +1 -0
- package/bubble/bubble-chart.d.ts +13 -0
- package/bubble/bubble-chart.d.ts.map +1 -0
- package/bubble/bubble-chart.js +305 -0
- package/bubble/bubble-chart.props.d.ts +26 -0
- package/bubble/bubble-chart.props.d.ts.map +1 -0
- package/bubble/bubble-chart.props.js +0 -0
- package/bubble/index.d.ts +3 -0
- package/bubble/index.d.ts.map +1 -0
- package/bubble/index.js +1 -0
- package/candlestick/candlestick-chart.d.ts +12 -0
- package/candlestick/candlestick-chart.d.ts.map +1 -0
- package/candlestick/candlestick-chart.js +292 -0
- package/candlestick/candlestick-chart.props.d.ts +51 -0
- package/candlestick/candlestick-chart.props.d.ts.map +1 -0
- package/candlestick/candlestick-chart.props.js +0 -0
- package/candlestick/index.d.ts +3 -0
- package/candlestick/index.d.ts.map +1 -0
- package/candlestick/index.js +1 -0
- package/chart-container.d.ts +6 -0
- package/chart-container.d.ts.map +1 -0
- package/chart-container.js +63 -0
- package/chart-theme.context.d.ts +191 -0
- package/chart-theme.context.d.ts.map +1 -0
- package/chart-theme.context.js +276 -0
- package/column/column-chart.d.ts +13 -0
- package/column/column-chart.d.ts.map +1 -0
- package/column/column-chart.js +481 -0
- package/column/column-chart.props.d.ts +83 -0
- package/column/column-chart.props.d.ts.map +1 -0
- package/column/column-chart.props.js +0 -0
- package/column/index.d.ts +3 -0
- package/column/index.d.ts.map +1 -0
- package/column/index.js +1 -0
- package/gauge/digital/digital.gauge.d.ts +28 -0
- package/gauge/digital/digital.gauge.d.ts.map +1 -0
- package/gauge/digital/digital.gauge.js +213 -0
- package/gauge/gauge.types.d.ts +51 -0
- package/gauge/gauge.types.d.ts.map +1 -0
- package/gauge/gauge.types.js +0 -0
- package/gauge/index.d.ts +6 -0
- package/gauge/index.d.ts.map +1 -0
- package/gauge/index.js +4 -0
- package/gauge/radial/radial.gauge.d.ts +18 -0
- package/gauge/radial/radial.gauge.d.ts.map +1 -0
- package/gauge/radial/radial.gauge.js +284 -0
- package/gauge/simple/simple.gauge.d.ts +28 -0
- package/gauge/simple/simple.gauge.d.ts.map +1 -0
- package/gauge/simple/simple.gauge.js +102 -0
- package/gauge/speedometer/speedometer.gauge.d.ts +35 -0
- package/gauge/speedometer/speedometer.gauge.d.ts.map +1 -0
- package/gauge/speedometer/speedometer.gauge.js +241 -0
- package/geo/geo-chart.d.ts +15 -0
- package/geo/geo-chart.d.ts.map +1 -0
- package/geo/geo-chart.js +200 -0
- package/geo/geo-chart.props.d.ts +96 -0
- package/geo/geo-chart.props.d.ts.map +1 -0
- package/geo/geo-chart.props.js +0 -0
- package/geo/index.d.ts +7 -0
- package/geo/index.d.ts.map +1 -0
- package/geo/index.js +3 -0
- package/geo/us-chart.d.ts +15 -0
- package/geo/us-chart.d.ts.map +1 -0
- package/geo/us-chart.js +15 -0
- package/geo/world-chart.d.ts +15 -0
- package/geo/world-chart.d.ts.map +1 -0
- package/geo/world-chart.js +10 -0
- package/index.d.ts +17 -0
- package/index.d.ts.map +1 -0
- package/index.js +15 -0
- package/line/index.d.ts +3 -0
- package/line/index.d.ts.map +1 -0
- package/line/index.js +1 -0
- package/line/line-chart.d.ts +9 -0
- package/line/line-chart.d.ts.map +1 -0
- package/line/line-chart.js +8 -0
- package/line/line-chart.props.d.ts +12 -0
- package/line/line-chart.props.d.ts.map +1 -0
- package/line/line-chart.props.js +0 -0
- package/package.json +39 -0
- package/pie/index.d.ts +4 -0
- package/pie/index.d.ts.map +1 -0
- package/pie/index.js +2 -0
- package/pie/pie-chart.d.ts +13 -0
- package/pie/pie-chart.d.ts.map +1 -0
- package/pie/pie-chart.js +222 -0
- package/pie/pie-chart.props.d.ts +97 -0
- package/pie/pie-chart.props.d.ts.map +1 -0
- package/pie/pie-chart.props.js +12 -0
- package/props/cartesian.d.ts +120 -0
- package/props/cartesian.d.ts.map +1 -0
- package/props/cartesian.js +0 -0
- package/props/common.d.ts +28 -0
- package/props/common.d.ts.map +1 -0
- package/props/common.js +0 -0
- package/radar/index.d.ts +3 -0
- package/radar/index.d.ts.map +1 -0
- package/radar/index.js +1 -0
- package/radar/radar-chart.d.ts +12 -0
- package/radar/radar-chart.d.ts.map +1 -0
- package/radar/radar-chart.js +197 -0
- package/radar/radar-chart.props.d.ts +80 -0
- package/radar/radar-chart.props.d.ts.map +1 -0
- package/radar/radar-chart.props.js +0 -0
- package/radial/index.d.ts +3 -0
- package/radial/index.d.ts.map +1 -0
- package/radial/index.js +1 -0
- package/radial/radial-chart.d.ts +12 -0
- package/radial/radial-chart.d.ts.map +1 -0
- package/radial/radial-chart.js +235 -0
- package/radial/radial-chart.props.d.ts +74 -0
- package/radial/radial-chart.props.d.ts.map +1 -0
- package/radial/radial-chart.props.js +0 -0
- package/scatter/index.d.ts +3 -0
- package/scatter/index.d.ts.map +1 -0
- package/scatter/index.js +1 -0
- package/scatter/scatter-chart.d.ts +13 -0
- package/scatter/scatter-chart.d.ts.map +1 -0
- package/scatter/scatter-chart.js +310 -0
- package/scatter/scatter-chart.props.d.ts +36 -0
- package/scatter/scatter-chart.props.d.ts.map +1 -0
- package/scatter/scatter-chart.props.js +0 -0
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
import { withResponsiveContainer } from '../chart-container';
|
|
2
|
+
import { useChartTheme, withChartTheme } from '../chart-theme.context';
|
|
3
|
+
import { SkiaChart, SkiaRenderer } from '@wuba/react-native-echarts';
|
|
4
|
+
import { BarChart as EChartsBarChart } from 'echarts/charts';
|
|
5
|
+
import { GridComponent, LegendComponent, TooltipComponent, } from 'echarts/components';
|
|
6
|
+
import * as echarts from 'echarts/core';
|
|
7
|
+
import React, { useEffect, useMemo, useRef } from 'react';
|
|
8
|
+
import { getAxis } from '../axis';
|
|
9
|
+
echarts.use([
|
|
10
|
+
TooltipComponent,
|
|
11
|
+
GridComponent,
|
|
12
|
+
LegendComponent,
|
|
13
|
+
SkiaRenderer,
|
|
14
|
+
EChartsBarChart,
|
|
15
|
+
]);
|
|
16
|
+
const ChartComponent = ({ data, width = 220, height = 350, boundaryGap = true, cornerRadius = [4, 4, 0, 0], horizontal = false, stack, stackNormalize = false, activeIndex, activeColor, barInsideLabelPosition = 'start', barInsideLabelFormatter, barOutsideLabelPosition = 'start', barOutsideLabelFormatter, itemStyle, showXAxis = true, showXAxisTicks = true, showYAxis = true, showYAxisTicks = true, showXAxisSplitLines = true, showYAxisSplitLines = true, grid, showLegend = false, showHighlighter = true, xAxisTickLabelFormatter, yAxisTickLabelFormatter, xAxisTicks, xAxisLabel, yAxisLabel, onSelect, ...props }) => {
|
|
17
|
+
const { theme } = useChartTheme(props.theme, props.colors);
|
|
18
|
+
const chartRef = useRef(null);
|
|
19
|
+
const onSelectRef = useRef(onSelect);
|
|
20
|
+
onSelectRef.current = onSelect;
|
|
21
|
+
const selectContextRef = useRef({ displaySeries: [], labelOverlayDuplicate: false });
|
|
22
|
+
const normalizedSeries = useMemo(() => {
|
|
23
|
+
let normalizedData = [];
|
|
24
|
+
if (!Array.isArray(data) || data.length === 0)
|
|
25
|
+
return normalizedData;
|
|
26
|
+
const first = data[0];
|
|
27
|
+
if (typeof first === 'number') {
|
|
28
|
+
normalizedData = [
|
|
29
|
+
{
|
|
30
|
+
name: 'Series 1',
|
|
31
|
+
data: data.map((value, index) => [String(index), value]),
|
|
32
|
+
},
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
else if (Array.isArray(first) && first.length === 2) {
|
|
36
|
+
normalizedData = [{ name: 'Series 1', data: data }];
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
normalizedData = JSON.parse(JSON.stringify(data))
|
|
40
|
+
.filter((item) => item.data && item.data.length > 0)
|
|
41
|
+
.map((item, index) => {
|
|
42
|
+
const firstItem = item.data[0];
|
|
43
|
+
if (typeof firstItem === 'number') {
|
|
44
|
+
item.data = item.data.map((value, i) => [
|
|
45
|
+
String(i),
|
|
46
|
+
value,
|
|
47
|
+
]);
|
|
48
|
+
}
|
|
49
|
+
return {
|
|
50
|
+
name: item.name || 'Series ' + (index + 1),
|
|
51
|
+
data: [...item.data],
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
return normalizedData;
|
|
56
|
+
}, [data]);
|
|
57
|
+
const hasNamedSeries = useMemo(() => normalizedSeries.some((s) => 'name' in s && s.name), [normalizedSeries]);
|
|
58
|
+
const displaySeries = useMemo(() => {
|
|
59
|
+
if (!stackNormalize || normalizedSeries.length <= 1)
|
|
60
|
+
return normalizedSeries;
|
|
61
|
+
const len = normalizedSeries[0]?.data?.length ?? 0;
|
|
62
|
+
if (len === 0)
|
|
63
|
+
return normalizedSeries;
|
|
64
|
+
return normalizedSeries.map((s) => {
|
|
65
|
+
const rawData = s.data;
|
|
66
|
+
const sumsAt = new Array(len).fill(0);
|
|
67
|
+
normalizedSeries.forEach((other) => {
|
|
68
|
+
const d = 'data' in other ? other.data : [];
|
|
69
|
+
d.forEach((v, i) => {
|
|
70
|
+
if (i < len)
|
|
71
|
+
sumsAt[i] += typeof v === 'number' ? v : v[1];
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
const normalizedData = rawData.map((v, i) => {
|
|
75
|
+
const val = typeof v === 'number' ? v : v[1];
|
|
76
|
+
const sum = sumsAt[i] || 1;
|
|
77
|
+
return sum > 0 ? (val / sum) * 100 : 0;
|
|
78
|
+
});
|
|
79
|
+
return {
|
|
80
|
+
name: s.name,
|
|
81
|
+
data: rawData.map((v, i) => [v[0], normalizedData[i]]),
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
}, [normalizedSeries, stackNormalize]);
|
|
85
|
+
const showLabelInside = barInsideLabelFormatter != null;
|
|
86
|
+
const showLabelOutside = barOutsideLabelFormatter != null;
|
|
87
|
+
const isSingleSeries = displaySeries.length === 1;
|
|
88
|
+
const labelOverlayDuplicate = showLabelInside && showLabelOutside && isSingleSeries;
|
|
89
|
+
selectContextRef.current = { displaySeries, labelOverlayDuplicate };
|
|
90
|
+
const option = useMemo(() => {
|
|
91
|
+
const categories = (displaySeries[0]?.data ?? []).map((item) => String(item[0]));
|
|
92
|
+
const dataPoints = displaySeries.flatMap((s) => s.data.map((d) => d[1]));
|
|
93
|
+
const xAxisData = xAxisTicks != null && xAxisTicks.length > 0
|
|
94
|
+
? xAxisTicks
|
|
95
|
+
: categories.length > 0
|
|
96
|
+
? categories
|
|
97
|
+
: getAxis(dataPoints).map(String);
|
|
98
|
+
const tooltipConfig = showHighlighter
|
|
99
|
+
? {
|
|
100
|
+
trigger: 'axis',
|
|
101
|
+
axisPointer: {
|
|
102
|
+
type: 'shadow',
|
|
103
|
+
shadowStyle: {
|
|
104
|
+
color: 'rgba(0,0,0,0.08)',
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
}
|
|
108
|
+
: { trigger: 'axis' };
|
|
109
|
+
const categoryAxisConfig = {
|
|
110
|
+
type: 'category',
|
|
111
|
+
data: xAxisData,
|
|
112
|
+
boundaryGap,
|
|
113
|
+
...((horizontal ? yAxisLabel : xAxisLabel) != null && (horizontal ? yAxisLabel : xAxisLabel) !== '' && {
|
|
114
|
+
name: horizontal ? yAxisLabel : xAxisLabel,
|
|
115
|
+
nameLocation: 'middle',
|
|
116
|
+
nameGap: 25,
|
|
117
|
+
nameTextStyle: { color: horizontal ? theme.axis.y.tickLabelColor : theme.axis.x.tickLabelColor },
|
|
118
|
+
}),
|
|
119
|
+
axisLabel: {
|
|
120
|
+
show: showXAxis || xAxisTickLabelFormatter != null,
|
|
121
|
+
color: theme.axis.x.tickLabelColor,
|
|
122
|
+
formatter: xAxisTickLabelFormatter ?? undefined,
|
|
123
|
+
},
|
|
124
|
+
axisLine: showXAxis
|
|
125
|
+
? {
|
|
126
|
+
show: true,
|
|
127
|
+
lineStyle: {
|
|
128
|
+
color: theme.axis.x.lineColor,
|
|
129
|
+
width: theme.axis.x.lineWidth,
|
|
130
|
+
},
|
|
131
|
+
}
|
|
132
|
+
: { show: false },
|
|
133
|
+
axisTick: {
|
|
134
|
+
show: showXAxis && showXAxisTicks,
|
|
135
|
+
lineStyle: {
|
|
136
|
+
color: theme.axis.x.tickColor,
|
|
137
|
+
width: theme.axis.x.tickWidth,
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
splitLine: {
|
|
141
|
+
show: showXAxisSplitLines,
|
|
142
|
+
lineStyle: {
|
|
143
|
+
color: theme.axis.x.splitLineColor,
|
|
144
|
+
width: theme.axis.x.splitLineWidth,
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
};
|
|
148
|
+
const valueAxisConfig = {
|
|
149
|
+
type: 'value',
|
|
150
|
+
...(stackNormalize &&
|
|
151
|
+
displaySeries.length > 1 && {
|
|
152
|
+
min: 0,
|
|
153
|
+
max: 100,
|
|
154
|
+
}),
|
|
155
|
+
...((horizontal ? xAxisLabel : yAxisLabel) != null && (horizontal ? xAxisLabel : yAxisLabel) !== '' && {
|
|
156
|
+
name: horizontal ? xAxisLabel : yAxisLabel,
|
|
157
|
+
nameLocation: 'middle',
|
|
158
|
+
nameGap: 40,
|
|
159
|
+
nameTextStyle: { color: horizontal ? theme.axis.x.tickLabelColor : theme.axis.y.tickLabelColor },
|
|
160
|
+
}),
|
|
161
|
+
axisLabel: {
|
|
162
|
+
show: showYAxis || yAxisTickLabelFormatter != null,
|
|
163
|
+
color: theme.axis.y.tickLabelColor,
|
|
164
|
+
formatter: yAxisTickLabelFormatter ??
|
|
165
|
+
(stackNormalize && displaySeries.length > 1
|
|
166
|
+
? (value) => `${value}%`
|
|
167
|
+
: undefined),
|
|
168
|
+
},
|
|
169
|
+
axisLine: showYAxis
|
|
170
|
+
? {
|
|
171
|
+
show: true,
|
|
172
|
+
lineStyle: {
|
|
173
|
+
color: theme.axis.y.lineColor,
|
|
174
|
+
width: theme.axis.y.lineWidth,
|
|
175
|
+
},
|
|
176
|
+
}
|
|
177
|
+
: { show: false },
|
|
178
|
+
axisTick: {
|
|
179
|
+
show: showYAxis && showYAxisTicks,
|
|
180
|
+
lineStyle: {
|
|
181
|
+
color: theme.axis.y.tickColor,
|
|
182
|
+
width: theme.axis.y.tickWidth,
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
splitLine: {
|
|
186
|
+
show: showYAxisSplitLines,
|
|
187
|
+
lineStyle: {
|
|
188
|
+
color: theme.axis.y.splitLineColor,
|
|
189
|
+
width: theme.axis.y.splitLineWidth,
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
};
|
|
193
|
+
const xAxisConfig = horizontal ? valueAxisConfig : categoryAxisConfig;
|
|
194
|
+
const yAxisConfig = horizontal ? categoryAxisConfig : valueAxisConfig;
|
|
195
|
+
const legendConfig = showLegend && hasNamedSeries
|
|
196
|
+
? {
|
|
197
|
+
data: normalizedSeries
|
|
198
|
+
.filter((s) => 'name' in s && s.name)
|
|
199
|
+
.map((s) => s.name),
|
|
200
|
+
textStyle: {
|
|
201
|
+
color: theme.legend.textColor,
|
|
202
|
+
fontSize: theme.legend.fontSize,
|
|
203
|
+
},
|
|
204
|
+
backgroundColor: theme.legend.backgroundColor,
|
|
205
|
+
}
|
|
206
|
+
: undefined;
|
|
207
|
+
const isDefaultVerticalRadius = Array.isArray(cornerRadius) &&
|
|
208
|
+
cornerRadius[0] === 4 &&
|
|
209
|
+
cornerRadius[1] === 4 &&
|
|
210
|
+
cornerRadius[2] === 0 &&
|
|
211
|
+
cornerRadius[3] === 0;
|
|
212
|
+
const effectiveCornerRadius = horizontal
|
|
213
|
+
? isDefaultVerticalRadius
|
|
214
|
+
? [0, 4, 4, 0]
|
|
215
|
+
: Array.isArray(cornerRadius)
|
|
216
|
+
? cornerRadius
|
|
217
|
+
: [0, cornerRadius, cornerRadius, 0]
|
|
218
|
+
: Array.isArray(cornerRadius)
|
|
219
|
+
? cornerRadius
|
|
220
|
+
: [cornerRadius, cornerRadius, cornerRadius, cornerRadius];
|
|
221
|
+
const isStacked = (stack !== undefined && stack !== false) ||
|
|
222
|
+
(stackNormalize && displaySeries.length > 1);
|
|
223
|
+
const showLabelInside = barInsideLabelFormatter != null;
|
|
224
|
+
const showLabelOutside = barOutsideLabelFormatter != null;
|
|
225
|
+
const isSingleSeries = displaySeries.length === 1;
|
|
226
|
+
const insideLabelPositionMap = horizontal
|
|
227
|
+
? { start: 'insideLeft', middle: 'inside', end: 'insideRight' }
|
|
228
|
+
: { start: 'insideLeft', middle: 'inside', end: 'insideRight' };
|
|
229
|
+
const outsideLabelPositionMap = horizontal
|
|
230
|
+
? { start: 'right', end: 'left' }
|
|
231
|
+
: { start: 'top', end: 'bottom' };
|
|
232
|
+
const resolveInsidePosition = (value, index, category) => {
|
|
233
|
+
const pos = typeof barInsideLabelPosition === 'function'
|
|
234
|
+
? barInsideLabelPosition(value, index, category)
|
|
235
|
+
: barInsideLabelPosition;
|
|
236
|
+
return insideLabelPositionMap[pos] ?? 'insideLeft';
|
|
237
|
+
};
|
|
238
|
+
const resolveOutsidePosition = (value, index, category) => {
|
|
239
|
+
const pos = typeof barOutsideLabelPosition === 'function'
|
|
240
|
+
? barOutsideLabelPosition(value, index, category)
|
|
241
|
+
: barOutsideLabelPosition;
|
|
242
|
+
return outsideLabelPositionMap[pos] ?? (horizontal ? 'right' : 'top');
|
|
243
|
+
};
|
|
244
|
+
const echartsInsidePosition = typeof barInsideLabelPosition === 'function'
|
|
245
|
+
? undefined
|
|
246
|
+
: (insideLabelPositionMap[barInsideLabelPosition] ?? 'insideLeft');
|
|
247
|
+
const echartsOutsidePosition = typeof barOutsideLabelPosition === 'function'
|
|
248
|
+
? undefined
|
|
249
|
+
: (outsideLabelPositionMap[barOutsideLabelPosition] ?? (horizontal ? 'right' : 'top'));
|
|
250
|
+
const seriesConfig = displaySeries.map((s, index) => {
|
|
251
|
+
const seriesColor = theme.series[index % theme.series.length].color;
|
|
252
|
+
const isEndBar = index === displaySeries.length - 1;
|
|
253
|
+
const barBorderRadius = isStacked && !isEndBar ? [0, 0, 0, 0] : effectiveCornerRadius;
|
|
254
|
+
const isSingle = displaySeries.length === 1;
|
|
255
|
+
const showActive = isSingle &&
|
|
256
|
+
activeIndex != null &&
|
|
257
|
+
activeIndex >= 0 &&
|
|
258
|
+
activeIndex < s.data.length;
|
|
259
|
+
const effectiveActiveColor = activeColor ?? seriesColor;
|
|
260
|
+
const useItemStyleFn = isSingle && itemStyle != null;
|
|
261
|
+
const baseItemStyle = {
|
|
262
|
+
color: seriesColor,
|
|
263
|
+
borderRadius: barBorderRadius,
|
|
264
|
+
};
|
|
265
|
+
const barData = showActive
|
|
266
|
+
? s.data.map((d, i) => {
|
|
267
|
+
const value = d[1];
|
|
268
|
+
if (i === activeIndex) {
|
|
269
|
+
return {
|
|
270
|
+
value,
|
|
271
|
+
itemStyle: {
|
|
272
|
+
color: effectiveActiveColor,
|
|
273
|
+
borderColor: effectiveActiveColor,
|
|
274
|
+
borderWidth: 2,
|
|
275
|
+
borderType: 'dashed',
|
|
276
|
+
borderRadius: barBorderRadius,
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
const override = itemStyle ? itemStyle(value, i) : {};
|
|
281
|
+
return {
|
|
282
|
+
value,
|
|
283
|
+
itemStyle: { ...baseItemStyle, ...override },
|
|
284
|
+
};
|
|
285
|
+
})
|
|
286
|
+
: useItemStyleFn
|
|
287
|
+
? s.data.map((d, i) => {
|
|
288
|
+
const value = d[1];
|
|
289
|
+
const override = itemStyle(value, i);
|
|
290
|
+
return {
|
|
291
|
+
value,
|
|
292
|
+
itemStyle: { ...baseItemStyle, ...override },
|
|
293
|
+
};
|
|
294
|
+
})
|
|
295
|
+
: s.data.map((d) => d[1]);
|
|
296
|
+
const labelConfig = {};
|
|
297
|
+
if (showLabelInside && isSingleSeries && barInsideLabelFormatter) {
|
|
298
|
+
labelConfig.show = true;
|
|
299
|
+
labelConfig.position =
|
|
300
|
+
typeof barInsideLabelPosition === 'function'
|
|
301
|
+
? (params) => resolveInsidePosition(params.value, params.dataIndex, categories[params.dataIndex])
|
|
302
|
+
: echartsInsidePosition;
|
|
303
|
+
labelConfig.color = '#fff';
|
|
304
|
+
labelConfig.formatter = (params) => barInsideLabelFormatter(params.value, params.dataIndex, categories[params.dataIndex]);
|
|
305
|
+
}
|
|
306
|
+
else if (showLabelOutside &&
|
|
307
|
+
isSingleSeries &&
|
|
308
|
+
barOutsideLabelFormatter &&
|
|
309
|
+
!(showLabelInside && barInsideLabelFormatter)) {
|
|
310
|
+
labelConfig.show = true;
|
|
311
|
+
labelConfig.position =
|
|
312
|
+
typeof barOutsideLabelPosition === 'function'
|
|
313
|
+
? (params) => resolveOutsidePosition(params.value, params.dataIndex, categories[params.dataIndex])
|
|
314
|
+
: echartsOutsidePosition;
|
|
315
|
+
labelConfig.formatter = (params) => barOutsideLabelFormatter(params.value, params.dataIndex, categories[params.dataIndex]);
|
|
316
|
+
}
|
|
317
|
+
const barSeries = {
|
|
318
|
+
type: 'bar',
|
|
319
|
+
data: barData,
|
|
320
|
+
itemStyle: showActive || useItemStyleFn
|
|
321
|
+
? undefined
|
|
322
|
+
: {
|
|
323
|
+
color: seriesColor,
|
|
324
|
+
borderRadius: barBorderRadius,
|
|
325
|
+
},
|
|
326
|
+
emphasis: showHighlighter
|
|
327
|
+
? {
|
|
328
|
+
focus: 'self',
|
|
329
|
+
itemStyle: {
|
|
330
|
+
color: seriesColor,
|
|
331
|
+
borderColor: '#fff',
|
|
332
|
+
borderWidth: 1,
|
|
333
|
+
},
|
|
334
|
+
}
|
|
335
|
+
: { focus: 'none' },
|
|
336
|
+
};
|
|
337
|
+
if (Object.keys(labelConfig).length > 0)
|
|
338
|
+
barSeries.label = labelConfig;
|
|
339
|
+
if (s.name)
|
|
340
|
+
barSeries.name = s.name;
|
|
341
|
+
if (stack !== undefined && stack !== false) {
|
|
342
|
+
barSeries.stack = typeof stack === 'string' ? stack : 'total';
|
|
343
|
+
}
|
|
344
|
+
else if (stackNormalize && displaySeries.length > 1) {
|
|
345
|
+
barSeries.stack = 'total';
|
|
346
|
+
}
|
|
347
|
+
return barSeries;
|
|
348
|
+
});
|
|
349
|
+
// When both inside and outside formatters are set, add a second series for outside labels (transparent bars)
|
|
350
|
+
if (showLabelInside && showLabelOutside && isSingleSeries && seriesConfig.length > 0) {
|
|
351
|
+
const first = seriesConfig[0];
|
|
352
|
+
const labelOnlySeries = {
|
|
353
|
+
type: 'bar',
|
|
354
|
+
data: first.data,
|
|
355
|
+
barGap: '-100%',
|
|
356
|
+
itemStyle: { color: 'transparent', borderColor: 'transparent' },
|
|
357
|
+
label: {
|
|
358
|
+
show: true,
|
|
359
|
+
position: typeof barOutsideLabelPosition === 'function'
|
|
360
|
+
? (params) => resolveOutsidePosition(params.value, params.dataIndex, categories[params.dataIndex])
|
|
361
|
+
: echartsOutsidePosition,
|
|
362
|
+
color: theme.axis.x?.tickLabelColor ?? '#333',
|
|
363
|
+
formatter: (params) => barOutsideLabelFormatter(params.value, params.dataIndex, categories[params.dataIndex]),
|
|
364
|
+
},
|
|
365
|
+
emphasis: { focus: 'none' },
|
|
366
|
+
tooltip: { show: false },
|
|
367
|
+
};
|
|
368
|
+
seriesConfig.push(labelOnlySeries);
|
|
369
|
+
}
|
|
370
|
+
const config = {
|
|
371
|
+
tooltip: tooltipConfig,
|
|
372
|
+
xAxis: xAxisConfig,
|
|
373
|
+
yAxis: yAxisConfig,
|
|
374
|
+
series: seriesConfig,
|
|
375
|
+
};
|
|
376
|
+
if (legendConfig)
|
|
377
|
+
config.legend = legendConfig;
|
|
378
|
+
if (grid)
|
|
379
|
+
config.grid = grid;
|
|
380
|
+
return config;
|
|
381
|
+
}, [
|
|
382
|
+
theme,
|
|
383
|
+
normalizedSeries,
|
|
384
|
+
displaySeries,
|
|
385
|
+
boundaryGap,
|
|
386
|
+
cornerRadius,
|
|
387
|
+
horizontal,
|
|
388
|
+
stack,
|
|
389
|
+
stackNormalize,
|
|
390
|
+
activeIndex,
|
|
391
|
+
activeColor,
|
|
392
|
+
barInsideLabelPosition,
|
|
393
|
+
barInsideLabelFormatter,
|
|
394
|
+
barOutsideLabelPosition,
|
|
395
|
+
barOutsideLabelFormatter,
|
|
396
|
+
itemStyle,
|
|
397
|
+
showXAxis,
|
|
398
|
+
showXAxisTicks,
|
|
399
|
+
showYAxis,
|
|
400
|
+
showYAxisTicks,
|
|
401
|
+
showXAxisSplitLines,
|
|
402
|
+
showYAxisSplitLines,
|
|
403
|
+
grid,
|
|
404
|
+
showLegend,
|
|
405
|
+
hasNamedSeries,
|
|
406
|
+
showHighlighter,
|
|
407
|
+
xAxisTickLabelFormatter,
|
|
408
|
+
yAxisTickLabelFormatter,
|
|
409
|
+
xAxisTicks,
|
|
410
|
+
xAxisLabel,
|
|
411
|
+
yAxisLabel,
|
|
412
|
+
]);
|
|
413
|
+
useEffect(() => {
|
|
414
|
+
let chart;
|
|
415
|
+
if (chartRef.current) {
|
|
416
|
+
try {
|
|
417
|
+
chart = echarts.init(chartRef.current, 'light', { width, height });
|
|
418
|
+
chart.setOption(option);
|
|
419
|
+
const handleSeriesClick = (params) => {
|
|
420
|
+
const cb = onSelectRef.current;
|
|
421
|
+
if (typeof cb !== 'function')
|
|
422
|
+
return;
|
|
423
|
+
if (params.componentType !== 'series')
|
|
424
|
+
return;
|
|
425
|
+
if (params.seriesType !== 'bar')
|
|
426
|
+
return;
|
|
427
|
+
let seriesIndex = params.seriesIndex;
|
|
428
|
+
const dataIndex = params.dataIndex;
|
|
429
|
+
if (typeof seriesIndex !== 'number' ||
|
|
430
|
+
typeof dataIndex !== 'number' ||
|
|
431
|
+
dataIndex < 0) {
|
|
432
|
+
return;
|
|
433
|
+
}
|
|
434
|
+
const { displaySeries: ds, labelOverlayDuplicate: overlay } = selectContextRef.current;
|
|
435
|
+
if (overlay && seriesIndex === 1)
|
|
436
|
+
seriesIndex = 0;
|
|
437
|
+
const s = ds[seriesIndex];
|
|
438
|
+
if (!s?.data || !Array.isArray(s.data))
|
|
439
|
+
return;
|
|
440
|
+
const row = s.data[dataIndex];
|
|
441
|
+
if (row === undefined)
|
|
442
|
+
return;
|
|
443
|
+
const seriesName = s.name != null && s.name !== ''
|
|
444
|
+
? String(s.name)
|
|
445
|
+
: `Series ${seriesIndex + 1}`;
|
|
446
|
+
if (!Array.isArray(row) || row.length < 2)
|
|
447
|
+
return;
|
|
448
|
+
const x = row[0];
|
|
449
|
+
const y = Number(row[1]);
|
|
450
|
+
const event = {
|
|
451
|
+
seriesIndex,
|
|
452
|
+
dataIndex,
|
|
453
|
+
seriesName,
|
|
454
|
+
x,
|
|
455
|
+
y,
|
|
456
|
+
};
|
|
457
|
+
cb(event);
|
|
458
|
+
};
|
|
459
|
+
chart.on('click', handleSeriesClick);
|
|
460
|
+
}
|
|
461
|
+
catch (error) {
|
|
462
|
+
console.warn('Chart initialization error:', error);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return () => {
|
|
466
|
+
if (chart) {
|
|
467
|
+
try {
|
|
468
|
+
chart.dispose();
|
|
469
|
+
}
|
|
470
|
+
catch (error) {
|
|
471
|
+
console.warn('Chart disposal error:', error);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
}, [option, width, height]);
|
|
476
|
+
return <SkiaChart ref={chartRef} useRNGH/>;
|
|
477
|
+
};
|
|
478
|
+
const ColumnChartComponent = withResponsiveContainer(withChartTheme(ChartComponent));
|
|
479
|
+
export const ColumnChart = Object.assign(ColumnChartComponent, {
|
|
480
|
+
displayName: 'ColumnChart',
|
|
481
|
+
});
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { CartesianChartProps } from '../props/cartesian';
|
|
2
|
+
import type { SeriesData } from '../area/area-chart.props';
|
|
3
|
+
/**
|
|
4
|
+
* Props for ColumnChart.
|
|
5
|
+
* common -> cartesian -> column
|
|
6
|
+
*/
|
|
7
|
+
export interface ColumnChartProps extends CartesianChartProps {
|
|
8
|
+
/**
|
|
9
|
+
* Chart data. Same shape as area: single series, with labels, or multiple named series.
|
|
10
|
+
*/
|
|
11
|
+
data: SeriesData;
|
|
12
|
+
/**
|
|
13
|
+
* Whether to leave gaps at the start and end of the axis.
|
|
14
|
+
* @default true
|
|
15
|
+
*/
|
|
16
|
+
boundaryGap?: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Bar corner radius: number (all corners) or [topLeft, topRight, bottomRight, bottomLeft].
|
|
19
|
+
* @default [4, 4, 0, 0]
|
|
20
|
+
*/
|
|
21
|
+
cornerRadius?: number | [number, number, number, number];
|
|
22
|
+
/**
|
|
23
|
+
* When true, bars are horizontal (categories on Y-axis, values on X-axis).
|
|
24
|
+
* Bar chart is the horizontal orientation of column chart.
|
|
25
|
+
* @default false
|
|
26
|
+
*/
|
|
27
|
+
horizontal?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Stack ID for stacking multiple series.
|
|
30
|
+
*/
|
|
31
|
+
stack?: string | false;
|
|
32
|
+
/**
|
|
33
|
+
* When true with stack, show stacked bars as percentages (0–100%).
|
|
34
|
+
* @default false
|
|
35
|
+
*/
|
|
36
|
+
stackNormalize?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Zero-based index of the bar to highlight (active state). Only applies to single series.
|
|
39
|
+
* The active bar uses activeColor and a dashed border.
|
|
40
|
+
*/
|
|
41
|
+
activeIndex?: number;
|
|
42
|
+
/**
|
|
43
|
+
* Color for the active bar when activeIndex is set.
|
|
44
|
+
* @default darker shade of series color
|
|
45
|
+
*/
|
|
46
|
+
activeColor?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Position of the label inside the bar.
|
|
49
|
+
* @default 'start'
|
|
50
|
+
*/
|
|
51
|
+
barInsideLabelPosition?: 'start' | 'middle' | 'end' | ((value: number, index: number, category?: string) => 'start' | 'middle' | 'end');
|
|
52
|
+
/**
|
|
53
|
+
* Formatter for the label inside the bar.
|
|
54
|
+
* @default undefined
|
|
55
|
+
*/
|
|
56
|
+
barInsideLabelFormatter?: (value: number, index: number, category?: string) => string;
|
|
57
|
+
/**
|
|
58
|
+
* Position of the label outside the bar.
|
|
59
|
+
* @default 'start'
|
|
60
|
+
*/
|
|
61
|
+
barOutsideLabelPosition?: 'start' | 'end' | ((value: number, index: number, category?: string) => 'start' | 'end');
|
|
62
|
+
/**
|
|
63
|
+
* Formatter for the label outside the bar.
|
|
64
|
+
* @default undefined
|
|
65
|
+
*/
|
|
66
|
+
barOutsideLabelFormatter?: (value: number, index: number, category?: string) => string;
|
|
67
|
+
/**
|
|
68
|
+
* Per-bar item style override. When provided for single series, called for each bar with (value, index).
|
|
69
|
+
* Returned object is merged over the base itemStyle (e.g. color, borderColor, borderRadius).
|
|
70
|
+
*/
|
|
71
|
+
itemStyle?: (value: number, index: number) => BarItemStyle;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Per-bar style overrides (ECharts itemStyle subset).
|
|
75
|
+
*/
|
|
76
|
+
export interface BarItemStyle {
|
|
77
|
+
color?: string;
|
|
78
|
+
borderColor?: string;
|
|
79
|
+
borderWidth?: number;
|
|
80
|
+
borderType?: 'solid' | 'dashed' | 'dotted';
|
|
81
|
+
borderRadius?: number | number[];
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=column-chart.props.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"column-chart.props.d.ts","sourceRoot":"","sources":["../../../../components/chart/column/column-chart.props.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC9D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAE3D;;;GAGG;AACH,MAAM,WAAW,gBAAiB,SAAQ,mBAAmB;IAC3D;;OAEG;IACH,IAAI,EAAE,UAAU,CAAC;IACjB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACzD;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACvB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,sBAAsB,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC,CAAC;IACxI;;;OAGG;IACH,uBAAuB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACtF;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,OAAO,GAAG,KAAK,CAAC,CAAC;IACnH;;;OAGG;IACH,wBAAwB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;IACvF;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,YAAY,CAAC;CAC5D;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC3C,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAClC"}
|
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/chart/column/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC"}
|
package/column/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ColumnChart } from './column-chart';
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { BaseGaugeProps } from '../gauge.types';
|
|
3
|
+
/**
|
|
4
|
+
* Props for the DigitalGauge component.
|
|
5
|
+
* A gauge chart with smooth animations built using SVG.
|
|
6
|
+
*/
|
|
7
|
+
interface DigitalGaugeProps extends BaseGaugeProps {
|
|
8
|
+
/**
|
|
9
|
+
* Whether to show the inner arc.
|
|
10
|
+
* @default false
|
|
11
|
+
*/
|
|
12
|
+
showInnerArc?: boolean;
|
|
13
|
+
/**
|
|
14
|
+
* Animation duration in milliseconds.
|
|
15
|
+
* @default 1000
|
|
16
|
+
*/
|
|
17
|
+
animationDuration?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare const DigitalGauge: ((props: DigitalGaugeProps & {
|
|
20
|
+
theme?: Partial<import("../..").ChartTheme>;
|
|
21
|
+
} & {
|
|
22
|
+
width?: number | string;
|
|
23
|
+
height?: number | string;
|
|
24
|
+
}) => React.JSX.Element) & {
|
|
25
|
+
displayName: string;
|
|
26
|
+
};
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=digital.gauge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"digital.gauge.d.ts","sourceRoot":"","sources":["../../../../../components/chart/gauge/digital/digital.gauge.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAG3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD;;;GAGG;AACH,UAAU,iBAAkB,SAAQ,cAAc;IAChD;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AA+UD,eAAO,MAAM,YAAY;;;;;;;CAEvB,CAAC"}
|