@easy-editor/materials-dashboard-line-chart 0.0.4 → 0.0.5

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/src/component.tsx CHANGED
@@ -1,277 +1,279 @@
1
- /**
2
- * Line Chart Component
3
- * 折线图组件 - 支持数据源绑定和事件交互
4
- */
5
-
6
- import { useEffect, useMemo, useRef, type CSSProperties } from 'react'
7
- import * as echarts from 'echarts/core'
8
- import { LineChart as EChartsLineChart } from 'echarts/charts'
9
- import { GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
10
- import { CanvasRenderer } from 'echarts/renderers'
11
- import type { SeriesOption } from 'echarts'
12
- import { type MaterialComponet, useDataSource } from '@easy-editor/materials-shared'
13
- import { DEFAULT_COLORS, DEFAULT_DATA, type DataPoint } from './constants'
14
- import styles from './component.module.css'
15
-
16
- // 按需注册 ECharts 组件
17
- echarts.use([EChartsLineChart, GridComponent, TooltipComponent, LegendComponent, CanvasRenderer])
18
-
19
- export interface LineChartProps extends MaterialComponet {
20
- /** X轴字段 */
21
- xField?: string
22
- /** Y轴字段列表 */
23
- yFields?: string[]
24
- /** 颜色列表 */
25
- colors?: string[]
26
- /** 显示网格 */
27
- showGrid?: boolean
28
- /** 显示图例 */
29
- showLegend?: boolean
30
- /** 显示提示 */
31
- showTooltip?: boolean
32
- /** 发光效果 */
33
- glowEffect?: boolean
34
- /** 线条宽度 */
35
- strokeWidth?: number
36
- /** 区域填充 */
37
- areaFill?: boolean
38
- /** 平滑曲线 */
39
- smooth?: boolean
40
- /** 点击事件 */
41
- onClick?: (e: React.MouseEvent) => void
42
- /** 双击事件 */
43
- onDoubleClick?: (e: React.MouseEvent) => void
44
- /** 鼠标进入 */
45
- onMouseEnter?: (e: React.MouseEvent) => void
46
- /** 鼠标离开 */
47
- onMouseLeave?: (e: React.MouseEvent) => void
48
- }
49
-
50
- // 构建 series 配置
51
- const buildSeries = (
52
- yFields: string[],
53
- data: DataPoint[],
54
- colors: string[],
55
- options: {
56
- smooth: boolean
57
- strokeWidth: number
58
- glowEffect: boolean
59
- areaFill: boolean
60
- },
61
- ): SeriesOption[] => {
62
- const { smooth, strokeWidth, glowEffect, areaFill } = options
63
- return yFields.map((field, index) => {
64
- const color = colors[index % colors.length]
65
- return {
66
- name: field,
67
- type: 'line' as const,
68
- data: data.map(item => item[field] as number),
69
- smooth,
70
- lineStyle: {
71
- width: strokeWidth,
72
- color,
73
- shadowColor: glowEffect ? color : 'transparent',
74
- shadowBlur: glowEffect ? 10 : 0,
75
- },
76
- itemStyle: {
77
- color,
78
- },
79
- areaStyle: areaFill
80
- ? {
81
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
82
- { offset: 0, color: `${color}40` },
83
- { offset: 1, color: `${color}05` },
84
- ]),
85
- }
86
- : undefined,
87
- symbol: 'circle',
88
- symbolSize: 6,
89
- }
90
- })
91
- }
92
-
93
- // 构建图表配置
94
- const buildOption = (
95
- data: DataPoint[],
96
- xField: string,
97
- series: SeriesOption[],
98
- options: {
99
- showGrid: boolean
100
- showLegend: boolean
101
- showTooltip: boolean
102
- },
103
- ) => {
104
- const { showGrid, showLegend, showTooltip } = options
105
-
106
- return {
107
- backgroundColor: 'transparent',
108
- grid: {
109
- top: showLegend ? 40 : 20,
110
- right: 20,
111
- bottom: 30,
112
- left: 50,
113
- containLabel: false,
114
- },
115
- xAxis: {
116
- type: 'category',
117
- data: data.map(item => item[xField]),
118
- axisLine: {
119
- lineStyle: {
120
- color: '#8899aa',
121
- opacity: 0.3,
122
- },
123
- },
124
- axisTick: { show: false },
125
- axisLabel: {
126
- color: '#8899aa',
127
- fontSize: 12,
128
- },
129
- splitLine: {
130
- show: showGrid,
131
- lineStyle: {
132
- color: '#00d4ff',
133
- opacity: 0.1,
134
- type: 'dashed',
135
- },
136
- },
137
- },
138
- yAxis: {
139
- type: 'value',
140
- axisLine: {
141
- lineStyle: {
142
- color: '#8899aa',
143
- opacity: 0.3,
144
- },
145
- },
146
- axisTick: { show: false },
147
- axisLabel: {
148
- color: '#8899aa',
149
- fontSize: 11,
150
- },
151
- splitLine: {
152
- show: showGrid,
153
- lineStyle: {
154
- color: '#00d4ff',
155
- opacity: 0.1,
156
- type: 'dashed',
157
- },
158
- },
159
- },
160
- tooltip: showTooltip
161
- ? {
162
- trigger: 'axis',
163
- backgroundColor: 'rgba(0, 20, 40, 0.9)',
164
- borderColor: '#00d4ff',
165
- borderWidth: 1,
166
- textStyle: {
167
- color: '#fff',
168
- },
169
- }
170
- : undefined,
171
- legend: showLegend
172
- ? {
173
- show: true,
174
- top: 10,
175
- textStyle: {
176
- color: '#8899aa',
177
- fontSize: 11,
178
- },
179
- }
180
- : undefined,
181
- series,
182
- }
183
- }
184
-
185
- export const LineChart: React.FC<LineChartProps> = ({
186
- ref,
187
- $data,
188
- __dataSource,
189
- xField = 'name',
190
- yFields = ['value1', 'value2'],
191
- colors = DEFAULT_COLORS,
192
- showGrid = true,
193
- showLegend = true,
194
- showTooltip = true,
195
- glowEffect = true,
196
- strokeWidth = 2,
197
- areaFill = false,
198
- smooth = true,
199
- rotation = 0,
200
- opacity = 100,
201
- background = 'transparent',
202
- style: externalStyle,
203
- onClick,
204
- onDoubleClick,
205
- onMouseEnter,
206
- onMouseLeave,
207
- }) => {
208
- const chartRef = useRef<HTMLDivElement>(null)
209
- const chartInstance = useRef<echarts.ECharts | null>(null)
210
-
211
- // 解析数据源
212
- const dataSource = useDataSource($data, __dataSource)
213
- const data = useMemo<DataPoint[]>(() => {
214
- if (dataSource.length > 0) {
215
- return dataSource as DataPoint[]
216
- }
217
- return DEFAULT_DATA
218
- }, [dataSource])
219
-
220
- useEffect(() => {
221
- if (!chartRef.current) {
222
- return
223
- }
224
-
225
- chartInstance.current = echarts.init(chartRef.current)
226
-
227
- // 构建 series
228
- const series = buildSeries(yFields, data, colors, {
229
- smooth,
230
- strokeWidth,
231
- glowEffect,
232
- areaFill,
233
- })
234
-
235
- const option = buildOption(data, xField, series, {
236
- showGrid,
237
- showLegend,
238
- showTooltip,
239
- })
240
-
241
- chartInstance.current.setOption(option)
242
-
243
- // 响应式调整
244
- const resizeObserver = new ResizeObserver(() => {
245
- chartInstance.current?.resize()
246
- })
247
- resizeObserver.observe(chartRef.current)
248
-
249
- return () => {
250
- resizeObserver.disconnect()
251
- chartInstance.current?.dispose()
252
- }
253
- }, [data, xField, yFields, colors, showGrid, showLegend, showTooltip, glowEffect, strokeWidth, areaFill, smooth])
254
-
255
- const containerStyle: CSSProperties = {
256
- width: '100%',
257
- height: '100%',
258
- transform: rotation !== 0 ? `rotate(${rotation}deg)` : undefined,
259
- opacity: opacity / 100,
260
- backgroundColor: background,
261
- ...externalStyle,
262
- }
263
-
264
- return (
265
- <div
266
- className={styles.container}
267
- onClick={onClick}
268
- onDoubleClick={onDoubleClick}
269
- onMouseEnter={onMouseEnter}
270
- onMouseLeave={onMouseLeave}
271
- ref={ref}
272
- style={containerStyle}
273
- >
274
- <div className={styles.chart} ref={chartRef} />
275
- </div>
276
- )
277
- }
1
+ /**
2
+ * Line Chart Component
3
+ * 折线图组件 - 支持数据源绑定和事件交互
4
+ */
5
+
6
+ import { useEffect, useMemo, useRef, type CSSProperties } from 'react'
7
+ import * as echarts from 'echarts/core'
8
+ import { LineChart as EChartsLineChart } from 'echarts/charts'
9
+ import { GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
10
+ import { CanvasRenderer } from 'echarts/renderers'
11
+ import type { SeriesOption } from 'echarts'
12
+ import { type MaterialComponet, useDataSource } from '@easy-editor/materials-shared'
13
+ import { DEFAULT_COLORS, DEFAULT_DATA, type DataPoint } from './constants'
14
+ import styles from './component.module.css'
15
+
16
+ // 按需注册 ECharts 组件
17
+ echarts.use([EChartsLineChart, GridComponent, TooltipComponent, LegendComponent, CanvasRenderer])
18
+
19
+ export interface LineChartProps extends MaterialComponet {
20
+ /** X轴字段 */
21
+ xField?: string
22
+ /** Y轴字段列表 */
23
+ yFields?: string[]
24
+ /** 颜色列表 */
25
+ colors?: string[]
26
+ /** 显示网格 */
27
+ showGrid?: boolean
28
+ /** 显示图例 */
29
+ showLegend?: boolean
30
+ /** 显示提示 */
31
+ showTooltip?: boolean
32
+ /** 发光效果 */
33
+ glowEffect?: boolean
34
+ /** 线条宽度 */
35
+ strokeWidth?: number
36
+ /** 区域填充 */
37
+ areaFill?: boolean
38
+ /** 平滑曲线 */
39
+ smooth?: boolean
40
+ /** 点击事件 */
41
+ onClick?: (e: React.MouseEvent) => void
42
+ /** 双击事件 */
43
+ onDoubleClick?: (e: React.MouseEvent) => void
44
+ /** 鼠标进入 */
45
+ onMouseEnter?: (e: React.MouseEvent) => void
46
+ /** 鼠标离开 */
47
+ onMouseLeave?: (e: React.MouseEvent) => void
48
+ }
49
+
50
+ // 构建 series 配置
51
+ const buildSeries = (
52
+ yFields: string[],
53
+ data: DataPoint[],
54
+ colors: string[],
55
+ options: {
56
+ smooth: boolean
57
+ strokeWidth: number
58
+ glowEffect: boolean
59
+ areaFill: boolean
60
+ },
61
+ ): SeriesOption[] => {
62
+ const { smooth, strokeWidth, glowEffect, areaFill } = options
63
+ return yFields.map((field, index) => {
64
+ const color = colors[index % colors.length]
65
+ return {
66
+ name: field,
67
+ type: 'line' as const,
68
+ data: data.map(item => item[field] as number),
69
+ smooth,
70
+ lineStyle: {
71
+ width: strokeWidth,
72
+ color,
73
+ shadowColor: glowEffect ? color : 'transparent',
74
+ shadowBlur: glowEffect ? 10 : 0,
75
+ },
76
+ itemStyle: {
77
+ color,
78
+ },
79
+ areaStyle: areaFill
80
+ ? {
81
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
82
+ { offset: 0, color: `${color}40` },
83
+ { offset: 1, color: `${color}05` },
84
+ ]),
85
+ }
86
+ : undefined,
87
+ symbol: 'circle',
88
+ symbolSize: 6,
89
+ }
90
+ })
91
+ }
92
+
93
+ // 构建图表配置
94
+ const buildOption = (
95
+ data: DataPoint[],
96
+ xField: string,
97
+ series: SeriesOption[],
98
+ options: {
99
+ showGrid: boolean
100
+ showLegend: boolean
101
+ showTooltip: boolean
102
+ },
103
+ ) => {
104
+ const { showGrid, showLegend, showTooltip } = options
105
+
106
+ return {
107
+ backgroundColor: 'transparent',
108
+ grid: {
109
+ top: showLegend ? 40 : 20,
110
+ right: 20,
111
+ bottom: 30,
112
+ left: 50,
113
+ containLabel: false,
114
+ },
115
+ xAxis: {
116
+ type: 'category',
117
+ data: data.map(item => item[xField]),
118
+ axisLine: {
119
+ lineStyle: {
120
+ color: '#8899aa',
121
+ opacity: 0.3,
122
+ },
123
+ },
124
+ axisTick: { show: false },
125
+ axisLabel: {
126
+ color: '#8899aa',
127
+ fontSize: 12,
128
+ },
129
+ splitLine: {
130
+ show: showGrid,
131
+ lineStyle: {
132
+ color: '#00d4ff',
133
+ opacity: 0.1,
134
+ type: 'dashed',
135
+ },
136
+ },
137
+ },
138
+ yAxis: {
139
+ type: 'value',
140
+ axisLine: {
141
+ lineStyle: {
142
+ color: '#8899aa',
143
+ opacity: 0.3,
144
+ },
145
+ },
146
+ axisTick: { show: false },
147
+ axisLabel: {
148
+ color: '#8899aa',
149
+ fontSize: 11,
150
+ },
151
+ splitLine: {
152
+ show: showGrid,
153
+ lineStyle: {
154
+ color: '#00d4ff',
155
+ opacity: 0.1,
156
+ type: 'dashed',
157
+ },
158
+ },
159
+ },
160
+ tooltip: showTooltip
161
+ ? {
162
+ trigger: 'axis',
163
+ backgroundColor: 'rgba(0, 20, 40, 0.9)',
164
+ borderColor: '#00d4ff',
165
+ borderWidth: 1,
166
+ textStyle: {
167
+ color: '#fff',
168
+ },
169
+ }
170
+ : undefined,
171
+ legend: showLegend
172
+ ? {
173
+ show: true,
174
+ top: 10,
175
+ textStyle: {
176
+ color: '#8899aa',
177
+ fontSize: 11,
178
+ },
179
+ }
180
+ : undefined,
181
+ series,
182
+ }
183
+ }
184
+
185
+ export const LineChart: React.FC<LineChartProps> = ({
186
+ ref,
187
+ $data,
188
+ __dataSource,
189
+ xField = 'name',
190
+ yFields = ['value1', 'value2'],
191
+ colors = DEFAULT_COLORS,
192
+ showGrid = true,
193
+ showLegend = true,
194
+ showTooltip = true,
195
+ glowEffect = true,
196
+ strokeWidth = 2,
197
+ areaFill = false,
198
+ smooth = true,
199
+ rotation = 0,
200
+ opacity = 100,
201
+ background = 'transparent',
202
+ style: externalStyle,
203
+ onClick,
204
+ onDoubleClick,
205
+ onMouseEnter,
206
+ onMouseLeave,
207
+ }) => {
208
+ const chartRef = useRef<HTMLDivElement>(null)
209
+ const chartInstance = useRef<echarts.ECharts | null>(null)
210
+
211
+ // 解析数据源
212
+ const dataSource = useDataSource($data, __dataSource)
213
+ const data = useMemo<DataPoint[]>(() => {
214
+ if (dataSource.length > 0) {
215
+ return dataSource as DataPoint[]
216
+ }
217
+ return DEFAULT_DATA
218
+ }, [dataSource])
219
+
220
+ useEffect(() => {
221
+ if (!chartRef.current) {
222
+ return
223
+ }
224
+
225
+ chartInstance.current = echarts.init(chartRef.current)
226
+
227
+ // 构建 series
228
+ const series = buildSeries(yFields, data, colors, {
229
+ smooth,
230
+ strokeWidth,
231
+ glowEffect,
232
+ areaFill,
233
+ })
234
+
235
+ const option = buildOption(data, xField, series, {
236
+ showGrid,
237
+ showLegend,
238
+ showTooltip,
239
+ })
240
+
241
+ chartInstance.current.setOption(option)
242
+
243
+ // 响应式调整
244
+ const resizeObserver = new ResizeObserver(() => {
245
+ chartInstance.current?.resize()
246
+ })
247
+ resizeObserver.observe(chartRef.current)
248
+
249
+ return () => {
250
+ resizeObserver.disconnect()
251
+ chartInstance.current?.dispose()
252
+ }
253
+ }, [data, xField, yFields, colors, showGrid, showLegend, showTooltip, glowEffect, strokeWidth, areaFill, smooth])
254
+
255
+ const containerStyle: CSSProperties = {
256
+ width: '100%',
257
+ height: '100%',
258
+ transform: rotation !== 0 ? `rotate(${rotation}deg)` : undefined,
259
+ opacity: opacity / 100,
260
+ backgroundColor: background,
261
+ ...externalStyle,
262
+ }
263
+
264
+ return (
265
+ <div
266
+ className={styles.container}
267
+ onClick={onClick}
268
+ onDoubleClick={onDoubleClick}
269
+ onMouseEnter={onMouseEnter}
270
+ onMouseLeave={onMouseLeave}
271
+ ref={ref}
272
+ style={containerStyle}
273
+ >
274
+ <div className={styles.chart} ref={chartRef} />
275
+ </div>
276
+ )
277
+ }
278
+
279
+ export default LineChart
package/src/meta.ts CHANGED
@@ -1,23 +1,23 @@
1
- import type { ComponentMetadata } from '@easy-editor/core'
2
- import { MaterialGroup } from '@easy-editor/materials-shared'
3
- import { COMPONENT_NAME, PACKAGE_NAME } from './constants'
4
- import { configure } from './configure'
5
- import { snippets } from './snippets'
6
- import pkg from '../package.json'
7
-
8
- const meta: ComponentMetadata = {
9
- componentName: COMPONENT_NAME,
10
- title: '折线图',
11
- group: MaterialGroup.CHART,
12
- devMode: 'proCode',
13
- npm: {
14
- package: PACKAGE_NAME,
15
- version: pkg.version,
16
- globalName: COMPONENT_NAME,
17
- componentName: COMPONENT_NAME,
18
- },
19
- snippets,
20
- configure,
21
- }
22
-
23
- export { meta }
1
+ import type { ComponentMetadata } from '@easy-editor/core'
2
+ import { MaterialGroup } from '@easy-editor/materials-shared'
3
+ import { COMPONENT_NAME, PACKAGE_NAME } from './constants'
4
+ import { configure } from './configure'
5
+ import { snippets } from './snippets'
6
+ import pkg from '../package.json'
7
+
8
+ export const meta: ComponentMetadata = {
9
+ componentName: COMPONENT_NAME,
10
+ title: '折线图',
11
+ group: MaterialGroup.CHART,
12
+ devMode: 'proCode',
13
+ npm: {
14
+ package: PACKAGE_NAME,
15
+ version: pkg.version,
16
+ globalName: COMPONENT_NAME,
17
+ componentName: COMPONENT_NAME,
18
+ },
19
+ snippets,
20
+ configure,
21
+ }
22
+
23
+ export default meta