@antv/gpt-vis 1.0.0-beta.2 → 1.0.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 +217 -43
- package/README.zh-CN.md +221 -47
- package/dist/cjs/gpt-vis/index.js +1 -1
- package/dist/cjs/vis/dual-axes/index.js +1 -2
- package/dist/cjs/vis/fishbone-diagram/index.js +12 -4
- package/dist/cjs/vis/flow-diagram/index.js +27 -11
- package/dist/cjs/vis/indented-tree/index.js +13 -3
- package/dist/cjs/vis/mindmap/index.js +12 -4
- package/dist/cjs/vis/network-graph/index.js +11 -2
- package/dist/cjs/vis/organization-chart/index.js +12 -3
- package/dist/cjs/vis/scatter/index.d.ts +2 -0
- package/dist/cjs/vis/scatter/index.js +7 -3
- package/dist/cjs/vis/waterfall/index.js +1 -1
- package/dist/esm/gpt-vis/index.js +1 -1
- package/dist/esm/vis/dual-axes/index.js +10 -3
- package/dist/esm/vis/fishbone-diagram/index.js +6 -5
- package/dist/esm/vis/flow-diagram/index.js +17 -10
- package/dist/esm/vis/indented-tree/index.js +9 -4
- package/dist/esm/vis/mindmap/index.js +6 -5
- package/dist/esm/vis/network-graph/index.js +5 -3
- package/dist/esm/vis/organization-chart/index.js +6 -4
- package/dist/esm/vis/scatter/index.d.ts +2 -0
- package/dist/esm/vis/scatter/index.js +12 -2
- package/dist/esm/vis/waterfall/index.js +6 -4
- package/dist/umd/index.min.js +1 -1
- package/package.json +2 -6
package/README.zh-CN.md
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
1
|
<img src="https://gw.alipayobjects.com/zos/antfincdn/R8sN%24GNdh6/language.svg" width="18"> [English](./README.md) | 简体中文
|
|
2
2
|
|
|
3
|
-
<
|
|
3
|
+
<div align="center">
|
|
4
|
+
<img src="https://github.com/eosphoros-ai/GPT-Vis/assets/17919400/c8804ffb-d3d6-45d3-846f-cf217681ab05" height="70" />
|
|
5
|
+
</div>
|
|
6
|
+
|
|
7
|
+
<h1 align="center">GPT-Vis</h1>
|
|
4
8
|
|
|
5
9
|
<div align="center">
|
|
6
|
-
<img src="https://github.com/eosphoros-ai/GPT-Vis/assets/17919400/c8804ffb-d3d6-45d3-846f-cf217681ab05" height="70">
|
|
7
10
|
|
|
8
|
-
面向 LLM 时代的 AI
|
|
11
|
+
面向 LLM 时代的 AI 原生可视化库,框架无关,开箱即用。
|
|
9
12
|
|
|
10
13
|
[](https://www.npmjs.com/package/@antv/gpt-vis)
|
|
11
14
|
[](https://www.npmjs.com/package/@antv/gpt-vis)
|
|
12
15
|
[](./LICENSE)
|
|
13
16
|
|
|
14
17
|
<p align="center">
|
|
15
|
-
<a href="https://gpt-vis.antv.vision" target="_blank">📖 文档</a>
|
|
16
|
-
<a href="/
|
|
17
|
-
<a href="/
|
|
18
|
-
<a href="
|
|
19
|
-
<a href="https://github.com/antvis/mcp-server-chart" target="_blank">🔌 MCP 服务器</a>
|
|
18
|
+
<a href="https://gpt-vis.antv.vision" target="_blank">📖 文档</a> ·
|
|
19
|
+
<a href="https://gpt-vis.antv.vision/examples" target="_blank">🎨 图表示例</a> ·
|
|
20
|
+
<a href="https://github.com/antvis/mcp-server-chart" target="_blank">🔌 MCP 服务</a> ·
|
|
21
|
+
<a href="/skills/chart-visualization" target="_blank">🧩 图表技能</a>
|
|
20
22
|
</p>
|
|
21
23
|
|
|
22
24
|
</div>
|
|
23
25
|
|
|
24
26
|
<div align="center">
|
|
25
|
-
<
|
|
27
|
+
<img src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*k21VQY6NgAwAAAAAWAAAAAgAemJ7AQ/fmt.avif" width="100%" />
|
|
26
28
|
</div>
|
|
27
29
|
|
|
28
30
|
<br/>
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
## ✨ 特性
|
|
31
33
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
-
|
|
38
|
-
- **📊 20+ 图表类型**: 统计图表、关系图表和高级可视化图表
|
|
39
|
-
- **🧠 智能默认值**: 自动数据检测、智能配色方案、自适应布局
|
|
34
|
+
- 🚀 **框架无关** — 原生 JavaScript、React、Vue、Angular,任何框架均可使用
|
|
35
|
+
- ✍️ **类 Markdown 语法** — LLM 可以直接生成的简洁语法,易学易用
|
|
36
|
+
- 🌊 **流式渲染** — 原生支持 AI 模型流式输出,边生成边渲染
|
|
37
|
+
- 🛡️ **高容错** — 优雅处理不完整、格式异常的数据,适配 AI 生成内容的不确定性
|
|
38
|
+
- 📊 **26 种图表** — 统计图表、关系图表、文本可视化,覆盖主流场景
|
|
39
|
+
- 🎨 **主题系统** — 内置亮色、暗色、学术三套主题,支持自定义配色
|
|
40
40
|
|
|
41
41
|
## 🚀 快速开始
|
|
42
42
|
|
|
@@ -57,7 +57,7 @@ const gptVis = new GPTVis({
|
|
|
57
57
|
height: 400,
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
-
//
|
|
60
|
+
// 类 Markdown 的可视化语法
|
|
61
61
|
const visSyntax = `
|
|
62
62
|
vis line
|
|
63
63
|
data
|
|
@@ -72,7 +72,11 @@ data
|
|
|
72
72
|
gptVis.render(visSyntax);
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
###
|
|
75
|
+
### 流式渲染
|
|
76
|
+
|
|
77
|
+
AI 模型边生成、图表边渲染,无需等待完整响应:
|
|
78
|
+
|
|
79
|
+
<img src="https://mdn.alipayobjects.com/huamei_qa8qxu/afts/img/A*_xY7Q6QyuZ4AAAAAWeAAAAgAemJ7AQ/original" width="100%" />
|
|
76
80
|
|
|
77
81
|
```javascript
|
|
78
82
|
import { GPTVis, isVisSyntax } from '@antv/gpt-vis';
|
|
@@ -90,18 +94,20 @@ function onToken(token) {
|
|
|
90
94
|
|
|
91
95
|
## 📚 语法指南
|
|
92
96
|
|
|
93
|
-
|
|
97
|
+
`render()` 支持两种输入格式:vis 语法(适合 LLM 流式生成)和 JSON 对象(适合程序化调用)。
|
|
98
|
+
|
|
99
|
+
### Vis 语法
|
|
100
|
+
|
|
101
|
+
类 Markdown 的声明式语法,LLM 无需学习复杂 API 即可生成:
|
|
94
102
|
|
|
95
103
|
```
|
|
96
104
|
vis [图表类型]
|
|
97
105
|
[属性] [值]
|
|
98
106
|
data
|
|
99
|
-
- [
|
|
107
|
+
- [字段] [值]
|
|
100
108
|
```
|
|
101
109
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
**简单图表:**
|
|
110
|
+
**饼图:**
|
|
105
111
|
|
|
106
112
|
```
|
|
107
113
|
vis pie
|
|
@@ -113,7 +119,29 @@ data
|
|
|
113
119
|
innerRadius 0.6
|
|
114
120
|
```
|
|
115
121
|
|
|
116
|
-
|
|
122
|
+
**主题:**
|
|
123
|
+
|
|
124
|
+
内置三套主题,通过 `theme` 属性切换:
|
|
125
|
+
|
|
126
|
+
| 主题 | 标识 | 背景色 | 色板 |
|
|
127
|
+
| ------------ | --------- | ------ | ----------------------------------------------------- |
|
|
128
|
+
| 默认(亮色) | `default` | `#FFF` | `#1783FF` `#F08F56` `#D580FF` `#00C9C9` `#7863FF` ... |
|
|
129
|
+
| 暗色 | `dark` | `#000` | `#1783FF` `#F08F56` `#D580FF` `#00C9C9` `#7863FF` ... |
|
|
130
|
+
| 学术 | `academy` | `#FFF` | `#4e79a7` `#f28e2c` `#e15759` `#76b7b2` `#59a14f` ... |
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
vis line
|
|
134
|
+
data
|
|
135
|
+
- time 2020
|
|
136
|
+
value 100
|
|
137
|
+
- time 2021
|
|
138
|
+
value 120
|
|
139
|
+
theme dark
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
**自定义样式:**
|
|
143
|
+
|
|
144
|
+
通过 `style` 设置线宽、自定义配色等:
|
|
117
145
|
|
|
118
146
|
```
|
|
119
147
|
vis line
|
|
@@ -129,17 +157,89 @@ style
|
|
|
129
157
|
- #5AD8A6
|
|
130
158
|
```
|
|
131
159
|
|
|
132
|
-
|
|
160
|
+
**包含空格的值用引号包裹:**
|
|
133
161
|
|
|
134
162
|
```
|
|
135
|
-
vis
|
|
163
|
+
vis pie
|
|
136
164
|
data
|
|
137
|
-
-
|
|
165
|
+
- category "Q1 销售额"
|
|
166
|
+
value 30
|
|
167
|
+
- category "Q2 销售额"
|
|
168
|
+
value 25
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
**层级数据:**
|
|
172
|
+
|
|
173
|
+
```
|
|
174
|
+
vis mindmap
|
|
175
|
+
data
|
|
176
|
+
- name 项目规划
|
|
138
177
|
children
|
|
139
|
-
- name
|
|
140
|
-
- name
|
|
178
|
+
- name 第一阶段
|
|
179
|
+
- name 第二阶段
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### JSON 对象
|
|
183
|
+
|
|
184
|
+
也支持直接传入 JSON 对象,适合程序化调用:
|
|
185
|
+
|
|
186
|
+
```javascript
|
|
187
|
+
gptVis.render({
|
|
188
|
+
type: 'pie',
|
|
189
|
+
data: [
|
|
190
|
+
{ category: 'Android', value: 72 },
|
|
191
|
+
{ category: 'iOS', value: 28 },
|
|
192
|
+
],
|
|
193
|
+
});
|
|
141
194
|
```
|
|
142
195
|
|
|
196
|
+
## 📊 图表类型
|
|
197
|
+
|
|
198
|
+
支持 26 种图表,覆盖统计分析、关系网络、文本可视化三大类。
|
|
199
|
+
|
|
200
|
+
### 统计图表(18 种)
|
|
201
|
+
|
|
202
|
+
| 图表 | 类型标识 |
|
|
203
|
+
| -------- | ------------ |
|
|
204
|
+
| 折线图 | `line` |
|
|
205
|
+
| 面积图 | `area` |
|
|
206
|
+
| 柱状图 | `column` |
|
|
207
|
+
| 条形图 | `bar` |
|
|
208
|
+
| 饼图 | `pie` |
|
|
209
|
+
| 散点图 | `scatter` |
|
|
210
|
+
| 雷达图 | `radar` |
|
|
211
|
+
| 漏斗图 | `funnel` |
|
|
212
|
+
| 瀑布图 | `waterfall` |
|
|
213
|
+
| 双轴图 | `dual-axes` |
|
|
214
|
+
| 直方图 | `histogram` |
|
|
215
|
+
| 箱线图 | `boxplot` |
|
|
216
|
+
| 小提琴图 | `violin` |
|
|
217
|
+
| 韦恩图 | `venn` |
|
|
218
|
+
| 桑基图 | `sankey` |
|
|
219
|
+
| 树图 | `treemap` |
|
|
220
|
+
| 词云 | `word-cloud` |
|
|
221
|
+
| 水波图 | `liquid` |
|
|
222
|
+
|
|
223
|
+
### 关系图表(6 种)
|
|
224
|
+
|
|
225
|
+
| 图表 | 类型标识 |
|
|
226
|
+
| ---------- | -------------------- |
|
|
227
|
+
| 流程图 | `flow-diagram` |
|
|
228
|
+
| 网络图 | `network-graph` |
|
|
229
|
+
| 思维导图 | `mindmap` |
|
|
230
|
+
| 缩进树 | `indented-tree` |
|
|
231
|
+
| 组织架构图 | `organization-chart` |
|
|
232
|
+
| 鱼骨图 | `fishbone-diagram` |
|
|
233
|
+
|
|
234
|
+
### 文本可视化(2 种)
|
|
235
|
+
|
|
236
|
+
| 图表 | 类型标识 |
|
|
237
|
+
| -------- | --------- |
|
|
238
|
+
| 表格 | `table` |
|
|
239
|
+
| 文本摘要 | `summary` |
|
|
240
|
+
|
|
241
|
+
查看全部示例 → [图表示例](https://gpt-vis.antv.vision/examples)
|
|
242
|
+
|
|
143
243
|
## 🔧 框架集成
|
|
144
244
|
|
|
145
245
|
<details>
|
|
@@ -191,25 +291,22 @@ function ChartComponent({ visSyntax }) {
|
|
|
191
291
|
</template>
|
|
192
292
|
|
|
193
293
|
<script setup>
|
|
194
|
-
import { ref,
|
|
294
|
+
import { ref, watch, onUnmounted } from 'vue';
|
|
195
295
|
import { GPTVis } from '@antv/gpt-vis';
|
|
196
296
|
|
|
197
297
|
const props = defineProps(['visSyntax']);
|
|
198
298
|
const chartRef = ref(null);
|
|
199
299
|
let gptVis = null;
|
|
200
300
|
|
|
201
|
-
onMounted(() => {
|
|
202
|
-
gptVis = new GPTVis({ container: chartRef.value, width: 600, height: 400 });
|
|
203
|
-
gptVis.render(props.visSyntax);
|
|
204
|
-
});
|
|
205
|
-
|
|
206
301
|
watch(
|
|
207
302
|
() => props.visSyntax,
|
|
208
|
-
(
|
|
209
|
-
if (gptVis) {
|
|
210
|
-
gptVis.
|
|
303
|
+
(syntax) => {
|
|
304
|
+
if (!gptVis) {
|
|
305
|
+
gptVis = new GPTVis({ container: chartRef.value, width: 600, height: 400 });
|
|
211
306
|
}
|
|
307
|
+
gptVis.render(syntax);
|
|
212
308
|
},
|
|
309
|
+
{ immediate: true },
|
|
213
310
|
);
|
|
214
311
|
|
|
215
312
|
onUnmounted(() => gptVis?.destroy());
|
|
@@ -218,18 +315,95 @@ onUnmounted(() => gptVis?.destroy());
|
|
|
218
315
|
|
|
219
316
|
</details>
|
|
220
317
|
|
|
221
|
-
|
|
318
|
+
<details>
|
|
319
|
+
<summary><strong>Markdown 渲染器(marked)</strong></summary>
|
|
222
320
|
|
|
223
|
-
GPT-Vis
|
|
321
|
+
GPT-Vis 的 vis 语法天然兼容 Markdown code fence,可以与任何 Markdown 渲染器集成。以下示例使用 `marked` + `marked-highlight`,普通代码块走语法高亮,`vis` 代码块自动渲染为交互式图表。
|
|
224
322
|
|
|
225
|
-
|
|
323
|
+
**安装依赖:**
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
npm install @antv/gpt-vis marked marked-highlight highlight.js
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
**完整示例:**
|
|
330
|
+
|
|
331
|
+
```javascript
|
|
332
|
+
import { Marked } from 'marked';
|
|
333
|
+
import { markedHighlight } from 'marked-highlight';
|
|
334
|
+
import hljs from 'highlight.js';
|
|
335
|
+
import { GPTVis } from '@antv/gpt-vis';
|
|
336
|
+
|
|
337
|
+
class GPTVisElement extends HTMLElement {
|
|
338
|
+
connectedCallback() {
|
|
339
|
+
const syntax = decodeURIComponent(this.dataset.syntax);
|
|
340
|
+
this._instance = new GPTVis({ container: this });
|
|
341
|
+
this._instance.render(syntax);
|
|
342
|
+
}
|
|
343
|
+
disconnectedCallback() {
|
|
344
|
+
this._instance?.destroy();
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
if (!customElements.get('gpt-vis')) {
|
|
348
|
+
customElements.define('gpt-vis', GPTVisElement);
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
const marked = new Marked(
|
|
352
|
+
markedHighlight({
|
|
353
|
+
langPrefix: 'hljs language-',
|
|
354
|
+
highlight(code, lang) {
|
|
355
|
+
if (lang?.startsWith('vis')) return code;
|
|
356
|
+
const language = hljs.getLanguage(lang) ? lang : 'plaintext';
|
|
357
|
+
return hljs.highlight(code, { language }).value;
|
|
358
|
+
},
|
|
359
|
+
}),
|
|
360
|
+
{
|
|
361
|
+
renderer: {
|
|
362
|
+
code({ text, lang }) {
|
|
363
|
+
if (lang?.startsWith('vis')) {
|
|
364
|
+
const syntax = encodeURIComponent(lang + '\n' + text);
|
|
365
|
+
return `<gpt-vis data-syntax="${syntax}" style="min-height:300px"></gpt-vis>`;
|
|
366
|
+
}
|
|
367
|
+
return false;
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
const markdown = `# My Report
|
|
374
|
+
|
|
375
|
+
\`\`\`vis bar
|
|
376
|
+
data
|
|
377
|
+
- category Python
|
|
378
|
+
value 28.1
|
|
379
|
+
- category JavaScript
|
|
380
|
+
value 18.5
|
|
381
|
+
- category Java
|
|
382
|
+
value 15.6
|
|
383
|
+
- category "C/C++"
|
|
384
|
+
value 12.3
|
|
385
|
+
title 2024 Programming Language Popularity
|
|
386
|
+
\`\`\`
|
|
387
|
+
`;
|
|
226
388
|
|
|
227
|
-
|
|
389
|
+
document.getElementById('content').innerHTML = marked.parse(markdown);
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
</details>
|
|
393
|
+
|
|
394
|
+
## 🤖 AI 生态
|
|
395
|
+
|
|
396
|
+
GPT-Vis 提供完整的 AI 集成方案:
|
|
397
|
+
|
|
398
|
+
- **[MCP 服务](https://github.com/antvis/mcp-server-chart)** — 通过 Model Context Protocol 让 AI 模型直接调用可视化能力
|
|
399
|
+
- **[图表技能](https://github.com/antvis/GPT-Vis/tree/main/skills/chart-visualization)** — 为 AI 助手提供图表推荐与生成能力,支持语法模式和代码模式两种输出
|
|
400
|
+
|
|
401
|
+
## 🤝 贡献
|
|
228
402
|
|
|
229
|
-
|
|
403
|
+
> **AI 生成代码策略**:本项目仅合并 AI 生成的代码。
|
|
230
404
|
|
|
231
|
-
1. 提交 Issue
|
|
232
|
-
2. 标记 @copilot
|
|
405
|
+
1. 提交 Issue 描述问题或需求
|
|
406
|
+
2. 标记 @copilot 生成实现方案
|
|
233
407
|
3. 提交包含 AI 生成代码的 PR
|
|
234
408
|
|
|
235
409
|
## 📄 开源协议
|
|
@@ -118,7 +118,7 @@ var _GPTVis = class {
|
|
|
118
118
|
this.wrapperInstance = (0, import_vis_wrapper.createVisWrapper)(this.options.container, {
|
|
119
119
|
chartType: type,
|
|
120
120
|
syntax: config,
|
|
121
|
-
locale: this.options.locale || "
|
|
121
|
+
locale: this.options.locale || "en-US"
|
|
122
122
|
});
|
|
123
123
|
} else {
|
|
124
124
|
this.wrapperInstance.update(config);
|
|
@@ -100,9 +100,17 @@ var FishboneDiagram = (options) => {
|
|
|
100
100
|
height,
|
|
101
101
|
autoFit: "view",
|
|
102
102
|
autoResize: true,
|
|
103
|
-
padding: 20,
|
|
104
|
-
theme:
|
|
105
|
-
plugins: title ? [
|
|
103
|
+
padding: title ? [46, 20, 20, 20] : 20,
|
|
104
|
+
theme: (0, import_theme.getTheme)(theme),
|
|
105
|
+
plugins: title ? [
|
|
106
|
+
{
|
|
107
|
+
key: "title",
|
|
108
|
+
type: "title",
|
|
109
|
+
title,
|
|
110
|
+
titleFill: isDark ? "#e0e6ed" : "#000",
|
|
111
|
+
titleFontFamily: "sans-serif"
|
|
112
|
+
}
|
|
113
|
+
] : [],
|
|
106
114
|
data: graphData,
|
|
107
115
|
node: {
|
|
108
116
|
type: "rect",
|
|
@@ -110,7 +118,7 @@ var FishboneDiagram = (options) => {
|
|
|
110
118
|
var _a;
|
|
111
119
|
const depth = d.depth ?? 0;
|
|
112
120
|
const nodeStyle = {
|
|
113
|
-
radius: 8,
|
|
121
|
+
radius: theme === "academy" ? 0 : 8,
|
|
114
122
|
size: getNodeSize(String(d.id), depth),
|
|
115
123
|
labelText: String(d.id),
|
|
116
124
|
labelPlacement: "left",
|
|
@@ -53,12 +53,13 @@ function ensureBehaviorRegistered() {
|
|
|
53
53
|
function escapeHtml(str = "") {
|
|
54
54
|
return str.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
55
55
|
}
|
|
56
|
-
function createNodeHTML(d, color, selectedBorderColor = "#000") {
|
|
56
|
+
function createNodeHTML(d, color, selectedBorderColor = "#000", theme = "default") {
|
|
57
57
|
var _a, _b, _c;
|
|
58
58
|
const text = escapeHtml(((_a = d.data) == null ? void 0 : _a.text) || "");
|
|
59
59
|
const isHovered = (_b = d.states) == null ? void 0 : _b.includes("active");
|
|
60
60
|
const isSelected = (_c = d.states) == null ? void 0 : _c.includes("selected");
|
|
61
61
|
const nodeColor = isHovered ? ACTIVE_COLOR : color;
|
|
62
|
+
const borderRadius = theme === "academy" ? "0px" : "8px";
|
|
62
63
|
return `
|
|
63
64
|
<div
|
|
64
65
|
data-node-key="${escapeHtml(String(d.id))}"
|
|
@@ -69,7 +70,7 @@ function createNodeHTML(d, color, selectedBorderColor = "#000") {
|
|
|
69
70
|
padding: 16px;
|
|
70
71
|
background: ${nodeColor};
|
|
71
72
|
border: 3px solid ${isSelected ? selectedBorderColor : nodeColor};
|
|
72
|
-
border-radius:
|
|
73
|
+
border-radius: ${borderRadius};
|
|
73
74
|
color: #fff;
|
|
74
75
|
font-size: 16px;
|
|
75
76
|
font-weight: 600;
|
|
@@ -90,7 +91,7 @@ function createNodeHTML(d, color, selectedBorderColor = "#000") {
|
|
|
90
91
|
</div>
|
|
91
92
|
`;
|
|
92
93
|
}
|
|
93
|
-
function measureAndUpdateNodeSizes(graph, container, nodeColorMap, selectedBorderColor) {
|
|
94
|
+
function measureAndUpdateNodeSizes(graph, container, nodeColorMap, selectedBorderColor, theme = "default") {
|
|
94
95
|
const nodes = graph.getNodeData();
|
|
95
96
|
const updatedNodes = nodes.map((node) => {
|
|
96
97
|
const dom = container.querySelector(`[data-node-key="${CSS.escape(String(node.id))}"]`);
|
|
@@ -107,7 +108,8 @@ function measureAndUpdateNodeSizes(graph, container, nodeColorMap, selectedBorde
|
|
|
107
108
|
innerHTML: createNodeHTML(
|
|
108
109
|
node,
|
|
109
110
|
nodeColorMap.get(String(node.id)) || "#1783FF",
|
|
110
|
-
selectedBorderColor
|
|
111
|
+
selectedBorderColor,
|
|
112
|
+
theme
|
|
111
113
|
)
|
|
112
114
|
}
|
|
113
115
|
};
|
|
@@ -187,21 +189,35 @@ var FlowDiagram = (options) => {
|
|
|
187
189
|
container: containerEl,
|
|
188
190
|
width,
|
|
189
191
|
height,
|
|
190
|
-
theme,
|
|
192
|
+
theme: (0, import_theme.getTheme)(theme),
|
|
191
193
|
data: { nodes: g6Nodes, edges: g6Edges },
|
|
192
194
|
autoFit: "view",
|
|
193
195
|
autoResize: true,
|
|
194
|
-
padding: 20,
|
|
195
|
-
plugins: title ? [
|
|
196
|
+
padding: title ? [46, 20, 20, 20] : 20,
|
|
197
|
+
plugins: title ? [
|
|
198
|
+
{
|
|
199
|
+
key: "title",
|
|
200
|
+
type: "title",
|
|
201
|
+
title,
|
|
202
|
+
titleFill: isDark ? "#e0e6ed" : "#000",
|
|
203
|
+
titleFontFamily: "sans-serif"
|
|
204
|
+
}
|
|
205
|
+
] : [],
|
|
196
206
|
node: {
|
|
197
207
|
type: "html",
|
|
198
208
|
style: (d) => {
|
|
209
|
+
var _a;
|
|
199
210
|
const color = nodeColorMap.get(String(d.id)) || colors[0];
|
|
211
|
+
const size = ((_a = d.style) == null ? void 0 : _a.size) || [
|
|
212
|
+
DEFAULT_NODE_WIDTH,
|
|
213
|
+
DEFAULT_NODE_HEIGHT
|
|
214
|
+
];
|
|
215
|
+
const height2 = size[1];
|
|
200
216
|
return {
|
|
201
|
-
size
|
|
217
|
+
size,
|
|
202
218
|
dx: -DEFAULT_NODE_WIDTH / 2,
|
|
203
|
-
dy: -
|
|
204
|
-
innerHTML: createNodeHTML(d, color, selectedBorder),
|
|
219
|
+
dy: -height2 / 2,
|
|
220
|
+
innerHTML: createNodeHTML(d, color, selectedBorder, theme),
|
|
205
221
|
ports: [{ placement: "top" }, { placement: "bottom" }]
|
|
206
222
|
};
|
|
207
223
|
},
|
|
@@ -248,7 +264,7 @@ var FlowDiagram = (options) => {
|
|
|
248
264
|
graph.render();
|
|
249
265
|
graph.once("afterrender", () => {
|
|
250
266
|
if (graph) {
|
|
251
|
-
measureAndUpdateNodeSizes(graph, containerEl, nodeColorMap, selectedBorder);
|
|
267
|
+
measureAndUpdateNodeSizes(graph, containerEl, nodeColorMap, selectedBorder, theme);
|
|
252
268
|
}
|
|
253
269
|
});
|
|
254
270
|
};
|
|
@@ -281,15 +281,17 @@ var IndentedTree = (options) => {
|
|
|
281
281
|
height,
|
|
282
282
|
autoFit: "view",
|
|
283
283
|
autoResize: true,
|
|
284
|
-
|
|
284
|
+
theme: (0, import_theme.getTheme)(theme),
|
|
285
|
+
padding: title ? [46, 20, 20, 20] : 20,
|
|
285
286
|
data: graphData,
|
|
286
287
|
node: {
|
|
287
288
|
type: GPT_VIS_INDENTED_NODE,
|
|
288
289
|
style: {
|
|
289
290
|
size: (d) => [measureTextWidth(String(d.id ?? ""), 12) + 6, NODE_HEIGHT],
|
|
290
291
|
labelBackground: (datum) => datum.id === rootId,
|
|
291
|
-
labelBackgroundRadius: 0,
|
|
292
|
+
labelBackgroundRadius: theme === "academy" ? 0 : 4,
|
|
292
293
|
labelBackgroundFill: palette[0] ?? "#1783FF",
|
|
294
|
+
labelPadding: (datum) => datum.id === rootId ? [2, 8] : 0,
|
|
293
295
|
labelFill: (datum) => datum.id === rootId ? "#fff" : isDark ? "#d0d0d0" : "#666",
|
|
294
296
|
labelText: (d) => {
|
|
295
297
|
var _a;
|
|
@@ -352,7 +354,15 @@ var IndentedTree = (options) => {
|
|
|
352
354
|
enable: (event) => event.targetType === "node" && event.target.id !== rootId
|
|
353
355
|
}
|
|
354
356
|
],
|
|
355
|
-
plugins: title ? [
|
|
357
|
+
plugins: title ? [
|
|
358
|
+
{
|
|
359
|
+
key: "title",
|
|
360
|
+
type: "title",
|
|
361
|
+
title,
|
|
362
|
+
titleFill: isDark ? "#e0e6ed" : "#000",
|
|
363
|
+
titleFontFamily: "sans-serif"
|
|
364
|
+
}
|
|
365
|
+
] : []
|
|
356
366
|
});
|
|
357
367
|
graph.render();
|
|
358
368
|
};
|
|
@@ -111,12 +111,20 @@ var Mindmap = (options) => {
|
|
|
111
111
|
height,
|
|
112
112
|
autoFit: "view",
|
|
113
113
|
autoResize: true,
|
|
114
|
-
padding: 20,
|
|
114
|
+
padding: title ? [46, 20, 20, 20] : 20,
|
|
115
115
|
zoomRange: [0.1, 5],
|
|
116
116
|
zoom: 1,
|
|
117
|
-
theme:
|
|
117
|
+
theme: (0, import_theme.getTheme)(theme),
|
|
118
118
|
data: graphData,
|
|
119
|
-
plugins: title ? [
|
|
119
|
+
plugins: title ? [
|
|
120
|
+
{
|
|
121
|
+
key: "title",
|
|
122
|
+
type: "title",
|
|
123
|
+
title,
|
|
124
|
+
titleFill: isDark ? "#e0e6ed" : "#000",
|
|
125
|
+
titleFontFamily: "sans-serif"
|
|
126
|
+
}
|
|
127
|
+
] : [],
|
|
120
128
|
node: {
|
|
121
129
|
type: "rect",
|
|
122
130
|
animation: { translate: false, update: false },
|
|
@@ -134,7 +142,7 @@ var Mindmap = (options) => {
|
|
|
134
142
|
const base = {
|
|
135
143
|
size: [nodeWidth, nodeHeight],
|
|
136
144
|
dx,
|
|
137
|
-
radius: 8,
|
|
145
|
+
radius: theme === "academy" ? 0 : 8,
|
|
138
146
|
labelText: label,
|
|
139
147
|
labelPlacement: "center",
|
|
140
148
|
labelFontSize: fontSize,
|
|
@@ -119,7 +119,8 @@ var NetworkGraph = (options) => {
|
|
|
119
119
|
height,
|
|
120
120
|
autoFit: "view",
|
|
121
121
|
autoResize: true,
|
|
122
|
-
|
|
122
|
+
theme: (0, import_theme.getTheme)(theme),
|
|
123
|
+
padding: title ? [46, 20, 20, 20] : 20,
|
|
123
124
|
data: {
|
|
124
125
|
nodes: nodeData,
|
|
125
126
|
edges: edgeData
|
|
@@ -132,7 +133,15 @@ var NetworkGraph = (options) => {
|
|
|
132
133
|
}
|
|
133
134
|
},
|
|
134
135
|
behaviors: ["drag-canvas", "drag-element", "click-select"],
|
|
135
|
-
plugins: title ? [
|
|
136
|
+
plugins: title ? [
|
|
137
|
+
{
|
|
138
|
+
key: "title",
|
|
139
|
+
type: "title",
|
|
140
|
+
title,
|
|
141
|
+
titleFill: isDark ? "#e0e6ed" : "#000",
|
|
142
|
+
titleFontFamily: "sans-serif"
|
|
143
|
+
}
|
|
144
|
+
] : []
|
|
136
145
|
});
|
|
137
146
|
graph.render();
|
|
138
147
|
};
|
|
@@ -83,7 +83,8 @@ var OrganizationChart = (options) => {
|
|
|
83
83
|
height,
|
|
84
84
|
autoFit: "view",
|
|
85
85
|
autoResize: true,
|
|
86
|
-
|
|
86
|
+
theme: (0, import_theme.getTheme)(theme),
|
|
87
|
+
padding: title ? [46, 20, 20, 20] : 20,
|
|
87
88
|
data: { nodes: nodeData, edges: edgeData },
|
|
88
89
|
plugins: [
|
|
89
90
|
{
|
|
@@ -119,7 +120,15 @@ var OrganizationChart = (options) => {
|
|
|
119
120
|
}
|
|
120
121
|
}
|
|
121
122
|
},
|
|
122
|
-
...title ? [
|
|
123
|
+
...title ? [
|
|
124
|
+
{
|
|
125
|
+
key: "title",
|
|
126
|
+
type: "title",
|
|
127
|
+
title,
|
|
128
|
+
titleFill: isDark ? "#e0e6ed" : "#000",
|
|
129
|
+
titleFontFamily: "sans-serif"
|
|
130
|
+
}
|
|
131
|
+
] : []
|
|
123
132
|
],
|
|
124
133
|
node: {
|
|
125
134
|
type: "rect",
|
|
@@ -132,7 +141,7 @@ var OrganizationChart = (options) => {
|
|
|
132
141
|
fill: (d) => colors[d.data.depth % colors.length],
|
|
133
142
|
stroke: isDark ? "#555" : "#e8ebf0",
|
|
134
143
|
lineWidth: 1,
|
|
135
|
-
radius: 8,
|
|
144
|
+
radius: theme === "academy" ? 0 : 8,
|
|
136
145
|
// Use official label wrapping/ellipsis for BOTH name & description.
|
|
137
146
|
// 1 line name + up to 2 lines description => total maxLines = 3.
|
|
138
147
|
labelText: (d) => d.data.description ? `${d.data.name}
|