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

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/meta.min.js CHANGED
@@ -1,2 +1 @@
1
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).EasyEditorMaterialsLineChartMeta={})}(this,function(e){"use strict";const t="EasyEditorMaterialsLineChart",a=[{name:"Mon",value1:120,value2:80},{name:"Tue",value1:200,value2:120},{name:"Wed",value1:150,value2:100},{name:"Thu",value1:280,value2:180},{name:"Fri",value1:220,value2:140},{name:"Sat",value1:300,value2:200},{name:"Sun",value1:250,value2:160}];const r={componentName:t,title:"折线图",group:"chart",devMode:"proCode",npm:{package:"@easy-editor/materials-dashboard-line-chart",version:"0.0.2",globalName:t,componentName:t},snippets:[{title:"折线图",screenshot:"",schema:{componentName:t,props:{data:a,xField:"name",yFields:["value1","value2"],showGrid:!0,showLegend:!0,glowEffect:!0,strokeWidth:2},$dashboard:{rect:{width:400,height:300}}}},{title:"简单折线图",screenshot:"",schema:{componentName:t,props:{data:a,xField:"name",yFields:["value1"],showGrid:!0,showLegend:!1,glowEffect:!0,strokeWidth:3},$dashboard:{rect:{width:300,height:200}}}}],configure:{props:[{type:"group",title:"属性",setter:"TabSetter",items:[{type:"group",key:"config",title:"配置",setter:{componentName:"CollapseSetter",props:{icon:!1}},items:[{name:"id",title:"ID",setter:"NodeIdSetter",extraProps:{label:!1}},{name:"title",title:"标题",setter:"StringSetter",extraProps:{getValue:e=>e.getExtraPropValue("title"),setValue(e,t){e.setExtraPropValue("title",t)}}},{type:"group",title:"基础属性",setter:{componentName:"CollapseSetter",props:{icon:!1}},items:[{name:"rect",title:"位置尺寸",setter:"RectSetter",extraProps:{getValue:e=>e.getExtraPropValue("$dashboard.rect"),setValue(e,t){e.setExtraPropValue("$dashboard.rect",t)}}}]},{type:"group",title:"数据",setter:{componentName:"CollapseSetter",props:{icon:!1}},items:[{name:"data",title:"数据",setter:"JsonSetter"},{name:"xField",title:"X轴字段",setter:"StringSetter",extraProps:{defaultValue:"name"}},{name:"yFields",title:"Y轴字段",setter:{componentName:"ArraySetter",props:{itemSetter:"StringSetter"}}}]},{type:"group",title:"坐标轴",setter:{componentName:"CollapseSetter",props:{icon:!1}},items:[{name:"xAxisLabel",title:"X轴标签",setter:"StringSetter"},{name:"yAxisLabel",title:"Y轴标签",setter:"StringSetter"},{name:"xAxisVisible",title:"显示X轴",setter:"SwitchSetter",extraProps:{defaultValue:!0}},{name:"yAxisVisible",title:"显示Y轴",setter:"SwitchSetter",extraProps:{defaultValue:!0}},{name:"axisLabelRotate",title:"标签旋转",setter:{componentName:"SliderSetter",props:{min:-90,max:90,step:15,suffix:"°"}},extraProps:{defaultValue:0}}]},{type:"group",title:"数值格式",setter:{componentName:"CollapseSetter",props:{icon:!1}},items:[{name:"valuePrefix",title:"前缀",setter:"StringSetter"},{name:"valueSuffix",title:"后缀",setter:"StringSetter"},{name:"valueDecimals",title:"小数位数",setter:{componentName:"NumberSetter",props:{suffix:""}},extraProps:{defaultValue:0}},{name:"valueSeparator",title:"千分位分隔",setter:"SwitchSetter",extraProps:{defaultValue:!1}}]},{type:"group",title:"样式",setter:{componentName:"CollapseSetter",props:{icon:!1}},items:[{name:"colors",title:"颜色",setter:{componentName:"ArraySetter",props:{itemSetter:"ColorSetter"}}},{name:"strokeWidth",title:"线条宽度",setter:{componentName:"SliderSetter",props:{min:1,max:10,step:1,suffix:"px"}},extraProps:{defaultValue:2}},{name:"smooth",title:"平滑曲线",setter:"SwitchSetter",extraProps:{defaultValue:!0}},{name:"areaFill",title:"区域填充",setter:"SwitchSetter",extraProps:{defaultValue:!1}},{name:"showGrid",title:"显示网格",setter:"SwitchSetter",extraProps:{defaultValue:!0}},{name:"showLegend",title:"显示图例",setter:"SwitchSetter",extraProps:{defaultValue:!0}},{name:"legendPosition",title:"图例位置",setter:{componentName:"SelectSetter",props:{options:[{label:"顶部",value:"top"},{label:"底部",value:"bottom"},{label:"左侧",value:"left"},{label:"右侧",value:"right"}]}},extraProps:{defaultValue:"bottom"}},{name:"showTooltip",title:"显示提示",setter:"SwitchSetter",extraProps:{defaultValue:!0}},{name:"glowEffect",title:"发光效果",setter:"SwitchSetter",extraProps:{defaultValue:!0}}]}]},{type:"group",key:"data",title:"数据",items:[{name:"dataBinding",title:"数据绑定",setter:"DataBindingSetter"}]},{type:"group",key:"advanced",title:"高级",items:[{name:"condition",title:"显隐控制",setter:"SwitchSetter",extraProps:{defaultValue:!0,supportVariable:!0}}]}]}],component:{},supports:{},advanced:{}}};e.default=r,Object.defineProperty(e,"__esModule",{value:!0})});
2
- //# sourceMappingURL=meta.min.js.map
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("react")):"function"==typeof define&&define.amd?define(["exports","react"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).EasyEditorMaterialsLineChartMeta={})}(this,function(e){"use strict";const t=(e,t)=>{const a=Array.isArray(e)?e:[e],r=a[0]||{};return{sourceType:"static",staticData:a,fieldMappings:Object.keys(r).map(e=>({componentField:e,sourceField:e}))}},a=(e,t,a)=>({type:"group",title:e,setter:{componentName:"CollapseSetter",props:{icon:!1,...a}},items:t}),r={name:"nodeInfo",title:"节点信息",setter:"NodeInfoSetter",extraProps:{label:!1}},o=a("基础配置",[{name:"title",title:"标题",setter:"StringSetter",extraProps:{getValue:e=>e.getExtraPropValue("title"),setValue(e,t){e.setExtraPropValue("title",t)}}},{name:"rect",title:"位置尺寸",setter:"RectSetter",extraProps:{getValue:e=>e.getExtraPropValue("$dashboard.rect"),setValue(e,t){e.setExtraPropValue("$dashboard.rect",t)}}},{name:"rotation",title:"旋转角度",setter:{componentName:"SliderSetter",props:{min:0,max:360,suffix:"°"}},extraProps:{defaultValue:0}},{name:"opacity",title:"不透明度",setter:{componentName:"SliderSetter",props:{min:0,max:100,suffix:"%"}},extraProps:{defaultValue:100}},{name:"background",title:"背景颜色",setter:"ColorSetter",extraProps:{defaultValue:"transparent"}}]),l=[{title:"点击事件",children:[{label:"点击",value:"onClick",description:"鼠标点击时触发"},{label:"双击",value:"onDoubleClick",description:"鼠标双击时触发"}]},{title:"鼠标事件",children:[{label:"鼠标进入",value:"onMouseEnter",description:"鼠标进入时触发"},{label:"鼠标离开",value:"onMouseLeave",description:"鼠标离开时触发"}]}],i=((e=l)=>a("事件绑定",[{name:"events",title:"事件",setter:{componentName:"EventSetter",props:{events:e}},extraProps:{label:!1}}]))(),s=a("高级配置",[{title:"条件渲染",setter:"SwitchSetter",extraProps:{supportVariable:!0,getValue:e=>e.getNode().getExtraPropValue("condition"),setValue(e,t){e.getNode().setExtraProp("condition",t)}}}]),n="EasyEditorMaterialsLineChart";const p=((e,t)=>({props:[{type:"group",title:"属性",setter:"TabSetter",items:[{type:"group",key:"config",title:"配置",items:[r,o,e]},{type:"group",key:"data",title:"数据",items:[r,t]},{type:"group",key:"advanced",title:"高级",items:[r,i,s]}]}],component:{},supports:{},advanced:{}}))(a("组件配置",[{type:"group",title:"组件配置",setter:"SubTabSetter",items:[{type:"group",key:"chartData",title:"数据",items:[{name:"xField",title:"X轴字段",setter:"StringSetter",extraProps:{defaultValue:"name"}},{name:"yFields",title:"Y轴字段",setter:{componentName:"ArraySetter",props:{itemSetter:"StringSetter"}},extraProps:{defaultValue:["value1","value2"]}}]},{type:"group",key:"style",title:"样式",items:[{name:"colors",title:"颜色",setter:{componentName:"ArraySetter",props:{itemSetter:"ColorSetter"}}},{name:"strokeWidth",title:"线条宽度",setter:{componentName:"SliderSetter",props:{min:1,max:10,step:1,suffix:"px"}},extraProps:{defaultValue:2}},{name:"smooth",title:"平滑曲线",setter:"SwitchSetter",extraProps:{defaultValue:!0}},{name:"areaFill",title:"区域填充",setter:"SwitchSetter",extraProps:{defaultValue:!1}},{name:"glowEffect",title:"发光效果",setter:"SwitchSetter",extraProps:{defaultValue:!0}}]},{type:"group",key:"legend",title:"图例",items:[{name:"showGrid",title:"显示网格",setter:"SwitchSetter",extraProps:{defaultValue:!0}},{name:"showLegend",title:"显示图例",setter:"SwitchSetter",extraProps:{defaultValue:!0}},{name:"legendPosition",title:"图例位置",setter:{componentName:"SelectSetter",props:{options:[{label:"顶部",value:"top"},{label:"底部",value:"bottom"},{label:"左侧",value:"left"},{label:"右侧",value:"right"}]}},extraProps:{defaultValue:"bottom"}},{name:"showTooltip",title:"显示提示",setter:"SwitchSetter",extraProps:{defaultValue:!0}}]}]}],{padding:"6px 16px 12px"}),{name:"$data",title:"数据配置",setter:{componentName:"DataSetter",props:{expectedFields:[{name:"name",label:"name",type:"string",required:!0,description:"类目名称"},{name:"value1",label:"value1",type:"number",required:!0,description:"数值1"},{name:"value2",label:"value2",type:"number",required:!1,description:"数值2"}],showPreview:!0,previewLimit:10}},extraProps:{label:!1}}),d=[{name:"A",value1:120,value2:80},{name:"B",value1:200,value2:120},{name:"C",value1:150,value2:100},{name:"D",value1:280,value2:180},{name:"E",value1:220,value2:140}];const u={componentName:n,title:"折线图",group:"chart",devMode:"proCode",npm:{package:"@easy-editor/materials-dashboard-line-chart",version:"0.0.4",globalName:n,componentName:n},snippets:[{title:"折线图",screenshot:"",schema:{componentName:n,title:"折线图",props:{$data:t(d),xField:"name",yFields:["value1","value2"],showGrid:!0,showLegend:!0,glowEffect:!0,strokeWidth:2,rotation:0,opacity:100,background:"transparent"},$dashboard:{rect:{width:400,height:300}}}},{title:"面积图",screenshot:"",schema:{componentName:n,title:"面积图",props:{$data:t(d),xField:"name",yFields:["value1","value2"],showGrid:!0,showLegend:!0,glowEffect:!0,strokeWidth:2,areaFill:!0,rotation:0,opacity:100,background:"transparent"},$dashboard:{rect:{width:400,height:300}}}},{title:"简单折线图",screenshot:"",schema:{componentName:n,title:"简单折线图",props:{$data:t(d),xField:"name",yFields:["value1"],showGrid:!0,showLegend:!1,glowEffect:!0,strokeWidth:3,rotation:0,opacity:100,background:"transparent"},$dashboard:{rect:{width:300,height:200}}}}],configure:p};e.meta=u});
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @easy-editor/easypack configuration
3
+ * @type {import('@easy-editor/easypack').EasypackConfig}
4
+ */
5
+ export default {
6
+ preset: 'material',
7
+ dev: {
8
+ port: 5001,
9
+ },
10
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@easy-editor/materials-dashboard-line-chart",
3
- "version": "0.0.3",
3
+ "version": "0.0.4",
4
4
  "description": "Line Chart component for EasyEditor dashboard",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -48,20 +48,16 @@
48
48
  },
