@easy-editor/materials-dashboard-gauge-chart 0.0.2

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.
Files changed (48) hide show
  1. package/.vite/plugins/vite-plugin-external-deps.ts +224 -0
  2. package/.vite/plugins/vite-plugin-material-dev.ts +218 -0
  3. package/CHANGELOG.md +7 -0
  4. package/LICENSE +9 -0
  5. package/dist/component.esm.js +28857 -0
  6. package/dist/component.esm.js.map +1 -0
  7. package/dist/component.js +28864 -0
  8. package/dist/component.js.map +1 -0
  9. package/dist/component.min.js +24 -0
  10. package/dist/component.min.js.map +1 -0
  11. package/dist/index.cjs +29174 -0
  12. package/dist/index.cjs.map +1 -0
  13. package/dist/index.esm.js +29171 -0
  14. package/dist/index.esm.js.map +1 -0
  15. package/dist/index.js +29178 -0
  16. package/dist/index.js.map +1 -0
  17. package/dist/index.min.js +24 -0
  18. package/dist/index.min.js.map +1 -0
  19. package/dist/meta.esm.js +319 -0
  20. package/dist/meta.esm.js.map +1 -0
  21. package/dist/meta.js +329 -0
  22. package/dist/meta.js.map +1 -0
  23. package/dist/meta.min.js +2 -0
  24. package/dist/meta.min.js.map +1 -0
  25. package/dist/src/component.d.ts +19 -0
  26. package/dist/src/configure.d.ts +7 -0
  27. package/dist/src/constants.d.ts +28 -0
  28. package/dist/src/index.d.ts +6 -0
  29. package/dist/src/meta.d.ts +3 -0
  30. package/dist/src/snippets.d.ts +3 -0
  31. package/dist/src/types.d.ts +50 -0
  32. package/dist/src/utils.d.ts +28 -0
  33. package/package.json +67 -0
  34. package/rollup.config.js +212 -0
  35. package/src/component.module.css +16 -0
  36. package/src/component.tsx +180 -0
  37. package/src/configure.ts +285 -0
  38. package/src/constants.ts +37 -0
  39. package/src/index.tsx +7 -0
  40. package/src/meta.ts +23 -0
  41. package/src/snippets.ts +55 -0
  42. package/src/type.d.ts +8 -0
  43. package/src/types.ts +55 -0
  44. package/src/utils.ts +57 -0
  45. package/tsconfig.build.json +12 -0
  46. package/tsconfig.json +9 -0
  47. package/tsconfig.test.json +7 -0
  48. package/vite.config.ts +54 -0
