diff --git a/.changeset/slow-spiders-raise.md b/.changeset/slow-spiders-raise.md
new file mode 100644
index 0000000..cc0d0f5
--- /dev/null
+++ b/.changeset/slow-spiders-raise.md
@@ -0,0 +1,5 @@
+---
+'@antv/gpt-vis': patch
+---
+
+feat: add fishbone diagram component
diff --git a/evaluations/datastes/chart/dual-axes/eval.json b/evaluations/datastes/chart/dual-axes/eval.json
index 01340a7..bdc4228 100644
--- a/evaluations/datastes/chart/dual-axes/eval.json
+++ b/evaluations/datastes/chart/dual-axes/eval.json
@@ -15,10 +15,7 @@
"question": "用双轴图来表示一个城市的年度平均气温和降水量。从2016到2020年,平均气温分别是15°C、16°C、17°C、18°C、19°C;同期的年降水量为800mm、850mm、900mm、950mm、1000mm。",
"response": "{\"type\":\"dual-axes\",\"categories\":[\"2016\",\"2017\",\"2018\",\"2019\",\"2020\"],\"title\":\"2016-2020年平均气温与降水量\",\"axisXTitle\":\"年份\",\"series\":[{\"type\":\"line\",\"data\":[15,16,17,18,19],\"axisYTitle\":\"平均气温(°C)\"},{\"type\":\"column\",\"data\":[800,850,900,950,1000],\"axisYTitle\":\"年降水量(mm)\"}]}",
"answer": "{\"type\":\"dual-axes\",\"categories\":[\"2016\",\"2017\",\"2018\",\"2019\",\"2020\"],\"title\":\"2016-2020年城市气候数据\",\"axisXTitle\":\"年份\",\"series\":[{\"type\":\"line\",\"data\":[15,16,17,18,19],\"axisYTitle\":\"平均气温 (°C)\"},{\"type\":\"column\",\"data\":[800,850,900,950,1000],\"axisYTitle\":\"降水量 (mm)\"}]}",
- "reference": [
- "[WIP]双轴图 - DualAxes Chart 基础概念",
- "热力地图 - HeatMap 使用示例"
- ]
+ "reference": ["[WIP]双轴图 - DualAxes Chart 基础概念", "热力地图 - HeatMap 使用示例"]
},
{
"type": "text2chart",
@@ -69,10 +66,7 @@
"question": "用双轴图展示过去三年的气温和降水量数据 [{ \"month\": \"Jan\", \"temperature\": 5, \"rainfall\": 50 }, { \"month\": \"Feb\", \"temperature\": 7, \"rainfall\": 60 }, { \"month\": \"Mar\", \"temperature\": 10, \"rainfall\": 80 }]",
"response": "{\"type\":\"dual-axes\",\"categories\":[\"Jan\",\"Feb\",\"Mar\"],\"title\":\"过去三年的气温和降水量\",\"axisXTitle\":\"月份\",\"series\":[{\"type\":\"line\",\"data\":[5,7,10],\"axisYTitle\":\"气温\"},{\"type\":\"column\",\"data\":[50,60,80],\"axisYTitle\":\"降水量\"}]}",
"answer": "{\"type\":\"dual-axes\",\"categories\":[\"Jan\",\"Feb\",\"Mar\"],\"title\":\"Monthly Temperature and Rainfall (Q1)\",\"axisXTitle\":\"Month\",\"series\":[{\"type\":\"line\",\"data\":[5,7,10],\"axisYTitle\":\"Temperature (°C)\"},{\"type\":\"column\",\"data\":[50,60,80],\"axisYTitle\":\"Rainfall (mm)\"}]}",
- "reference": [
- "[WIP]双轴图 - DualAxes Chart 基础概念",
- "热力地图 - HeatMap 使用示例"
- ]
+ "reference": ["[WIP]双轴图 - DualAxes Chart 基础概念", "热力地图 - HeatMap 使用示例"]
},
{
"type": "data2chart",
diff --git a/evaluations/datastes/chart/dual-axes/metrics.json b/evaluations/datastes/chart/dual-axes/metrics.json
index adf4a17..3765354 100644
--- a/evaluations/datastes/chart/dual-axes/metrics.json
+++ b/evaluations/datastes/chart/dual-axes/metrics.json
@@ -16,10 +16,7 @@
"question": "用双轴图来表示一个城市的年度平均气温和降水量。从2016到2020年,平均气温分别是15°C、16°C、17°C、18°C、19°C;同期的年降水量为800mm、850mm、900mm、950mm、1000mm。",
"response": "{\"type\":\"dual-axes\",\"categories\":[\"2016\",\"2017\",\"2018\",\"2019\",\"2020\"],\"title\":\"2016-2020年平均气温与降水量\",\"axisXTitle\":\"年份\",\"series\":[{\"type\":\"line\",\"data\":[15,16,17,18,19],\"axisYTitle\":\"平均气温(°C)\"},{\"type\":\"column\",\"data\":[800,850,900,950,1000],\"axisYTitle\":\"年降水量(mm)\"}]}",
"answer": "{\"type\":\"dual-axes\",\"categories\":[\"2016\",\"2017\",\"2018\",\"2019\",\"2020\"],\"title\":\"2016-2020年城市气候数据\",\"axisXTitle\":\"年份\",\"series\":[{\"type\":\"line\",\"data\":[15,16,17,18,19],\"axisYTitle\":\"平均气温 (°C)\"},{\"type\":\"column\",\"data\":[800,850,900,950,1000],\"axisYTitle\":\"降水量 (mm)\"}]}",
- "reference": [
- "[WIP]双轴图 - DualAxes Chart 基础概念",
- "热力地图 - HeatMap 使用示例"
- ],
+ "reference": ["[WIP]双轴图 - DualAxes Chart 基础概念", "热力地图 - HeatMap 使用示例"],
"correctness": 1
},
{
@@ -75,10 +72,7 @@
"question": "用双轴图展示过去三年的气温和降水量数据 [{ \"month\": \"Jan\", \"temperature\": 5, \"rainfall\": 50 }, { \"month\": \"Feb\", \"temperature\": 7, \"rainfall\": 60 }, { \"month\": \"Mar\", \"temperature\": 10, \"rainfall\": 80 }]",
"response": "{\"type\":\"dual-axes\",\"categories\":[\"Jan\",\"Feb\",\"Mar\"],\"title\":\"过去三年的气温和降水量\",\"axisXTitle\":\"月份\",\"series\":[{\"type\":\"line\",\"data\":[5,7,10],\"axisYTitle\":\"气温\"},{\"type\":\"column\",\"data\":[50,60,80],\"axisYTitle\":\"降水量\"}]}",
"answer": "{\"type\":\"dual-axes\",\"categories\":[\"Jan\",\"Feb\",\"Mar\"],\"title\":\"Monthly Temperature and Rainfall (Q1)\",\"axisXTitle\":\"Month\",\"series\":[{\"type\":\"line\",\"data\":[5,7,10],\"axisYTitle\":\"Temperature (°C)\"},{\"type\":\"column\",\"data\":[50,60,80],\"axisYTitle\":\"Rainfall (mm)\"}]}",
- "reference": [
- "[WIP]双轴图 - DualAxes Chart 基础概念",
- "热力地图 - HeatMap 使用示例"
- ],
+ "reference": ["[WIP]双轴图 - DualAxes Chart 基础概念", "热力地图 - HeatMap 使用示例"],
"correctness": 1
},
{
diff --git a/evaluations/datastes/chart/dual-axes/test.json b/evaluations/datastes/chart/dual-axes/test.json
index d12e61e..584fb06 100644
--- a/evaluations/datastes/chart/dual-axes/test.json
+++ b/evaluations/datastes/chart/dual-axes/test.json
@@ -348,22 +348,20 @@
{
"type": "line",
"data": [
- 100, 102, 101, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112,
- 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125,
- 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138,
- 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149
+ 100, 102, 101, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116,
+ 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133,
+ 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149
],
"axisYTitle": "Stock Price"
},
{
"type": "column",
"data": [
- 10000, 12000, 11000, 13000, 14000, 15000, 16000, 17000, 18000,
- 19000, 20000, 21000, 22000, 23000, 24000, 25000, 26000, 27000,
- 28000, 29000, 30000, 31000, 32000, 33000, 34000, 35000, 36000,
- 37000, 38000, 39000, 40000, 41000, 42000, 43000, 44000, 45000,
- 46000, 47000, 48000, 49000, 50000, 51000, 52000, 53000, 54000,
- 55000, 56000, 57000, 58000, 59000
+ 10000, 12000, 11000, 13000, 14000, 15000, 16000, 17000, 18000, 19000, 20000, 21000,
+ 22000, 23000, 24000, 25000, 26000, 27000, 28000, 29000, 30000, 31000, 32000, 33000,
+ 34000, 35000, 36000, 37000, 38000, 39000, 40000, 41000, 42000, 43000, 44000, 45000,
+ 46000, 47000, 48000, 49000, 50000, 51000, 52000, 53000, 54000, 55000, 56000, 57000,
+ 58000, 59000
],
"axisYTitle": "Trading Volume"
}
diff --git a/evaluations/prompts/dual-axes-chart/data2chart.md b/evaluations/prompts/dual-axes-chart/data2chart.md
index b363c04..6ff1d89 100644
--- a/evaluations/prompts/dual-axes-chart/data2chart.md
+++ b/evaluations/prompts/dual-axes-chart/data2chart.md
@@ -1,4 +1,3 @@
-
## 角色
你是一个 mock 图表数据生成器,生成[WIP]双轴图相关的可视化问答对数据。
@@ -12,37 +11,67 @@
## [WIP]双轴图图表知识库
### 图表属性
+
```typescript
type DualAxes = {
- type: "dual-axes";
+ type: 'dual-axes';
categories: string[];
title?: string;
axisXTitle?: string;
series: seriesDataItem[];
-}
+};
type seriesDataItem = {
- type: "line" | "column";
+ type: 'line' | 'column';
data: number[];
axisYTitle?: string;
-}
-
+};
```
### 数据要求
-+ type:图表的类型,必填,文本类型,值必须为 "dual-axes"
-+ categories:图表的X轴的数组,必填,数组文本类型
-+ title:图表的标题,选填,文本类型
-+ axisXTitle:图表的X轴的标题,选填,文本类型
-+ series:图表详细组合,必填,数组对象类型,每个对象代表一个基础图表,包含:
- - type:基础图表的类型,必填,"column"表示柱状图,"line"表示折线图
- - data:基础图表的数据,必填,数组数值类型
- - axisYTitle:基础图表的Y轴标题,选填,文本类型
+
+- type:图表的类型,必填,文本类型,值必须为 "dual-axes"
+- categories:图表的X轴的数组,必填,数组文本类型
+- title:图表的标题,选填,文本类型
+- axisXTitle:图表的X轴的标题,选填,文本类型
+- series:图表详细组合,必填,数组对象类型,每个对象代表一个基础图表,包含:
+ - type:基础图表的类型,必填,"column"表示柱状图,"line"表示折线图
+ - data:基础图表的数据,必填,数组数值类型
+ - axisYTitle:基础图表的Y轴标题,选填,文本类型
## 参考例子
```json
-[{"type":"data2chart","question":"用双轴图可视化我的数据 [{ \"year\": 2020, \"revenue\": 500, \"growth_rate\": 10 }, { \"year\": 2021, \"revenue\": 600, \"growth_rate\": 12 }, { \"year\": 2022, \"revenue\": 700, \"growth_rate\": 15 }]","answer":{"type":"dual-axes","categories":["2020","2021","2022"],"title":"2020-2022 Income and Growth Rate","axisXTitle":"Year","series":[{"type":"column","data":[500,600,700],"axisYTitle":"Income"},{"type":"line","data":[10,12,15],"axisYTitle":"Growth Rate"}]}},{"type":"data2chart","question":"用组合图可视化我的数据 [{ \"day\": \"20240501\", \"cnt\": 1000, \"growth_rate\": 10 }, { \"day\": \"20240502\", \"cnt\": 1200, \"growth_rate\": 12 }, { \"day\": \"20240503\", \"cnt\": 1500, \"growth_rate\": 16 }]","answer":{"type":"dual-axes","categories":["20240501","20240502","20240503"],"title":"五一期间景区人流量","axisXTitle":"日期","series":[{"type":"column","data":[1000,1200,1500],"axisYTitle":"人数"},{"type":"line","data":[10,12,16],"axisYTitle":"增长率"}]}}]
+[
+ {
+ "type": "data2chart",
+ "question": "用双轴图可视化我的数据 [{ \"year\": 2020, \"revenue\": 500, \"growth_rate\": 10 }, { \"year\": 2021, \"revenue\": 600, \"growth_rate\": 12 }, { \"year\": 2022, \"revenue\": 700, \"growth_rate\": 15 }]",
+ "answer": {
+ "type": "dual-axes",
+ "categories": ["2020", "2021", "2022"],
+ "title": "2020-2022 Income and Growth Rate",
+ "axisXTitle": "Year",
+ "series": [
+ { "type": "column", "data": [500, 600, 700], "axisYTitle": "Income" },
+ { "type": "line", "data": [10, 12, 15], "axisYTitle": "Growth Rate" }
+ ]
+ }
+ },
+ {
+ "type": "data2chart",
+ "question": "用组合图可视化我的数据 [{ \"day\": \"20240501\", \"cnt\": 1000, \"growth_rate\": 10 }, { \"day\": \"20240502\", \"cnt\": 1200, \"growth_rate\": 12 }, { \"day\": \"20240503\", \"cnt\": 1500, \"growth_rate\": 16 }]",
+ "answer": {
+ "type": "dual-axes",
+ "categories": ["20240501", "20240502", "20240503"],
+ "title": "五一期间景区人流量",
+ "axisXTitle": "日期",
+ "series": [
+ { "type": "column", "data": [1000, 1200, 1500], "axisYTitle": "人数" },
+ { "type": "line", "data": [10, 12, 16], "axisYTitle": "增长率" }
+ ]
+ }
+ }
+]
```
## 要求
diff --git a/evaluations/prompts/dual-axes-chart/text2chart.md b/evaluations/prompts/dual-axes-chart/text2chart.md
index 98a218f..d5c03a4 100644
--- a/evaluations/prompts/dual-axes-chart/text2chart.md
+++ b/evaluations/prompts/dual-axes-chart/text2chart.md
@@ -1,4 +1,3 @@
-
## 角色
你是一个 mock 图表数据生成器,生成[WIP]双轴图相关的可视化问答对数据。
@@ -12,37 +11,53 @@
## [WIP]双轴图图表知识库
### 图表属性
+
```typescript
type DualAxes = {
- type: "dual-axes";
+ type: 'dual-axes';
categories: string[];
title?: string;
axisXTitle?: string;
series: seriesDataItem[];
-}
+};
type seriesDataItem = {
- type: "line" | "column";
+ type: 'line' | 'column';
data: number[];
axisYTitle?: string;
-}
-
+};
```
### 数据要求
-+ type:图表的类型,必填,文本类型,值必须为 "dual-axes"
-+ categories:图表的X轴的数组,必填,数组文本类型
-+ title:图表的标题,选填,文本类型
-+ axisXTitle:图表的X轴的标题,选填,文本类型
-+ series:图表详细组合,必填,数组对象类型,每个对象代表一个基础图表,包含:
- - type:基础图表的类型,必填,"column"表示柱状图,"line"表示折线图
- - data:基础图表的数据,必填,数组数值类型
- - axisYTitle:基础图表的Y轴标题,选填,文本类型
+
+- type:图表的类型,必填,文本类型,值必须为 "dual-axes"
+- categories:图表的X轴的数组,必填,数组文本类型
+- title:图表的标题,选填,文本类型
+- axisXTitle:图表的X轴的标题,选填,文本类型
+- series:图表详细组合,必填,数组对象类型,每个对象代表一个基础图表,包含:
+ - type:基础图表的类型,必填,"column"表示柱状图,"line"表示折线图
+ - data:基础图表的数据,必填,数组数值类型
+ - axisYTitle:基础图表的Y轴标题,选填,文本类型
## 参考例子
```json
-[{"type":"text2chart","question":"用双轴图展示某公司的年销售额与利润率,2018 年至 2022 年的销售额分别为 91.9 亿、99.1 亿、101.6 亿、114.4 亿、121 亿,利润率分别为 5.5%、6.0%、6.2%、7.0%、7.5%。","answer":{"type":"dual-axes","categories":["2018","2019","2020","2021","2022"],"title":"2018-2022销售额与利润率","axisXTitle":"年份","series":[{"type":"column","data":[91.9,99.1,101.6,114.4,121],"axisYTitle":"销售额"},{"type":"line","data":[0.055,0.06,0.062,0.07,0.075],"axisYTitle":"利润率"}]}}]
+[
+ {
+ "type": "text2chart",
+ "question": "用双轴图展示某公司的年销售额与利润率,2018 年至 2022 年的销售额分别为 91.9 亿、99.1 亿、101.6 亿、114.4 亿、121 亿,利润率分别为 5.5%、6.0%、6.2%、7.0%、7.5%。",
+ "answer": {
+ "type": "dual-axes",
+ "categories": ["2018", "2019", "2020", "2021", "2022"],
+ "title": "2018-2022销售额与利润率",
+ "axisXTitle": "年份",
+ "series": [
+ { "type": "column", "data": [91.9, 99.1, 101.6, 114.4, 121], "axisYTitle": "销售额" },
+ { "type": "line", "data": [0.055, 0.06, 0.062, 0.07, 0.075], "axisYTitle": "利润率" }
+ ]
+ }
+ }
+]
```
## 要求
diff --git a/package.json b/package.json
index 7b3f252..e32c8a4 100644
--- a/package.json
+++ b/package.json
@@ -49,7 +49,7 @@
"publish-package": "pnpm build && changeset publish"
},
"dependencies": {
- "@ant-design/graphs": "^2.0.0-beta.4",
+ "@ant-design/graphs": "^2.0.1",
"@ant-design/icons": "^5.4.0",
"@ant-design/plots": "^2.2.5",
"@ant-design/x": "^1.0.0-alpha.12",
diff --git a/src/FishboneDiagram/demos/common.tsx b/src/FishboneDiagram/demos/common.tsx
new file mode 100644
index 0000000..d7d6edf
--- /dev/null
+++ b/src/FishboneDiagram/demos/common.tsx
@@ -0,0 +1,64 @@
+import { FishboneDiagram } from '@antv/gpt-vis';
+import React from 'react';
+
+const data = {
+ name: '产品盈利未达到预期目标',
+ children: [
+ {
+ name: '问题描述与分析',
+ children: [
+ { name: '品牌销量分析' },
+ { name: '市场容量评估' },
+ { name: '品牌的市场份额分析' },
+ { name: '总贡献毛利计算' },
+ ],
+ },
+ {
+ name: '品牌定位策略',
+ children: [
+ { name: '外包装设计' },
+ { name: '品牌名称选择' },
+ { name: '销售价格定位' },
+ { name: '产品规格定义' },
+ ],
+ },
+ {
+ name: '分销渠道管理',
+ children: [
+ { name: '地区分布' },
+ { name: '渠道选择' },
+ { name: '客户类型分类' },
+ { name: '销售人员覆盖范围' },
+ ],
+ },
+ {
+ name: '市场知名度提升',
+ children: [
+ { name: '地区权重分析' },
+ { name: '媒体组合策略' },
+ { name: '广告投入预算' },
+ { name: '品质意识提升' },
+ ],
+ },
+ {
+ name: '试购买策略',
+ children: [
+ { name: '现场展示效果' },
+ { name: '促销形式设计' },
+ { name: '促销时机选择' },
+ { name: '供货保证措施' },
+ ],
+ },
+ {
+ name: '重复购买策略',
+ children: [
+ { name: '消费者档案管理' },
+ { name: '使用场合分析' },
+ { name: '使用次数统计' },
+ { name: '产品原因退货处理' },
+ ],
+ },
+ ],
+};
+
+export default () =>
+
+### 使用 Markdown 协议
+
+
+
+## Spec
+
+```json
+{
+ "type": "fishbone-diagram",
+ "data": {
+ "name": "problem",
+ "children": [
+ {
+ "name": "bone 1",
+ "children": [{ "name": "factor 1-1" }, { "name": "factor 1-2" }]
+ },
+ {
+ "name": "bone 2",
+ "children": [{ "name": "factor 2-1" }, { "name": "factor 2-2" }]
+ }
+ ]
+ }
+}
+```
+
+## API
+
+### FishboneProps
+
+| 属性 | 类型 | 是否必传 | 默认值 | 说明 |
+| ---- | -------------- | -------- | ------ | ---- |
+| data | `FishboneData` | 是 | - | 数据 |
+
+### FishboneData
+
+| 属性 | 类型 | 是否必传 | 默认值 | 说明 |
+| -------- | ---------------- | -------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| name | `string` | 是 | - | 节点的名称,用于显示在思维导图的节点上 |
+| children | `FishboneData[]` | 否 | - | 当前节点的子节点集合。如果当前节点没有子节点,该字段可以省略。每个子节点本身也是一个 `FishboneData` 对象,这意味着它可以包含自己的子节点,从而递归地构建出一个多层次的树状结构 |
diff --git a/src/FishboneDiagram/index.tsx b/src/FishboneDiagram/index.tsx
new file mode 100644
index 0000000..c83509b
--- /dev/null
+++ b/src/FishboneDiagram/index.tsx
@@ -0,0 +1,25 @@
+import type { FishboneOptions } from '@ant-design/graphs';
+import { Fishbone as ADCFishbone } from '@ant-design/graphs';
+import React, { useMemo } from 'react';
+import { useGraphConfig } from '../ConfigProvider/hooks';
+import type { TreeGraphProps } from '../types';
+import { visTreeData2GraphData } from '../utils/graph';
+
+export interface FishboneDiagramProps extends TreeGraphProps {}
+
+const defaultConfig: FishboneOptions = {
+ autoFit: 'view',
+ autoResize: true,
+};
+
+const FishboneDiagram: React.FC