@wil-works/evoke-charts 0.1.1 → 0.3.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/README.md +10 -6
- package/dist/evoke-charts.css +54 -37
- package/dist/index.mjs +1894 -121
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,12 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
`@wil-works/evoke-charts` — 零依赖 Canvas 自绘图表库(Vue 3)。Evoke 生态的独立图表包,不依赖任何第三方图表引擎,也不依赖 Evoke 其他组件库。
|
|
4
4
|
|
|
5
|
+
**在线文档**:[evoke-charts.wil-works.com](https://evoke-charts.wil-works.com) — 全部图表类型、完整配置项与在线示例。
|
|
6
|
+
|
|
5
7
|
## 特性
|
|
6
8
|
|
|
7
9
|
- **20+ 图表类型**:折线 / 面积 / 柱状 / 堆叠柱 / 条形 / 饼图 / 环形 / 玫瑰图 / 散点(含趋势线)/ 雷达 / 漏斗 / 仪表盘 / 热力图 / K 线 / 子弹图 / 直方图 / 矩形树图 / 旭日图 / 瀑布图 / 箱线图 / 混合图 / 迷你图
|
|
8
10
|
- **零运行时依赖**:仅 peer 依赖 Vue 3,全部绘制自研 Canvas 2D
|
|
9
11
|
- **主题跟随**:从 `--ev-*` CSS 令牌实时读取颜色,宿主换主题 / 暗色即跟随;无令牌时使用内置色板兜底
|
|
10
12
|
- **交互完备**:tooltip、图例点选 / 悬停高亮、十字准线、dataZoom(滑块 / 滚轮 / 触摸平移)、框选刷选、工具箱(导出 PNG / 还原)、多图 connect 联动
|
|
13
|
+
- **叙述与编排**:`annotations[]` 图内旁白(峰值标注 / 区间强调 / 涨跌结论)、`emphasis` 焦点弱化、`scenes` 分幕 reveal / 自动播报
|
|
14
|
+
- **AI 生成**:`generateChartSpec` 数据直生(CSV / 表格 → Spec,列推断与选型全自动)、`buildChartPrompt` 提示词契约(喂给任意大模型)、`lintChartSpec` 渲染自检;Spec 即 `options`,`getSpec / setSpec` 往返
|
|
11
15
|
- **导出**:`toDataURL`(PNG)、`exportSVG`(真矢量,渲染指令录制重放)
|
|
12
16
|
- **无障碍**:`role="img"` + aria-label、hover 信息 aria-live 播报
|
|
13
17
|
|
|
@@ -56,10 +60,10 @@ const options = {
|
|
|
56
60
|
|
|
57
61
|
## 主题接入
|
|
58
62
|
|
|
59
|
-
图表颜色按以下 `--ev-*` 令牌实时读取(`document.documentElement`
|
|
63
|
+
图表颜色按以下 `--ev-*` 令牌实时读取(`document.documentElement` 上取值),未定义的槽位逐槽回落到内置成套色板:
|
|
60
64
|
|
|
61
|
-
- 系列色:`--ev-color-
|
|
62
|
-
- 表面:`--ev-bg-color`、`--ev-bg-color-overlay
|
|
65
|
+
- 系列色:`--ev-color-series-1` … `--ev-color-series-8`(数据系列专用色板,与状态语义色解耦;槽 1 未定义时回读 `--ev-color-primary`,主题跟随不受影响)
|
|
66
|
+
- 表面:`--ev-bg-color`、`--ev-bg-color-overlay`
|
|
63
67
|
- 文字:`--ev-text-color-primary / -secondary / -danger`
|
|
64
68
|
- 边线:`--ev-border-color / -light / -dark`
|
|
65
69
|
- 填充:`--ev-fill-color-light / -dark`
|
|
@@ -67,12 +71,12 @@ const options = {
|
|
|
67
71
|
|
|
68
72
|
暗色跟随约定:在 `html.dark` 选择器下重映射上述令牌(组件内部监听 `<html>` 的 `class` 变化自动重绘)。
|
|
69
73
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
`evoke-business-ui` 依赖本包并以 `EbChart`(模板 `<eb-chart>`)提供同一组件,其样式包内置了 `--eb-*` 令牌到 `--ev-*`(本包读取面)的映射,两库同用时图表自动跟随其主题、暗色与运行时换肤(其换肤时会派发 `ev-theme-change` 事件),无需额外配置。
|
|
74
|
+
图表引擎对宿主保持中立:不为任何组件库做特殊配置;组件库或站点需要个性化时,走通用扩展接口——槽位令牌、`padding` / `theme` / `animation` 配置,以及 `applySeriesPalette` 配色方案工具。
|
|
73
75
|
|
|
74
76
|
## 组件 API(摘要)
|
|
75
77
|
|
|
78
|
+
以下为常用项摘要,各图表类型的独立文档页与完整配置项见[在线文档](https://evoke-charts.wil-works.com/chart)。
|
|
79
|
+
|
|
76
80
|
### Props
|
|
77
81
|
|
|
78
82
|
| 名称 | 类型 | 默认值 | 说明 |
|
package/dist/evoke-charts.css
CHANGED
|
@@ -1,32 +1,44 @@
|
|
|
1
1
|
|
|
2
|
-
.ev-chart[data-v-
|
|
2
|
+
.ev-chart[data-v-ce034a2a] {
|
|
3
3
|
position: relative;
|
|
4
|
-
|
|
4
|
+
/* 容器不带边框:是否加框、加多粗由宿主决定,图表只负责内容;
|
|
5
|
+
圆角裁剪下沉到 canvas 与浮层自身(border-radius: inherit) */
|
|
6
|
+
overflow: visible;
|
|
5
7
|
border-radius: 8px;
|
|
6
8
|
background: var(--ev-bg-color, #ffffff);
|
|
7
|
-
border: 1px solid var(--ev-app-card-border, #e2e8f0);
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
/* 关键:canvas 必须能接收鼠标事件 */
|
|
11
|
-
.ev-chart__canvas[data-v-
|
|
12
|
+
.ev-chart__canvas[data-v-ce034a2a] {
|
|
12
13
|
position: absolute;
|
|
13
14
|
top: 0;
|
|
14
15
|
left: 0;
|
|
15
16
|
width: 100%;
|
|
16
17
|
height: 100%;
|
|
17
18
|
display: block;
|
|
19
|
+
border-radius: inherit;
|
|
18
20
|
/* 触摸:纵向留给页面滚动,横向拖拽由图表接管(dataZoom 平移) */
|
|
19
21
|
touch-action: pan-y;
|
|
20
22
|
}
|
|
21
|
-
|
|
23
|
+
|
|
24
|
+
/* HTML 覆盖层:只在内容层,不与 canvas 抢交互(子元素可自行 pointer-events:auto),
|
|
25
|
+
也不压过 tooltip(z-index 100) */
|
|
26
|
+
.ev-chart__overlay[data-v-ce034a2a] {
|
|
27
|
+
position: absolute;
|
|
28
|
+
inset: 0;
|
|
29
|
+
z-index: 1;
|
|
30
|
+
pointer-events: none;
|
|
31
|
+
border-radius: inherit;
|
|
32
|
+
}
|
|
33
|
+
.ev-chart__tooltip[data-v-ce034a2a] {
|
|
22
34
|
position: absolute;
|
|
23
35
|
pointer-events: none;
|
|
24
36
|
z-index: 100;
|
|
25
|
-
padding:
|
|
37
|
+
padding: 9px 12px;
|
|
26
38
|
background: var(--ev-bg-color-overlay, #ffffff);
|
|
27
39
|
border: 1px solid var(--ev-border-color, #e2e8f0);
|
|
28
|
-
border-radius:
|
|
29
|
-
box-shadow: 0
|
|
40
|
+
border-radius: 10px;
|
|
41
|
+
box-shadow: 0 6px 20px rgba(15, 23, 42, 0.12);
|
|
30
42
|
font-size: 13px;
|
|
31
43
|
line-height: 1.6;
|
|
32
44
|
white-space: nowrap;
|
|
@@ -39,47 +51,47 @@
|
|
|
39
51
|
}
|
|
40
52
|
|
|
41
53
|
/* tooltip 淡入淡出(仅 opacity,位置由 left/top transition 负责) */
|
|
42
|
-
.ev-chart-tooltip-enter-active[data-v-
|
|
43
|
-
.ev-chart-tooltip-leave-active[data-v-
|
|
54
|
+
.ev-chart-tooltip-enter-active[data-v-ce034a2a],
|
|
55
|
+
.ev-chart-tooltip-leave-active[data-v-ce034a2a] {
|
|
44
56
|
transition: opacity 0.18s ease;
|
|
45
57
|
}
|
|
46
58
|
|
|
47
59
|
/* 进入期间禁用位置 transition,避免首次出现时从旧位置滑入 */
|
|
48
|
-
.ev-chart-tooltip-enter-active[data-v-
|
|
60
|
+
.ev-chart-tooltip-enter-active[data-v-ce034a2a] {
|
|
49
61
|
transition:
|
|
50
62
|
opacity 0.18s ease,
|
|
51
63
|
left 0s,
|
|
52
64
|
top 0s;
|
|
53
65
|
}
|
|
54
|
-
.ev-chart-tooltip-enter-from[data-v-
|
|
55
|
-
.ev-chart-tooltip-leave-to[data-v-
|
|
66
|
+
.ev-chart-tooltip-enter-from[data-v-ce034a2a],
|
|
67
|
+
.ev-chart-tooltip-leave-to[data-v-ce034a2a] {
|
|
56
68
|
opacity: 0;
|
|
57
69
|
}
|
|
58
70
|
|
|
59
71
|
/* v-html 注入的内容不带 scoped 属性,需用 :deep() 穿透 */
|
|
60
|
-
[data-v-
|
|
72
|
+
[data-v-ce034a2a] .ev-chart__tooltip-title {
|
|
61
73
|
color: var(--ev-text-color-secondary, #6b7280);
|
|
62
74
|
font-size: 12px;
|
|
63
75
|
margin-bottom: 6px;
|
|
64
76
|
font-weight: 500;
|
|
65
77
|
}
|
|
66
|
-
[data-v-
|
|
78
|
+
[data-v-ce034a2a] .ev-chart__tooltip-item {
|
|
67
79
|
display: flex;
|
|
68
80
|
align-items: center;
|
|
69
81
|
gap: 8px;
|
|
70
82
|
padding: 2px 0;
|
|
71
83
|
}
|
|
72
|
-
[data-v-
|
|
84
|
+
[data-v-ce034a2a] .ev-chart__tooltip-dot {
|
|
73
85
|
width: 8px;
|
|
74
86
|
height: 8px;
|
|
75
87
|
border-radius: 50%;
|
|
76
88
|
flex-shrink: 0;
|
|
77
89
|
display: inline-block;
|
|
78
90
|
}
|
|
79
|
-
[data-v-
|
|
91
|
+
[data-v-ce034a2a] .ev-chart__tooltip-name {
|
|
80
92
|
color: var(--ev-text-color-primary, #111827);
|
|
81
93
|
}
|
|
82
|
-
[data-v-
|
|
94
|
+
[data-v-ce034a2a] .ev-chart__tooltip-value {
|
|
83
95
|
color: var(--ev-text-color-primary, #111827);
|
|
84
96
|
font-weight: 600;
|
|
85
97
|
margin-left: auto;
|
|
@@ -88,9 +100,10 @@
|
|
|
88
100
|
}
|
|
89
101
|
|
|
90
102
|
/* ══════ 空数据占位 ══════ */
|
|
91
|
-
.ev-chart__empty[data-v-
|
|
103
|
+
.ev-chart__empty[data-v-ce034a2a] {
|
|
92
104
|
position: absolute;
|
|
93
105
|
inset: 0;
|
|
106
|
+
border-radius: inherit;
|
|
94
107
|
display: flex;
|
|
95
108
|
flex-direction: column;
|
|
96
109
|
align-items: center;
|
|
@@ -100,7 +113,7 @@
|
|
|
100
113
|
gap: 14px;
|
|
101
114
|
user-select: none;
|
|
102
115
|
}
|
|
103
|
-
.ev-chart__empty-icon-wrap[data-v-
|
|
116
|
+
.ev-chart__empty-icon-wrap[data-v-ce034a2a] {
|
|
104
117
|
display: flex;
|
|
105
118
|
align-items: center;
|
|
106
119
|
justify-content: center;
|
|
@@ -109,40 +122,41 @@
|
|
|
109
122
|
border-radius: 16px;
|
|
110
123
|
background: var(--ev-fill-color-light, #f5f7fa);
|
|
111
124
|
}
|
|
112
|
-
.ev-chart__empty-img[data-v-
|
|
125
|
+
.ev-chart__empty-img[data-v-ce034a2a] {
|
|
113
126
|
width: 32px;
|
|
114
127
|
height: 32px;
|
|
115
128
|
opacity: 0.4;
|
|
116
129
|
}
|
|
117
|
-
.ev-chart__empty-text[data-v-
|
|
130
|
+
.ev-chart__empty-text[data-v-ce034a2a] {
|
|
118
131
|
letter-spacing: 0.04em;
|
|
119
132
|
font-weight: 500;
|
|
120
133
|
font-size: 13px;
|
|
121
134
|
}
|
|
122
135
|
|
|
123
136
|
/* ══════ 加载中骨架 ══════ */
|
|
124
|
-
.ev-chart__loading[data-v-
|
|
137
|
+
.ev-chart__loading[data-v-ce034a2a] {
|
|
125
138
|
position: absolute;
|
|
126
139
|
inset: 0;
|
|
140
|
+
border-radius: inherit;
|
|
127
141
|
display: flex;
|
|
128
142
|
align-items: center;
|
|
129
143
|
justify-content: center;
|
|
130
144
|
background: var(--ev-bg-color, #ffffff);
|
|
131
145
|
}
|
|
132
|
-
.ev-chart__loading-bars[data-v-
|
|
146
|
+
.ev-chart__loading-bars[data-v-ce034a2a] {
|
|
133
147
|
display: flex;
|
|
134
148
|
align-items: flex-end;
|
|
135
149
|
gap: 6px;
|
|
136
150
|
height: 60px;
|
|
137
151
|
}
|
|
138
|
-
.ev-chart__loading-bar[data-v-
|
|
152
|
+
.ev-chart__loading-bar[data-v-ce034a2a] {
|
|
139
153
|
width: 10px;
|
|
140
154
|
height: 40px;
|
|
141
155
|
border-radius: 4px;
|
|
142
156
|
background: var(--ev-border-color, #e2e8f0);
|
|
143
|
-
animation: ev-chart-shimmer-
|
|
157
|
+
animation: ev-chart-shimmer-ce034a2a 1.2s ease-in-out infinite;
|
|
144
158
|
}
|
|
145
|
-
@keyframes ev-chart-shimmer-
|
|
159
|
+
@keyframes ev-chart-shimmer-ce034a2a {
|
|
146
160
|
0%,
|
|
147
161
|
100% {
|
|
148
162
|
transform: scaleY(0.4);
|
|
@@ -155,9 +169,10 @@
|
|
|
155
169
|
}
|
|
156
170
|
|
|
157
171
|
/* ══════ 错误边界 ══════ */
|
|
158
|
-
.ev-chart__error[data-v-
|
|
172
|
+
.ev-chart__error[data-v-ce034a2a] {
|
|
159
173
|
position: absolute;
|
|
160
174
|
inset: 0;
|
|
175
|
+
border-radius: inherit;
|
|
161
176
|
display: flex;
|
|
162
177
|
flex-direction: column;
|
|
163
178
|
align-items: center;
|
|
@@ -168,11 +183,13 @@
|
|
|
168
183
|
padding: 20px;
|
|
169
184
|
text-align: center;
|
|
170
185
|
}
|
|
171
|
-
.ev-chart__error-icon[data-v-
|
|
172
|
-
|
|
173
|
-
|
|
186
|
+
.ev-chart__error-icon[data-v-ce034a2a] {
|
|
187
|
+
display: flex;
|
|
188
|
+
align-items: center;
|
|
189
|
+
justify-content: center;
|
|
190
|
+
font-size: 30px;
|
|
174
191
|
}
|
|
175
|
-
.ev-chart__error-text[data-v-
|
|
192
|
+
.ev-chart__error-text[data-v-ce034a2a] {
|
|
176
193
|
font-size: 12px;
|
|
177
194
|
line-height: 1.5;
|
|
178
195
|
max-width: 80%;
|
|
@@ -180,17 +197,17 @@
|
|
|
180
197
|
}
|
|
181
198
|
|
|
182
199
|
/* ══════ 进入/离开淡入淡出 ══════ */
|
|
183
|
-
.ev-chart-fade-enter-active[data-v-
|
|
184
|
-
.ev-chart-fade-leave-active[data-v-
|
|
200
|
+
.ev-chart-fade-enter-active[data-v-ce034a2a],
|
|
201
|
+
.ev-chart-fade-leave-active[data-v-ce034a2a] {
|
|
185
202
|
transition: opacity 0.2s ease;
|
|
186
203
|
}
|
|
187
|
-
.ev-chart-fade-enter-from[data-v-
|
|
188
|
-
.ev-chart-fade-leave-to[data-v-
|
|
204
|
+
.ev-chart-fade-enter-from[data-v-ce034a2a],
|
|
205
|
+
.ev-chart-fade-leave-to[data-v-ce034a2a] {
|
|
189
206
|
opacity: 0;
|
|
190
207
|
}
|
|
191
208
|
|
|
192
209
|
/* ══════ 无障碍:sr-only ══════ */
|
|
193
|
-
.ev-chart__sr-only[data-v-
|
|
210
|
+
.ev-chart__sr-only[data-v-ce034a2a] {
|
|
194
211
|
position: absolute;
|
|
195
212
|
width: 1px;
|
|
196
213
|
height: 1px;
|