49
49
  "dependencies": {
50
50
  "echarts": "^5.6.0",
51
- "@easy-editor/materials-shared": "0.0.0"
51
+ "@easy-editor/materials-shared": "0.0.1"
52
52
  },
53
53
  "scripts": {
54
- "dev": "vite",
54
+ "dev": "easypack dev",
55
55
  "dev:debug": "vite --port 5002",
56
56
  "format": "biome format --write .",
57
57
  "lint": "biome check .",
58
58
  "build": "npm-run-all -nl build:*",
59
59
  "build:clean": "rimraf dist/",
60
- "build:js": "rollup -c",
61
- "build:types": "pnpm types",
62
- "types": "npm-run-all -nl types:*",
63
- "types:src": "tsc --project tsconfig.build.json",
64
- "test-types": "tsc --project tsconfig.test.json"
60
+ "build:js": "easypack build"
65
61
  },
66
62
  "module": "dist/index.esm.js",
67
63
  "unpkg": "dist/index.min.js"
package/src/component.tsx CHANGED
@@ -1,232 +1,277 @@
1
- import { useEffect, useRef, type CSSProperties, type Ref } from 'react'
2
- import * as echarts from 'echarts/core'
3
- import { LineChart } from 'echarts/charts'
4
- import { GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
5
- import { CanvasRenderer } from 'echarts/renderers'
6
- import type { SeriesOption } from 'echarts'
7
- import { DEFAULT_COLORS, DEFAULT_DATA, type DataPoint } from './constants'
8
- import styles from './component.module.css'
9
-
10
- // 按需注册 ECharts 组件
11
- echarts.use([LineChart, GridComponent, TooltipComponent, LegendComponent, CanvasRenderer])
12
-
13
- interface LineChartProps {
14
- ref?: Ref<HTMLDivElement>
15
- data?: DataPoint[]
16
- xField?: string
17
- yFields?: string[]
18
- colors?: string[]
19
- showGrid?: boolean
20
- showLegend?: boolean
21
- showTooltip?: boolean
22
- glowEffect?: boolean
23
- strokeWidth?: number
24
- areaFill?: boolean
25
- smooth?: boolean
26
- style?: CSSProperties
27
- }
28
-
29
- // 构建 series 配置
30
- const buildSeries = (
31
- yFields: string[],
32
- data: DataPoint[],
33
- colors: string[],
34
- options: {
35
- smooth: boolean
36
- strokeWidth: number
37
- glowEffect: boolean
38
- areaFill: boolean
39
- },
40
- ): SeriesOption[] => {
41
- const { smooth, strokeWidth, glowEffect, areaFill } = options
42
- return yFields.map((field, index) => {
43
- const color = colors[index % colors.length]
44
- return {
45
- name: field,
46
- type: 'line' as const,
47
- data: data.map(item => item[field] as number),
48
- smooth,
49
- lineStyle: {
50
- width: strokeWidth,
51
- color,
52
- shadowColor: glowEffect ? color : 'transparent',
53
- shadowBlur: glowEffect ? 10 : 0,
54
- },
55
- itemStyle: {
56
- color,
57
- },
58
- areaStyle: areaFill
59
- ? {
60
- color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
61
- { offset: 0, color: `${color}40` },
62
- { offset: 1, color: `${color}05` },
63
- ]),
64
- }
65
- : undefined,
66
- symbol: 'circle',
67
- symbolSize: 6,
68
- }
69
- })
70
- }
71
-
72
- // 构建图表配置
73
- const buildOption = (
74
- data: DataPoint[],
75
- xField: string,
76
- series: SeriesOption[],
77
- options: {
78
- showGrid: boolean
79
- showLegend: boolean
80
- showTooltip: boolean
81
- },
82
- ) => {
83
- const { showGrid, showLegend, showTooltip } = options
84
-
85
- return {
86
- backgroundColor: 'transparent',
87
- grid: {
88
- top: showLegend ? 40 : 20,
89
- right: 20,
90
- bottom: 30,
91
- left: 50,
92
- containLabel: false,
93
- },
94
- xAxis: {
95
- type: 'category',
96
- data: data.map(item => item[xField]),
97
- axisLine: {
98
- lineStyle: {
99
- color: '#8899aa',
100
- opacity: 0.3,
101
- },
102
- },
103
- axisTick: { show: false },
104
- axisLabel: {
105
- color: '#8899aa',
106
- fontSize: 12,
107
- },
108
- splitLine: {
109
- show: showGrid,
110
- lineStyle: {
111
- color: '#00d4ff',
112
- opacity: 0.1,
113
- type: 'dashed',
114
- },
115
- },
116
- },
117
- yAxis: {
118
- type: 'value',
119
- axisLine: {
120
- lineStyle: {
121
- color: '#8899aa',
122
- opacity: 0.3,
123
- },
124
- },
125
- axisTick: { show: false },
126
- axisLabel: {
127
- color: '#8899aa',
128
- fontSize: 11,
129
- },
130
- splitLine: {
131
- show: showGrid,
132
- lineStyle: {
133
- color: '#00d4ff',
134
- opacity: 0.1,
135
- type: 'dashed',
136
- },
137
- },
138
- },
139
- tooltip: showTooltip
140
- ? {
141
- trigger: 'axis',
142
- backgroundColor: 'rgba(0, 20, 40, 0.9)',
143
- borderColor: '#00d4ff',
144
- borderWidth: 1,
145
- textStyle: {
146
- color: '#fff',
147
- },
148
- }
149
- : undefined,
150
- legend: showLegend
151
- ? {
152
- show: true,
153
- top: 10,
154
- textStyle: {
155
- color: '#8899aa',
156
- fontSize: 11,
157
- },
158
- }
159
- : undefined,
160
- series,
161
- }
162
- }
163
-
164
- const LineChartComponent = (props: LineChartProps) => {
165
- const {
166
- ref,
167
- data = DEFAULT_DATA,
168
- xField = 'name',
169
- yFields = ['value1', 'value2'],
170
- colors = DEFAULT_COLORS,
171
- showGrid = true,
172
- showLegend = true,
173
- showTooltip = true,
174
- glowEffect = true,
175
- strokeWidth = 2,
176
- areaFill = false,
177
- smooth = true,
178
- style: externalStyle,
179
- } = props
180
-
181
- const chartRef = useRef<HTMLDivElement>(null)
182
- const chartInstance = useRef<echarts.ECharts | null>(null)
183
-
184
- useEffect(() => {
185
- if (!chartRef.current) {
186
- return
187
- }
188
-
189
- chartInstance.current = echarts.init(chartRef.current)
190
-
191
- // 构建 series
192
- const series = buildSeries(yFields, data, colors, {
193
- smooth,
194
- strokeWidth,
195
- glowEffect,
196
- areaFill,
197
- })
198
-
199
- const option = buildOption(data, xField, series, {
200
- showGrid,
201
- showLegend,
202
- showTooltip,
203
- })
204
-
205
- chartInstance.current.setOption(option)
206
-
207
- // 响应式调整
208
- const resizeObserver = new ResizeObserver(() => {
209
- chartInstance.current?.resize()
210
- })
211
- resizeObserver.observe(chartRef.current)
212
-
213
- return () => {
214
- resizeObserver.disconnect()
215
- chartInstance.current?.dispose()
216
- }
217
- }, [data, xField, yFields, colors, showGrid, showLegend, showTooltip, glowEffect, strokeWidth, areaFill, smooth])
218
-
219
- const containerStyle: CSSProperties = {
220
- width: '100%',
221
- height: '100%',
222
- ...externalStyle,
223
- }
224
-
225
- return (
226
- <div className={styles.container} ref={ref} style={containerStyle}>
227
- <div className={styles.chart} ref={chartRef} />
228
- </div>
229
- )
230
- }
231
-
232
- export default LineChartComponent
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
+ }