@@ -0,0 +1,180 @@
1
+ import { useEffect, useRef, type CSSProperties, type Ref } from 'react'
2
+ import * as echarts from 'echarts/core'
3
+ import { GaugeChart } from 'echarts/charts'
4
+ import { TooltipComponent } from 'echarts/components'
5
+ import { CanvasRenderer } from 'echarts/renderers'
6
+ import type { EChartsOption } from 'echarts'
7
+ import { DEFAULT_RANGES, type GaugeRange } from './constants'
8
+ import styles from './component.module.css'
9
+
10
+ // 按需注册 ECharts 组件
11
+ echarts.use([GaugeChart, TooltipComponent, CanvasRenderer])
12
+
13
+ interface GaugeChartProps {
14
+ ref?: Ref<HTMLDivElement>
15
+ value?: number
16
+ min?: number
17
+ max?: number
18
+ unit?: string
19
+ showScale?: boolean
20
+ divisions?: number
21
+ showLabels?: boolean
22
+ pointerType?: 'needle' | 'triangle' | 'rect'
23
+ pointerColor?: string
24
+ ranges?: GaugeRange[]
25
+ glowEffect?: boolean
26
+ style?: CSSProperties
27
+ }
28
+
29
+ const GaugeChartComponent = (props: GaugeChartProps) => {
30
+ const {
31
+ ref,
32
+ value = 0,
33
+ min = 0,
34
+ max = 100,
35
+ unit = '',
36
+ showScale = true,
37
+ divisions = 10,
38
+ showLabels = true,
39
+ pointerType = 'needle',
40
+ pointerColor = '#00d4ff',
41
+ ranges = DEFAULT_RANGES,
42
+ glowEffect = true,
43
+ style: externalStyle,
44
+ } = props
45
+
46
+ const chartRef = useRef<HTMLDivElement>(null)
47
+ const chartInstance = useRef<echarts.ECharts | null>(null)
48
+
49
+ useEffect(() => {
50
+ if (!chartRef.current) {
51
+ return
52
+ }
53
+
54
+ chartInstance.current = echarts.init(chartRef.current)
55
+
56
+ // 构建颜色区间
57
+ const axisLineColors: [number, string][] = ranges.map(range => [(range.to - min) / (max - min), range.color])
58
+
59
+ // 指针宽度根据类型调整
60
+ const pointerWidthMap: Record<string, number> = {
61
+ needle: 4,
62
+ triangle: 8,
63
+ rect: 6,
64
+ }
65
+ const pointerWidth = pointerWidthMap[pointerType] ?? 6
66
+
67
+ const option: EChartsOption = {
68
+ backgroundColor: 'transparent',
69
+ series: [
70
+ {
71
+ type: 'gauge',
72
+ min,
73
+ max,
74
+ startAngle: 180,
75
+ endAngle: 0,
76
+ center: ['50%', '70%'],
77
+ radius: '90%',
78
+ progress: {
79
+ show: false,
80
+ },
81
+ axisLine: {
82
+ lineStyle: {
83
+ width: 20,
84
+ color: axisLineColors,
85
+ shadowColor: glowEffect ? 'rgba(0, 212, 255, 0.3)' : 'transparent',
86
+ shadowBlur: glowEffect ? 10 : 0,
87
+ },
88
+ },
89
+ axisTick: {
90
+ show: showScale,
91
+ distance: -25,
92
+ length: 6,
93
+ lineStyle: {
94
+ color: '#8899aa',
95
+ width: 1,
96
+ },
97
+ splitNumber: divisions / 5,
98
+ },
99
+ splitLine: {
100
+ show: showScale,
101
+ distance: -30,
102
+ length: 12,
103
+ lineStyle: {
104
+ color: '#8899aa',
105
+ width: 2,
106
+ },
107
+ },
108
+ axisLabel: {
109
+ show: showLabels,
110
+ distance: -40,
111
+ color: '#8899aa',
112
+ fontSize: 10,
113
+ },
114
+ pointer: {
115
+ show: true,
116
+ length: '60%',
117
+ width: pointerWidth,
118
+ itemStyle: {
119
+ color: pointerColor,
120
+ shadowColor: glowEffect ? pointerColor : 'transparent',
121
+ shadowBlur: glowEffect ? 10 : 0,
122
+ },
123
+ },
124
+ anchor: {
125
+ show: true,
126
+ size: 12,
127
+ itemStyle: {
128
+ color: pointerColor,
129
+ shadowColor: glowEffect ? pointerColor : 'transparent',
130
+ shadowBlur: glowEffect ? 5 : 0,
131
+ },
132
+ },
133
+ title: {
134
+ show: true,
135
+ offsetCenter: [0, '30%'],
136
+ color: '#8899aa',
137
+ fontSize: 12,
138
+ },
139
+ detail: {
140
+ valueAnimation: true,
141
+ offsetCenter: [0, '50%'],
142
+ fontSize: 28,
143
+ fontWeight: 'bold',
144
+ color: '#fff',
145
+ formatter: (val: number) => `${val}${unit}`,
146
+ textShadowColor: glowEffect ? 'rgba(0, 212, 255, 0.5)' : 'transparent',
147
+ textShadowBlur: glowEffect ? 10 : 0,
148
+ },
149
+ data: [{ value }],
150
+ },
151
+ ],
152
+ }
153
+
154
+ chartInstance.current.setOption(option)
155
+
156
+ const resizeObserver = new ResizeObserver(() => {
157
+ chartInstance.current?.resize()
158
+ })
159
+ resizeObserver.observe(chartRef.current)
160
+
161
+ return () => {
162
+ resizeObserver.disconnect()
163
+ chartInstance.current?.dispose()
164
+ }
165
+ }, [value, min, max, unit, showScale, divisions, showLabels, pointerType, pointerColor, ranges, glowEffect])
166
+
167
+ const containerStyle: CSSProperties = {
168
+ width: '100%',
169
+ height: '100%',
170
+ ...externalStyle,
171
+ }
172
+
173
+ return (
174
+ <div className={styles.container} ref={ref} style={containerStyle}>
175
+ <div className={styles.chart} ref={chartRef} />
176
+ </div>
177
+ )
178
+ }
179
+
180
+ export default GaugeChartComponent
@@ -0,0 +1,285 @@
1
+ /**
2
+ * Gauge Chart Configure
3
+ * 仪表盘组件配置
4
+ */
5
+
6
+ import type { Configure } from '@easy-editor/core'
7
+
8
+ const configure: Configure = {
9
+ props: [
10
+ {
11
+ type: 'group',
12
+ title: '属性',
13
+ setter: 'TabSetter',
14
+ items: [
15
+ {
16
+ type: 'group',
17
+ key: 'config',
18
+ title: '配置',
19
+ setter: {
20
+ componentName: 'CollapseSetter',
21
+ props: {
22
+ icon: false,
23
+ },
24
+ },
25
+ items: [
26
+ // 基础配置
27
+ {
28
+ name: 'id',
29
+ title: 'ID',
30
+ setter: 'NodeIdSetter',
31
+ extraProps: {
32
+ // @ts-expect-error label is not a valid extra prop
33
+ label: false,
34
+ },
35
+ },
36
+ {
37
+ name: 'title',
38
+ title: '标题',
39
+ setter: 'StringSetter',
40
+ extraProps: {
41
+ getValue(target) {
42
+ return target.getExtraPropValue('title')
43
+ },
44
+ setValue(target, value) {
45
+ target.setExtraPropValue('title', value)
46
+ },
47
+ },
48
+ },
49
+ {
50
+ type: 'group',
51
+ title: '基础属性',
52
+ setter: {
53
+ componentName: 'CollapseSetter',
54
+ props: {
55
+ icon: false,
56
+ },
57
+ },
58
+ items: [
59
+ {
60
+ name: 'rect',
61
+ title: '位置尺寸',
62
+ setter: 'RectSetter',
63
+ extraProps: {
64
+ getValue(target) {
65
+ return target.getExtraPropValue('$dashboard.rect')
66
+ },
67
+ setValue(target, value) {
68
+ target.setExtraPropValue('$dashboard.rect', value)
69
+ },
70
+ },
71
+ },
72
+ ],
73
+ },
74
+ // 组件配置
75
+ {
76
+ type: 'group',
77
+ title: '数值',
78
+ setter: {
79
+ componentName: 'CollapseSetter',
80
+ props: {
81
+ icon: false,
82
+ },
83
+ },
84
+ items: [
85
+ {
86
+ name: 'value',
87
+ title: '当前值',
88
+ setter: 'NumberSetter',
89
+ extraProps: {
90
+ defaultValue: 0,
91
+ },
92
+ },
93
+ {
94
+ name: 'min',
95
+ title: '最小值',
96
+ setter: 'NumberSetter',
97
+ extraProps: {
98
+ defaultValue: 0,
99
+ },
100
+ },
101
+ {
102
+ name: 'max',
103
+ title: '最大值',
104
+ setter: 'NumberSetter',
105
+ extraProps: {
106
+ defaultValue: 100,
107
+ },
108
+ },
109
+ {
110
+ name: 'unit',
111
+ title: '单位',
112
+ setter: 'StringSetter',
113
+ },
114
+ ],
115
+ },
116
+ {
117
+ type: 'group',
118
+ title: '数值格式',
119
+ setter: {
120
+ componentName: 'CollapseSetter',
121
+ props: {
122
+ icon: false,
123
+ },
124
+ },
125
+ items: [
126
+ {
127
+ name: 'valuePrefix',
128
+ title: '前缀',
129
+ setter: 'StringSetter',
130
+ },
131
+ {
132
+ name: 'valueSuffix',
133
+ title: '后缀',
134
+ setter: 'StringSetter',
135
+ },
136
+ {
137
+ name: 'valueDecimals',
138
+ title: '小数位数',
139
+ setter: {
140
+ componentName: 'NumberSetter',
141
+ props: {
142
+ suffix: '位',
143
+ },
144
+ },
145
+ extraProps: {
146
+ defaultValue: 0,
147
+ },
148
+ },
149
+ {
150
+ name: 'valueSeparator',
151
+ title: '千分位分隔',
152
+ setter: 'SwitchSetter',
153
+ extraProps: {
154
+ defaultValue: false,
155
+ },
156
+ },
157
+ ],
158
+ },
159
+ {
160
+ type: 'group',
161
+ title: '刻度',
162
+ setter: {
163
+ componentName: 'CollapseSetter',
164
+ props: {
165
+ icon: false,
166
+ },
167
+ },
168
+ items: [
169
+ {
170
+ name: 'showScale',
171
+ title: '显示刻度',
172
+ setter: 'SwitchSetter',
173
+ extraProps: {
174
+ defaultValue: true,
175
+ },
176
+ },
177
+ {
178
+ name: 'divisions',
179
+ title: '刻度数量',
180
+ setter: {
181
+ componentName: 'SliderSetter',
182
+ props: {
183
+ min: 2,
184
+ max: 20,
185
+ step: 1,
186
+ },
187
+ },
188
+ extraProps: {
189
+ defaultValue: 10,
190
+ },
191
+ },
192
+ {
193
+ name: 'showLabels',
194
+ title: '显示刻度值',
195
+ setter: 'SwitchSetter',
196
+ extraProps: {
197
+ defaultValue: true,
198
+ },
199
+ },
200
+ ],
201
+ },
202
+ {
203
+ type: 'group',
204
+ title: '样式',
205
+ setter: {
206
+ componentName: 'CollapseSetter',
207
+ props: {
208
+ icon: false,
209
+ },
210
+ },
211
+ items: [
212
+ {
213
+ name: 'pointerType',
214
+ title: '指针类型',
215
+ setter: {
216
+ componentName: 'SegmentedSetter',
217
+ props: {
218
+ options: [
219
+ { label: '针形', value: 'needle' },
220
+ { label: '三角形', value: 'triangle' },
221
+ { label: '矩形', value: 'rect' },
222
+ ],
223
+ },
224
+ },
225
+ extraProps: {
226
+ defaultValue: 'needle',
227
+ },
228
+ },
229
+ {
230
+ name: 'pointerColor',
231
+ title: '指针颜色',
232
+ setter: 'ColorSetter',
233
+ extraProps: {
234
+ defaultValue: '#ffffff',
235
+ },
236
+ },
237
+ {
238
+ name: 'glowEffect',
239
+ title: '发光效果',
240
+ setter: 'SwitchSetter',
241
+ extraProps: {
242
+ defaultValue: false,
243
+ },
244
+ },
245
+ ],
246
+ },
247
+ ],
248
+ },
249
+ {
250
+ type: 'group',
251
+ key: 'data',
252
+ title: '数据',
253
+ items: [
254
+ {
255
+ name: 'dataBinding',
256
+ title: '数据绑定',
257
+ setter: 'DataBindingSetter',
258
+ },
259
+ ],
260
+ },
261
+ {
262
+ type: 'group',
263
+ key: 'advanced',
264
+ title: '高级',
265
+ items: [
266
+ {
267
+ name: 'condition',
268
+ title: '显隐控制',
269
+ setter: 'SwitchSetter',
270
+ extraProps: {
271
+ defaultValue: true,
272
+ supportVariable: true,
273
+ },
274
+ },
275
+ ],
276
+ },
277
+ ],
278
+ },
279
+ ],
280
+ component: {},
281
+ supports: {},
282
+ advanced: {},
283
+ }
284
+
285
+ export default configure
@@ -0,0 +1,37 @@
1
+ /**
2
+ * 物料常量配置
3
+ * 统一管理全局变量名等配置,确保 meta.ts 和 rollup.config.js 使用相同的值
4
+ */
5
+
6
+ /**
7
+ * UMD 全局变量基础名称
8
+ */
9
+ export const COMPONENT_NAME = 'EasyEditorMaterialsGaugeChart'
10
+
11
+ /**
12
+ * 包名
13
+ */
14
+ export const PACKAGE_NAME = '@easy-editor/materials-dashboard-gauge-chart'
15
+
16
+ /**
17
+ * 指针类型
18
+ */
19
+ export const POINTER_TYPES = ['needle', 'triangle', 'rect'] as const
20
+
21
+ /**
22
+ * 颜色区间类型
23
+ */
24
+ export interface GaugeRange {
25
+ from: number
26
+ to: number
27
+ color: string
28
+ }
29
+
30
+ /**
31
+ * 默认颜色区间
32
+ */
33
+ export const DEFAULT_RANGES: GaugeRange[] = [
34
+ { from: 0, to: 40, color: '#00ff88' },
35
+ { from: 40, to: 70, color: '#ffcc00' },
36
+ { from: 70, to: 100, color: '#ff4444' },
37
+ ]
package/src/index.tsx ADDED
@@ -0,0 +1,7 @@
1
+ /**
2
+ * GaugeChart Entry
3
+ * 仪表盘组件入口
4
+ */
5
+
6
+ export { default as component } from './component'
7
+ export { default as meta } from './meta'
package/src/meta.ts ADDED
@@ -0,0 +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 default meta
@@ -0,0 +1,55 @@
1
+ import type { Snippet } from '@easy-editor/core'
2
+ import { COMPONENT_NAME } from './constants'
3
+
4
+ const snippets: Snippet[] = [
5
+ {
6
+ title: '仪表盘',
7
+ screenshot: '',
8
+ schema: {
9
+ componentName: COMPONENT_NAME,
10
+ props: {
11
+ value: 65,
12
+ min: 0,
13
+ max: 100,
14
+ showScale: true,
15
+ divisions: 10,
16
+ showLabels: true,
17
+ pointerType: 'needle',
18
+ pointerColor: '#ffffff',
19
+ },
20
+ $dashboard: {
21
+ rect: {
22
+ width: 220,
23
+ height: 140,
24
+ },
25
+ },
26
+ },
27
+ },
28
+ {
29
+ title: '发光仪表盘',
30
+ screenshot: '',
31
+ schema: {
32
+ componentName: COMPONENT_NAME,
33
+ props: {
34
+ value: 78,
35
+ min: 0,
36
+ max: 100,
37
+ unit: '%',
38
+ showScale: true,
39
+ divisions: 10,
40
+ showLabels: true,
41
+ pointerType: 'needle',
42
+ pointerColor: '#00ffff',
43
+ glowEffect: true,
44
+ },
45
+ $dashboard: {
46
+ rect: {
47
+ width: 220,
48
+ height: 140,
49
+ },
50
+ },
51
+ },
52
+ },
53
+ ]
54
+
55
+ export default snippets
package/src/type.d.ts ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * CSS Modules Type Declarations
3
+ */
4
+
5
+ declare module '*.module.css' {
6
+ const classes: { readonly [key: string]: string }
7
+ export default classes
8
+ }
package/src/types.ts ADDED
@@ -0,0 +1,55 @@
1
+ /**
2
+ * GaugeChart 类型定义
3
+ */
4
+
5
+ import type { CSSProperties, Ref } from 'react'
6
+
7
+ /**
8
+ * 颜色区间定义
9
+ */
10
+ export interface GaugeRange {
11
+ from: number
12
+ to: number
13
+ color: string
14
+ }
15
+
16
+ /**
17
+ * GaugeChart 组件属性
18
+ */
19
+ export interface GaugeChartProps {
20
+ ref?: Ref<HTMLDivElement>
21
+ value?: number
22
+ min?: number
23
+ max?: number
24
+ unit?: string
25
+ showScale?: boolean
26
+ divisions?: number
27
+ showLabels?: boolean
28
+ pointerType?: 'needle' | 'triangle' | 'rect'
29
+ pointerColor?: string
30
+ ranges?: GaugeRange[]
31
+ glowEffect?: boolean
32
+ style?: CSSProperties
33
+ }
34
+
35
+ /**
36
+ * 仪表盘配置参数
37
+ */
38
+ export interface GaugeConfig {
39
+ size: number
40
+ center: number
41
+ outerRadius: number
42
+ innerRadius: number
43
+ scaleRadius: number
44
+ startAngle: number
45
+ endAngle: number
46
+ angleRange: number
47
+ }
48
+
49
+ /**
50
+ * 点坐标
51
+ */
52
+ export interface Point {
53
+ x: number
54
+ y: number
55
+ }
package/src/utils.ts ADDED
@@ -0,0 +1,57 @@
1
+ /**
2
+ * GaugeChart SVG 辅助函数
3
+ */
4
+
5
+ import type { Point } from './types'
6
+
7
+ /**
8
+ * 将角度转换为弧度
9
+ */
10
+ export const degToRad = (deg: number): number => (deg * Math.PI) / 180
11
+
12
+ /**
13
+ * 根据角度计算圆上的点坐标
14
+ */
15
+ export const polarToCartesian = (cx: number, cy: number, radius: number, angleDeg: number): Point => {
16
+ const rad = degToRad(angleDeg)
17
+ return {
18
+ x: cx + radius * Math.cos(rad),
19
+ y: cy + radius * Math.sin(rad),
20
+ }
21
+ }
22
+
23
+ /**
24
+ * 生成圆弧路径
25
+ */
26
+ // biome-ignore lint: 参数过多是数学函数需要
27
+ export const describeArc = (cx: number, cy: number, radius: number, startAngle: number, endAngle: number): string => {
28
+ const start = polarToCartesian(cx, cy, radius, endAngle)
29
+ const end = polarToCartesian(cx, cy, radius, startAngle)
30
+ const largeArcFlag = endAngle - startAngle <= 180 ? '0' : '1'
31
+ return ['M', start.x, start.y, 'A', radius, radius, 0, largeArcFlag, 0, end.x, end.y].join(' ')
32
+ }
33
+
34
+ /**
35
+ * 生成唯一 ID
36
+ */
37
+ export const generateUniqueId = (prefix: string): string => `${prefix}-${Math.random().toString(36).substr(2, 9)}`
38
+
39
+ /**
40
+ * 计算归一化值
41
+ */
42
+ export const normalizeValue = (value: number, min: number, max: number): number => Math.min(Math.max(value, min), max)
43
+
44
+ /**
45
+ * 计算值对应的角度
46
+ */
47
+ // biome-ignore lint: 参数过多是数学函数需要
48
+ export const valueToAngle = (
49
+ value: number,
50
+ min: number,
51
+ max: number,
52
+ startAngle: number,
53
+ angleRange: number,
54
+ ): number => {
55
+ const ratio = (value - min) / (max - min)
56
+ return startAngle - ratio * angleRange
57
+ }