@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
package/.npmignore
ADDED
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 rn-widgets contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# @wavemaker/react-native-echarts
|
|
2
|
+
|
|
3
|
+
React Native chart components built with ECharts (via `@wuba/react-native-echarts`) and Skia. Works with Expo and bare React Native. Visit storybook at https://wavemaker.github.io/wm-react-native-echarts for more details on how to use and examples.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Building the library (maintainers)
|
|
8
|
+
|
|
9
|
+
Compile components and prepare the npm package:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm run build:lib # TypeScript compile → dist/npm-packages/charts
|
|
13
|
+
npm run prepare:npm # Write package.json, copy README, .npmignore
|
|
14
|
+
cd dist/npm-packages/charts && npm publish
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Development
|
|
20
|
+
|
|
21
|
+
This repo is an Expo app. To run the app and Storybook:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npm install
|
|
25
|
+
npx expo start # for mobile preview
|
|
26
|
+
npm run storybook # to checout the component stories
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Maintainers
|
|
32
|
+
|
|
33
|
+
This package is maintained by [WaveMaker](https://www.wavemaker.com/). The source repository is [wavemaker/wm-react-native-echarts](https://github.com/wavemaker/wm-react-native-echarts). Use [GitHub Issues](https://github.com/wavemaker/wm-react-native-echarts/issues) for bug reports and feature requests.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## License
|
|
38
|
+
|
|
39
|
+
MIT
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { AreaChartProps } from './area-chart.props';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
export type { AreaChartProps, AreaChartSelectEvent, SeriesData, } from './area-chart.props';
|
|
4
|
+
export declare const AreaChart: ((props: AreaChartProps & {
|
|
5
|
+
theme?: Partial<import("..").ChartTheme>;
|
|
6
|
+
} & {
|
|
7
|
+
width?: number | string;
|
|
8
|
+
height?: number | string;
|
|
9
|
+
}) => React.JSX.Element) & {
|
|
10
|
+
displayName: string;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=area-chart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"area-chart.d.ts","sourceRoot":"","sources":["../../../../components/chart/area/area-chart.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAc,MAAM,oBAAoB,CAAC;AASrE,OAAO,KAAqC,MAAM,OAAO,CAAC;AAI1D,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,UAAU,GACX,MAAM,oBAAoB,CAAC;AAsc5B,eAAO,MAAM,SAAS;;;;;;;CAEpB,CAAC"}
|
|
@@ -0,0 +1,404 @@
|
|
|
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 { LineChart } 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
|
+
// Register necessary components for this chart
|
|
10
|
+
echarts.use([
|
|
11
|
+
TooltipComponent,
|
|
12
|
+
GridComponent,
|
|
13
|
+
LegendComponent,
|
|
14
|
+
SkiaRenderer,
|
|
15
|
+
LineChart,
|
|
16
|
+
]);
|
|
17
|
+
const ChartComponent = ({ data, width = 220, height = 350, type = 'default', step, boundaryGap = false, stack, stackNormalize = false, symbol, symbolSize, areaOpacity = 0.6, areaFill = 'gradient', showXAxis = true, showXAxisTicks = true, showYAxis = true, showYAxisTicks = true, showXAxisSplitLines = true, showYAxisSplitLines = true, grid, showLegend = false, showHighlighter = true, xAxisTickLabelFormatter, yAxisTickLabelFormatter, xAxisTicks, xAxisLabel, yAxisLabel, onSelect, ...props }) => {
|
|
18
|
+
const { theme } = useChartTheme(props.theme, props.colors);
|
|
19
|
+
const chartRef = useRef(null);
|
|
20
|
+
const onSelectRef = useRef(onSelect);
|
|
21
|
+
onSelectRef.current = onSelect;
|
|
22
|
+
const selectContextRef = useRef({
|
|
23
|
+
displaySeries: [],
|
|
24
|
+
xAxisData: [],
|
|
25
|
+
});
|
|
26
|
+
// Derive smooth/step from type
|
|
27
|
+
const effectiveSmooth = type === 'smooth';
|
|
28
|
+
const effectiveStep = type === 'step' ? (step ?? 'start') : (step ?? false);
|
|
29
|
+
// Normalize data to array of { data: number[] } or { name: string; data: number[] }
|
|
30
|
+
const normalizedSeries = useMemo(() => {
|
|
31
|
+
let normalizedData = [];
|
|
32
|
+
if (!Array.isArray(data) || data.length === 0)
|
|
33
|
+
return normalizedData;
|
|
34
|
+
const first = data[0];
|
|
35
|
+
// Single series: number[] → one series
|
|
36
|
+
if (typeof first === 'number') {
|
|
37
|
+
normalizedData = [{ name: 'Series 1', data: data.map((value, index) => [String(index), value]) }];
|
|
38
|
+
}
|
|
39
|
+
else if (Array.isArray(first) && first.length === 2) {
|
|
40
|
+
normalizedData = [{ name: 'Series 1', data: data }];
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
normalizedData = JSON.parse(JSON.stringify(data))
|
|
44
|
+
.filter(item => item.data && item.data.length > 0)
|
|
45
|
+
.map((item, index) => {
|
|
46
|
+
const first = item.data[0];
|
|
47
|
+
// Single series: number[] → one series
|
|
48
|
+
if (typeof first === 'number') {
|
|
49
|
+
item.data = item.data.map((value, index) => [String(index), value]);
|
|
50
|
+
}
|
|
51
|
+
return {
|
|
52
|
+
name: item.name || 'Series ' + (index + 1),
|
|
53
|
+
data: [...item.data],
|
|
54
|
+
};
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
return normalizedData;
|
|
58
|
+
}, [data]);
|
|
59
|
+
// Check if series have names
|
|
60
|
+
const hasNamedSeries = useMemo(() => {
|
|
61
|
+
return normalizedSeries.some(s => 'name' in s && s.name);
|
|
62
|
+
}, [normalizedSeries]);
|
|
63
|
+
// When stackNormalize is true, convert each series to percentages (0–100) per x-index so stacked area sums to 100%
|
|
64
|
+
const displaySeries = useMemo(() => {
|
|
65
|
+
if (!stackNormalize || normalizedSeries.length <= 1) {
|
|
66
|
+
return normalizedSeries;
|
|
67
|
+
}
|
|
68
|
+
const len = normalizedSeries[0]?.data?.length ?? 0;
|
|
69
|
+
if (len === 0)
|
|
70
|
+
return normalizedSeries;
|
|
71
|
+
return normalizedSeries.map(s => {
|
|
72
|
+
const rawData = s.data;
|
|
73
|
+
const sumsAt = new Array(len).fill(0);
|
|
74
|
+
normalizedSeries.forEach((other, _i) => {
|
|
75
|
+
const d = 'data' in other ? other.data : [];
|
|
76
|
+
d.forEach((v, i) => { if (i < len)
|
|
77
|
+
sumsAt[i] += v; });
|
|
78
|
+
});
|
|
79
|
+
const normalizedData = rawData.map((v, i) => {
|
|
80
|
+
const sum = sumsAt[i] || 1;
|
|
81
|
+
return sum > 0 ? (v[1] / sum) * 100 : 0;
|
|
82
|
+
});
|
|
83
|
+
return 'name' in s && s.name
|
|
84
|
+
? { name: s.name, data: normalizedData }
|
|
85
|
+
: { data: normalizedData };
|
|
86
|
+
});
|
|
87
|
+
}, [normalizedSeries, stackNormalize]);
|
|
88
|
+
const xAxisData = useMemo(() => {
|
|
89
|
+
const dataPoints = normalizedSeries
|
|
90
|
+
.map(s => s.data.map(item => item[0]))
|
|
91
|
+
.flat();
|
|
92
|
+
return xAxisTicks != null && xAxisTicks.length > 0
|
|
93
|
+
? xAxisTicks
|
|
94
|
+
: getAxis(dataPoints).map(String);
|
|
95
|
+
}, [normalizedSeries, xAxisTicks]);
|
|
96
|
+
selectContextRef.current = { displaySeries, xAxisData };
|
|
97
|
+
const option = useMemo(() => {
|
|
98
|
+
// Build tooltip config
|
|
99
|
+
// axisPointer with snap: true so the pointer snaps to data points and triggers
|
|
100
|
+
// series emphasis (circle) at the hovered position. See https://echarts.apache.org/en/option.html#tooltip.axisPointer
|
|
101
|
+
const tooltipConfig = showHighlighter ? {
|
|
102
|
+
trigger: 'axis',
|
|
103
|
+
axisPointer: {
|
|
104
|
+
type: 'line',
|
|
105
|
+
snap: true,
|
|
106
|
+
lineStyle: {
|
|
107
|
+
type: 'solid',
|
|
108
|
+
width: 1,
|
|
109
|
+
color: theme.series[0].color ?? '#999',
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
} : null;
|
|
113
|
+
// Build xAxis config (category with data indices)
|
|
114
|
+
const xAxisConfig = {
|
|
115
|
+
type: 'category',
|
|
116
|
+
data: xAxisData,
|
|
117
|
+
...(xAxisLabel != null && xAxisLabel !== '' && {
|
|
118
|
+
name: xAxisLabel,
|
|
119
|
+
nameLocation: 'middle',
|
|
120
|
+
nameGap: 25,
|
|
121
|
+
nameTextStyle: { color: theme.axis.x.tickLabelColor },
|
|
122
|
+
}),
|
|
123
|
+
axisLabel: {
|
|
124
|
+
show: showXAxis || xAxisTickLabelFormatter != null,
|
|
125
|
+
color: theme.axis.x.tickLabelColor,
|
|
126
|
+
formatter: xAxisTickLabelFormatter ?? undefined,
|
|
127
|
+
},
|
|
128
|
+
axisLine: showXAxis ? {
|
|
129
|
+
show: true,
|
|
130
|
+
lineStyle: {
|
|
131
|
+
color: theme.axis.x.lineColor,
|
|
132
|
+
width: theme.axis.x.lineWidth,
|
|
133
|
+
},
|
|
134
|
+
} : {
|
|
135
|
+
show: false,
|
|
136
|
+
},
|
|
137
|
+
axisTick: {
|
|
138
|
+
show: showXAxisTicks,
|
|
139
|
+
lineStyle: {
|
|
140
|
+
color: theme.axis.x.tickColor,
|
|
141
|
+
width: theme.axis.x.tickWidth,
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
splitLine: {
|
|
145
|
+
show: showXAxisSplitLines,
|
|
146
|
+
lineStyle: {
|
|
147
|
+
color: theme.axis.x.splitLineColor,
|
|
148
|
+
width: theme.axis.x.splitLineWidth,
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
xAxisConfig.boundaryGap = boundaryGap;
|
|
153
|
+
// Build yAxis config (value, auto-scale from data)
|
|
154
|
+
const yAxisConfig = {
|
|
155
|
+
type: 'value',
|
|
156
|
+
...(stackNormalize && displaySeries.length > 1 && {
|
|
157
|
+
min: 0,
|
|
158
|
+
max: 100,
|
|
159
|
+
}),
|
|
160
|
+
...(yAxisLabel != null && yAxisLabel !== '' && {
|
|
161
|
+
name: yAxisLabel,
|
|
162
|
+
nameLocation: 'middle',
|
|
163
|
+
nameGap: 40,
|
|
164
|
+
nameTextStyle: { color: theme.axis.y.tickLabelColor },
|
|
165
|
+
}),
|
|
166
|
+
axisLabel: {
|
|
167
|
+
show: showYAxis || yAxisTickLabelFormatter != null,
|
|
168
|
+
color: theme.axis.y.tickLabelColor,
|
|
169
|
+
formatter: yAxisTickLabelFormatter ?? (stackNormalize && displaySeries.length > 1
|
|
170
|
+
? (value) => `${value}%`
|
|
171
|
+
: undefined),
|
|
172
|
+
},
|
|
173
|
+
axisLine: showYAxis ? {
|
|
174
|
+
show: true,
|
|
175
|
+
lineStyle: {
|
|
176
|
+
color: theme.axis.y.lineColor,
|
|
177
|
+
width: theme.axis.y.lineWidth,
|
|
178
|
+
},
|
|
179
|
+
} : {
|
|
180
|
+
show: false,
|
|
181
|
+
},
|
|
182
|
+
axisTick: {
|
|
183
|
+
show: showYAxisTicks,
|
|
184
|
+
lineStyle: {
|
|
185
|
+
color: theme.axis.y.tickColor,
|
|
186
|
+
width: theme.axis.y.tickWidth,
|
|
187
|
+
},
|
|
188
|
+
},
|
|
189
|
+
splitLine: {
|
|
190
|
+
show: showYAxisSplitLines,
|
|
191
|
+
lineStyle: {
|
|
192
|
+
color: theme.axis.y.splitLineColor,
|
|
193
|
+
width: theme.axis.y.splitLineWidth,
|
|
194
|
+
},
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
// Build legend config
|
|
198
|
+
const legendConfigFinal = showLegend && hasNamedSeries ? {
|
|
199
|
+
data: normalizedSeries
|
|
200
|
+
.filter(s => 'name' in s && s.name)
|
|
201
|
+
.map(s => s.name),
|
|
202
|
+
textStyle: {
|
|
203
|
+
color: theme.legend.textColor,
|
|
204
|
+
fontSize: theme.legend.fontSize,
|
|
205
|
+
},
|
|
206
|
+
backgroundColor: theme.legend.backgroundColor,
|
|
207
|
+
} : undefined;
|
|
208
|
+
// Build series config (use displaySeries so stackNormalize uses percentage data)
|
|
209
|
+
const seriesConfig = displaySeries.map((s, index) => {
|
|
210
|
+
const seriesColor = theme.series[index % theme.series.length].color;
|
|
211
|
+
const seriesLineWidth = theme.series[index]?.lineWidth ?? theme.series[0].lineWidth ?? 2;
|
|
212
|
+
// Convert opacity (0-1) to hex (00-FF)
|
|
213
|
+
const opacityHex = Math.round(areaOpacity * 255).toString(16).padStart(2, '0');
|
|
214
|
+
const colorWithOpacity = seriesColor + opacityHex;
|
|
215
|
+
const transparentColor = seriesColor + '00';
|
|
216
|
+
const solidColor = seriesColor + 'ff';
|
|
217
|
+
const areaStyleConfig = areaFill === 'gradient'
|
|
218
|
+
? {
|
|
219
|
+
color: {
|
|
220
|
+
type: 'linear',
|
|
221
|
+
x: 0,
|
|
222
|
+
y: 0,
|
|
223
|
+
x2: 0,
|
|
224
|
+
y2: 1,
|
|
225
|
+
colorStops: [
|
|
226
|
+
{ offset: 0, color: colorWithOpacity },
|
|
227
|
+
{ offset: 1, color: transparentColor },
|
|
228
|
+
],
|
|
229
|
+
},
|
|
230
|
+
}
|
|
231
|
+
: areaFill === 'transparent'
|
|
232
|
+
? { color: colorWithOpacity }
|
|
233
|
+
: { color: solidColor };
|
|
234
|
+
const series = {
|
|
235
|
+
data: 'data' in s ? s.data : [],
|
|
236
|
+
type: 'line',
|
|
237
|
+
symbol: !symbol || symbol === 'none' ? undefined : symbol,
|
|
238
|
+
symbolSize: symbolSize || 8,
|
|
239
|
+
areaStyle: areaStyleConfig,
|
|
240
|
+
itemStyle: {
|
|
241
|
+
color: seriesColor,
|
|
242
|
+
},
|
|
243
|
+
lineStyle: {
|
|
244
|
+
color: seriesColor,
|
|
245
|
+
width: seriesLineWidth,
|
|
246
|
+
},
|
|
247
|
+
// Point highlight at cursor: solid circle on the curve when axis pointer highlights this point
|
|
248
|
+
emphasis: showHighlighter
|
|
249
|
+
? {
|
|
250
|
+
focus: 'self',
|
|
251
|
+
scale: true,
|
|
252
|
+
symbol: 'circle',
|
|
253
|
+
symbolSize: 8,
|
|
254
|
+
itemStyle: {
|
|
255
|
+
color: seriesColor,
|
|
256
|
+
borderColor: '#FFFFFF',
|
|
257
|
+
borderWidth: 2,
|
|
258
|
+
},
|
|
259
|
+
}
|
|
260
|
+
: { focus: 'none', scale: false, symbolSize: 0 },
|
|
261
|
+
};
|
|
262
|
+
// Add name if present
|
|
263
|
+
if ('name' in s && s.name) {
|
|
264
|
+
series.name = s.name;
|
|
265
|
+
}
|
|
266
|
+
// Handle interpolation
|
|
267
|
+
if (effectiveStep !== false) {
|
|
268
|
+
series.step = effectiveStep;
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
series.smooth = effectiveSmooth;
|
|
272
|
+
}
|
|
273
|
+
// Handle stacking (when stackNormalize, data is already % so use same stack id so they stack to 100%)
|
|
274
|
+
if (stack !== undefined && stack !== false) {
|
|
275
|
+
series.stack = typeof stack === 'string' ? stack : 'total';
|
|
276
|
+
}
|
|
277
|
+
else if (stackNormalize && displaySeries.length > 1) {
|
|
278
|
+
series.stack = 'total';
|
|
279
|
+
}
|
|
280
|
+
return series;
|
|
281
|
+
});
|
|
282
|
+
const config = {
|
|
283
|
+
tooltip: tooltipConfig,
|
|
284
|
+
xAxis: xAxisConfig,
|
|
285
|
+
yAxis: yAxisConfig,
|
|
286
|
+
series: seriesConfig,
|
|
287
|
+
};
|
|
288
|
+
// Add legend if configured
|
|
289
|
+
if (legendConfigFinal) {
|
|
290
|
+
config.legend = legendConfigFinal;
|
|
291
|
+
}
|
|
292
|
+
// Add grid if configured
|
|
293
|
+
if (grid) {
|
|
294
|
+
config.grid = grid;
|
|
295
|
+
}
|
|
296
|
+
return config;
|
|
297
|
+
}, [
|
|
298
|
+
theme,
|
|
299
|
+
normalizedSeries,
|
|
300
|
+
xAxisData,
|
|
301
|
+
displaySeries,
|
|
302
|
+
type,
|
|
303
|
+
effectiveSmooth,
|
|
304
|
+
effectiveStep,
|
|
305
|
+
boundaryGap,
|
|
306
|
+
stack,
|
|
307
|
+
stackNormalize,
|
|
308
|
+
symbol,
|
|
309
|
+
symbolSize,
|
|
310
|
+
areaOpacity,
|
|
311
|
+
areaFill,
|
|
312
|
+
showXAxis,
|
|
313
|
+
showYAxis,
|
|
314
|
+
showXAxisTicks,
|
|
315
|
+
showYAxisTicks,
|
|
316
|
+
showXAxisSplitLines,
|
|
317
|
+
showYAxisSplitLines,
|
|
318
|
+
grid,
|
|
319
|
+
showLegend,
|
|
320
|
+
hasNamedSeries,
|
|
321
|
+
showHighlighter,
|
|
322
|
+
xAxisTickLabelFormatter,
|
|
323
|
+
yAxisTickLabelFormatter,
|
|
324
|
+
xAxisTicks,
|
|
325
|
+
xAxisLabel,
|
|
326
|
+
yAxisLabel,
|
|
327
|
+
]);
|
|
328
|
+
useEffect(() => {
|
|
329
|
+
let chart;
|
|
330
|
+
if (chartRef.current) {
|
|
331
|
+
try {
|
|
332
|
+
chart = echarts.init(chartRef.current, 'light', {
|
|
333
|
+
width: width,
|
|
334
|
+
height: height,
|
|
335
|
+
});
|
|
336
|
+
chart.setOption(option);
|
|
337
|
+
const handleSeriesClick = (params) => {
|
|
338
|
+
const cb = onSelectRef.current;
|
|
339
|
+
if (typeof cb !== 'function')
|
|
340
|
+
return;
|
|
341
|
+
if (params.componentType !== 'series')
|
|
342
|
+
return;
|
|
343
|
+
const seriesIndex = params.seriesIndex;
|
|
344
|
+
const dataIndex = params.dataIndex;
|
|
345
|
+
if (typeof seriesIndex !== 'number' ||
|
|
346
|
+
typeof dataIndex !== 'number' ||
|
|
347
|
+
dataIndex < 0) {
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
const { displaySeries: ds, xAxisData: xd } = selectContextRef.current;
|
|
351
|
+
const s = ds[seriesIndex];
|
|
352
|
+
if (!s?.data || !Array.isArray(s.data))
|
|
353
|
+
return;
|
|
354
|
+
const point = s.data[dataIndex];
|
|
355
|
+
if (point === undefined)
|
|
356
|
+
return;
|
|
357
|
+
const seriesName = s.name != null && s.name !== ''
|
|
358
|
+
? String(s.name)
|
|
359
|
+
: `Series ${seriesIndex + 1}`;
|
|
360
|
+
let x;
|
|
361
|
+
let y;
|
|
362
|
+
if (typeof point === 'number') {
|
|
363
|
+
x = xd[dataIndex] ?? dataIndex;
|
|
364
|
+
y = point;
|
|
365
|
+
}
|
|
366
|
+
else if (Array.isArray(point) && point.length >= 2) {
|
|
367
|
+
x = point[0];
|
|
368
|
+
y = Number(point[1]);
|
|
369
|
+
}
|
|
370
|
+
else {
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
const event = {
|
|
374
|
+
seriesIndex,
|
|
375
|
+
dataIndex,
|
|
376
|
+
seriesName,
|
|
377
|
+
x,
|
|
378
|
+
y,
|
|
379
|
+
};
|
|
380
|
+
cb(event);
|
|
381
|
+
};
|
|
382
|
+
chart.on('click', handleSeriesClick);
|
|
383
|
+
}
|
|
384
|
+
catch (error) {
|
|
385
|
+
console.warn('Chart initialization error:', error);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
return () => {
|
|
389
|
+
if (chart) {
|
|
390
|
+
try {
|
|
391
|
+
chart.dispose();
|
|
392
|
+
}
|
|
393
|
+
catch (error) {
|
|
394
|
+
console.warn('Chart disposal error:', error);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
};
|
|
398
|
+
}, [option, width, height]);
|
|
399
|
+
return <SkiaChart ref={chartRef} useRNGH/>;
|
|
400
|
+
};
|
|
401
|
+
const AreaChartComponent = withResponsiveContainer(withChartTheme(ChartComponent));
|
|
402
|
+
export const AreaChart = Object.assign(AreaChartComponent, {
|
|
403
|
+
displayName: 'AreaChart',
|
|
404
|
+
});
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { CartesianChartProps, CartesianChartSelectEvent } from '../props/cartesian';
|
|
2
|
+
/**
|
|
3
|
+
* Area/line/bar series data shape:
|
|
4
|
+
* - Single series: number[]
|
|
5
|
+
* - Single series with labels: [string | number, number][]
|
|
6
|
+
* - Multiple series: Array<{ name?: string; data: number[] }> or Array<{ name?: string; data: [string | number, number][] }>
|
|
7
|
+
*/
|
|
8
|
+
export type SeriesData = number[] | [string | number, number][] | Array<{
|
|
9
|
+
name?: string;
|
|
10
|
+
data: number[];
|
|
11
|
+
}> | Array<{
|
|
12
|
+
name?: string;
|
|
13
|
+
data: [string | number, number][];
|
|
14
|
+
}>;
|
|
15
|
+
/** @deprecated Use {@link CartesianChartSelectEvent} from `../props/cartesian`. */
|
|
16
|
+
export type AreaChartSelectEvent = CartesianChartSelectEvent;
|
|
17
|
+
/**
|
|
18
|
+
* Props for AreaChart.
|
|
19
|
+
* common -> cartesian -> area
|
|
20
|
+
*/
|
|
21
|
+
export interface AreaChartProps extends CartesianChartProps {
|
|
22
|
+
/**
|
|
23
|
+
* Chart data. Single series (number[]), multiple unnamed (number[][]), or multiple named series.
|
|
24
|
+
*/
|
|
25
|
+
data: SeriesData;
|
|
26
|
+
/**
|
|
27
|
+
* Curve type: 'default' (linear), 'smooth' (Bezier), or 'step'.
|
|
28
|
+
* @default 'default'
|
|
29
|
+
*/
|
|
30
|
+
type?: 'default' | 'smooth' | 'step';
|
|
31
|
+
/**
|
|
32
|
+
* Step mode when type="step". 'start' | 'middle' | 'end'.
|
|
33
|
+
*/
|
|
34
|
+
step?: 'start' | 'middle' | 'end' | false;
|
|
35
|
+
/**
|
|
36
|
+
* Stack ID for stacking multiple series. Use false to disable.
|
|
37
|
+
*/
|
|
38
|
+
stack?: string | false;
|
|
39
|
+
/**
|
|
40
|
+
* When true with stack, show stacked values as percentages (0–100%).
|
|
41
|
+
* @default false
|
|
42
|
+
*/
|
|
43
|
+
stackNormalize?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Symbol type for data points. Set to 'none' to hide.
|
|
46
|
+
* @default 'none'
|
|
47
|
+
*/
|
|
48
|
+
symbol?: 'none' | 'circle' | 'rect' | 'roundRect' | 'triangle' | 'diamond' | 'pin' | 'arrow' | string;
|
|
49
|
+
/**
|
|
50
|
+
* Size of the symbol. Number, [width, height], or function.
|
|
51
|
+
*/
|
|
52
|
+
symbolSize?: number | number[] | ((value: unknown) => number | number[]);
|
|
53
|
+
/**
|
|
54
|
+
* Opacity of the filled area (0-1).
|
|
55
|
+
* @default 0.6
|
|
56
|
+
*/
|
|
57
|
+
areaOpacity?: number;
|
|
58
|
+
/**
|
|
59
|
+
* Fill style for the area under the line: 'gradient' | 'transparent' | 'solid'.
|
|
60
|
+
* @default 'gradient'
|
|
61
|
+
*/
|
|
62
|
+
areaFill?: 'gradient' | 'transparent' | 'solid';
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=area-chart.props.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"area-chart.props.d.ts","sourceRoot":"","sources":["../../../../components/chart/area/area-chart.props.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAEzF;;;;;GAKG;AACH,MAAM,MAAM,UAAU,GAClB,MAAM,EAAE,GACR,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,GAC3B,KAAK,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,GACxC,KAAK,CAAC;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,CAAC,EAAE,CAAA;CAAE,CAAC,CAAC;AAEhE,mFAAmF;AACnF,MAAM,MAAM,oBAAoB,GAAG,yBAAyB,CAAC;AAE7D;;;GAGG;AACH,MAAM,WAAW,cAAe,SAAQ,mBAAmB;IACzD;;OAEG;IACH,IAAI,EAAE,UAAU,CAAC;IACjB;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC;;OAEG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAC;IAC1C;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC;IACvB;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,UAAU,GAAG,SAAS,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;IACtG;;OAEG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,OAAO,KAAK,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IACzE;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,QAAQ,CAAC,EAAE,UAAU,GAAG,aAAa,GAAG,OAAO,CAAC;CACjD"}
|
|
File without changes
|
package/area/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/chart/area/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,YAAY,EACV,cAAc,EACd,oBAAoB,EACpB,UAAU,GACX,MAAM,oBAAoB,CAAC"}
|
package/area/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AreaChart } from './area-chart';
|
package/axis.d.ts
ADDED
package/axis.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"axis.d.ts","sourceRoot":"","sources":["../../../components/chart/axis.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,GAAI,YAAO,EAAE,YAAS,EAAE,WAAW,MAAM,aAUpE,CAAA;AAED,eAAO,MAAM,OAAO,GAAI,MAAM,MAAM,EAAE,aAIrC,CAAA"}
|
package/axis.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const getAxisByMinMax = (min = 0, max = 100, interval) => {
|
|
2
|
+
interval = interval || Math.floor((max - min) / 10) || 1;
|
|
3
|
+
const axisArray = [];
|
|
4
|
+
for (let i = min; i <= max; i += interval) {
|
|
5
|
+
axisArray.push(i);
|
|
6
|
+
}
|
|
7
|
+
if (axisArray[axisArray.length - 1] !== max) {
|
|
8
|
+
axisArray.push(max);
|
|
9
|
+
}
|
|
10
|
+
return axisArray;
|
|
11
|
+
};
|
|
12
|
+
export const getAxis = (data) => {
|
|
13
|
+
const min = Math.min(...data);
|
|
14
|
+
const max = Math.max(...data);
|
|
15
|
+
return getAxisByMinMax(min, max);
|
|
16
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { BarChartProps } from './bar-chart.props';
|
|
3
|
+
/**
|
|
4
|
+
* Bar chart is the horizontal orientation of column chart.
|
|
5
|
+
* Renders ColumnChart with horizontal={true}.
|
|
6
|
+
*/
|
|
7
|
+
export type { BarChartProps } from './bar-chart.props';
|
|
8
|
+
export declare const BarChart: ((props: BarChartProps) => React.JSX.Element) & {
|
|
9
|
+
displayName: string;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=bar-chart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bar-chart.d.ts","sourceRoot":"","sources":["../../../../components/chart/bar/bar-chart.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD;;;GAGG;AACH,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAMvD,eAAO,MAAM,QAAQ,WAJa,aAAa;;CAM7C,CAAC"}
|
package/bar/bar-chart.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ColumnChartProps } from '../column/column-chart.props';
|
|
2
|
+
/**
|
|
3
|
+
* Props for BarChart.
|
|
4
|
+
* Bar chart is the horizontal orientation of column chart; horizontal is always true.
|
|
5
|
+
*/
|
|
6
|
+
export type BarChartProps = Omit<ColumnChartProps, 'horizontal'>;
|
|
7
|
+
//# sourceMappingURL=bar-chart.props.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bar-chart.props.d.ts","sourceRoot":"","sources":["../../../../components/chart/bar/bar-chart.props.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAErE;;;GAGG;AACH,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,EAAE,YAAY,CAAC,CAAC"}
|
|
File without changes
|
package/bar/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../components/chart/bar/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC"}
|
package/bar/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { BarChart } from './bar-chart';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { BubbleChartProps } from './bubble-chart.props';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
/** common -> cartesian -> scatter -> bubble */
|
|
4
|
+
export type { BubbleChartProps, BubbleSeriesData } from './bubble-chart.props';
|
|
5
|
+
export declare const BubbleChart: ((props: BubbleChartProps & {
|
|
6
|
+
theme?: Partial<import("..").ChartTheme>;
|
|
7
|
+
} & {
|
|
8
|
+
width?: number | string;
|
|
9
|
+
height?: number | string;
|
|
10
|
+
}) => React.JSX.Element) & {
|
|
11
|
+
displayName: string;
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=bubble-chart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bubble-chart.d.ts","sourceRoot":"","sources":["../../../../components/chart/bubble/bubble-chart.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAS7D,OAAO,KAAqC,MAAM,OAAO,CAAC;AAG1D,+CAA+C;AAC/C,YAAY,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAkV/E,eAAO,MAAM,WAAW;;;;;;;CAEtB,CAAC"}
|