From d259eda6b41532fb0be47d0b4ce2d4c04c899be3 Mon Sep 17 00:00:00 2001
From: silencezhang7 <765596994@qq.com>
Date: Fri, 27 Sep 2024 13:50:42 +0800
Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9EBI=E5=9C=96=E6=A8=99=E5=8A=9F?=
=?UTF-8?q?=E8=83=BD-=E6=9F=B1=E7=8B=80=E5=9C=96=20(#2779)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* 新增BI圖標功能-柱狀圖
* 新增BI图表功能-柱狀圖,优化代码,删除无用代码
* 优化生成逻辑,支持插件手动选择图表类型:目前支持柱状图,折线图,饼图
* 修改包名称,完成基础图表
---
packages/plugins/package.json | 4 +-
packages/plugins/register.ts | 4 +-
.../plugins/src/drawing/baseChart/index.ts | 93 +++
.../src/drawing/baseChart/template.json | 551 ++++++++++++++++++
packages/plugins/src/drawing/template.json | 17 +
.../web/components/common/Icon/constants.ts | 2 +
.../Icon/icons/core/workflow/template/BI.svg | 1 +
.../core/workflow/template/baseChart.svg | 1 +
8 files changed, 671 insertions(+), 2 deletions(-)
create mode 100644 packages/plugins/src/drawing/baseChart/index.ts
create mode 100644 packages/plugins/src/drawing/baseChart/template.json
create mode 100644 packages/plugins/src/drawing/template.json
create mode 100644 packages/web/components/common/Icon/icons/core/workflow/template/BI.svg
create mode 100644 packages/web/components/common/Icon/icons/core/workflow/template/baseChart.svg
diff --git a/packages/plugins/package.json b/packages/plugins/package.json
index 8611adefd..d9c824490 100644
--- a/packages/plugins/package.json
+++ b/packages/plugins/package.json
@@ -1,11 +1,13 @@
{
"name": "@fastgpt/plugins",
"version": "1.0.0",
+ "type": "module",
"dependencies": {
"duck-duck-scrape": "^2.2.5",
"lodash": "^4.17.21",
"axios": "^1.5.1",
- "expr-eval": "^2.0.2"
+ "expr-eval": "^2.0.2",
+ "echarts": "5.4.1"
},
"devDependencies": {
"@fastgpt/global": "workspace:*",
diff --git a/packages/plugins/register.ts b/packages/plugins/register.ts
index 91ba768ea..91ba92f12 100644
--- a/packages/plugins/register.ts
+++ b/packages/plugins/register.ts
@@ -22,7 +22,9 @@ const packagePluginList = [
'duckduckgo/search',
'duckduckgo/searchImg',
'duckduckgo/searchNews',
- 'duckduckgo/searchVideo'
+ 'duckduckgo/searchVideo',
+ 'drawing',
+ 'drawing/baseChart'
];
export const list = [...staticPluginList, ...packagePluginList];
diff --git a/packages/plugins/src/drawing/baseChart/index.ts b/packages/plugins/src/drawing/baseChart/index.ts
new file mode 100644
index 000000000..f5f71cc16
--- /dev/null
+++ b/packages/plugins/src/drawing/baseChart/index.ts
@@ -0,0 +1,93 @@
+import * as echarts from 'echarts';
+
+type Props = {
+ title: string;
+ xAxis: string;
+ yAxis: string;
+ chartType: string;
+};
+
+type Response = Promise<{
+ result: string;
+}>;
+
+type SeriesData = {
+ name: string;
+ type: 'bar' | 'line' | 'pie'; // 只允许这三种类型
+ data: number[] | { value: number; name: string }[]; // 根据图表类型的数据结构
+};
+type Option = {
+ backgroundColor: string;
+ title: { text: string };
+ tooltip: {};
+ xAxis: { data: string[] };
+ yAxis: {};
+ series: SeriesData[]; // 使用定义的类型
+};
+
+const generateChart = (title: string, xAxis: string, yAxis: string, chartType: string) => {
+ // @ts-ignore 无法使用dom,如使用jsdom会出现生成图片无法正常展示,有高手可以帮忙解决
+ const chart = echarts.init(undefined, undefined, {
+ renderer: 'svg', // 必须使用 SVG 模式
+ ssr: true, // 开启 SSR
+ width: 400, // 需要指明高和宽
+ height: 300
+ });
+
+ let parsedXAxis: string[] = [];
+ let parsedYAxis: number[] = [];
+ try {
+ parsedXAxis = JSON.parse(xAxis);
+ parsedYAxis = JSON.parse(yAxis);
+ } catch (error: unknown) {
+ console.error('解析数据时出错:', error);
+ }
+
+ const option: Option = {
+ backgroundColor: '#f5f5f5',
+ title: { text: title },
+ tooltip: {},
+ xAxis: { data: parsedXAxis },
+ yAxis: {},
+ series: [] // 初始化为空数组
+ };
+
+ // 根据 chartType 生成不同的图表
+ switch (chartType) {
+ case '柱状图':
+ option.series.push({ name: 'Sample', type: 'bar', data: parsedYAxis });
+ break;
+ case '折线图':
+ option.series.push({ name: 'Sample', type: 'line', data: parsedYAxis });
+ break;
+ case '饼图':
+ option.series.push({
+ name: 'Sample',
+ type: 'pie',
+ data: parsedYAxis.map((value, index) => ({
+ value,
+ name: parsedXAxis[index] // 使用 xAxis 作为饼图的名称
+ }))
+ });
+ break;
+ default:
+ console.error('不支持的图表类型:', chartType);
+ return '';
+ }
+
+ chart.setOption(option);
+ // 生成 Base64 图像
+ const base64Image = chart.getDataURL({ type: 'png' });
+ // 释放图表实例
+ chart.dispose();
+
+ return base64Image;
+};
+
+const main = async ({ title, xAxis, yAxis, chartType }: Props): Response => {
+ return {
+ result: generateChart(title, xAxis, yAxis, chartType)
+ };
+};
+
+export default main;
diff --git a/packages/plugins/src/drawing/baseChart/template.json b/packages/plugins/src/drawing/baseChart/template.json
new file mode 100644
index 000000000..8157a28ff
--- /dev/null
+++ b/packages/plugins/src/drawing/baseChart/template.json
@@ -0,0 +1,551 @@
+{
+ "author": "",
+ "version": "486",
+ "name": "基础图表",
+ "avatar": "core/workflow/template/baseChart",
+ "intro": "根据数据生成图表,可根据chartType生成柱状图,折线图,饼图",
+ "showStatus": true,
+ "weight": 10,
+
+ "isTool": true,
+ "templateType": "search",
+
+ "workflow": {
+ "nodes": [
+ {
+ "nodeId": "pluginInput",
+ "name": "common:core.module.template.self_input",
+ "intro": "workflow:intro_plugin_input",
+ "avatar": "core/workflow/template/workflowStart",
+ "flowNodeType": "pluginInput",
+ "showStatus": false,
+ "position": {
+ "x": 613.7921798611637,
+ "y": -124.66724109717275
+ },
+ "version": "481",
+ "inputs": [
+ {
+ "renderTypeList": [
+ "reference"
+ ],
+ "selectedTypeIndex": 0,
+ "valueType": "string",
+ "canEdit": true,
+ "key": "title",
+ "label": "title",
+ "description": "BI图表的标题",
+ "defaultValue": "",
+ "list": [
+ {
+ "label": "",
+ "value": ""
+ }
+ ],
+ "required": true,
+ "toolDescription": "BI图表的标题"
+ },
+ {
+ "renderTypeList": [
+ "reference"
+ ],
+ "selectedTypeIndex": 0,
+ "valueType": "string",
+ "canEdit": true,
+ "key": "xAxis",
+ "label": "xAxis",
+ "description": "x轴数据",
+ "defaultValue": "",
+ "required": true,
+ "toolDescription": "x轴数据",
+ "list": [
+ {
+ "label": "",
+ "value": ""
+ }
+ ]
+ },
+ {
+ "renderTypeList": [
+ "reference"
+ ],
+ "selectedTypeIndex": 0,
+ "valueType": "string",
+ "canEdit": true,
+ "key": "yAxis",
+ "label": "yAxis",
+ "description": "y轴数据",
+ "defaultValue": "",
+ "list": [
+ {
+ "label": "",
+ "value": ""
+ }
+ ],
+ "required": true,
+ "toolDescription": "y轴数据"
+ },
+ {
+ "renderTypeList": [
+ "select"
+ ],
+ "selectedTypeIndex": 0,
+ "valueType": "string",
+ "canEdit": true,
+ "key": "chartType",
+ "label": "chartType",
+ "description": "图表类型,如柱状图,折线图,饼图",
+ "defaultValue": "",
+ "required": true,
+ "list": [
+ {
+ "label": "柱状图",
+ "value": "柱状图"
+ },
+ {
+ "label": "折线图",
+ "value": "折线图"
+ },
+ {
+ "label": "饼图",
+ "value": "饼图"
+ }
+ ],
+ "toolDescription": "图表类型,如柱状图,折线图,饼图"
+ }
+ ],
+ "outputs": [
+ {
+ "id": "title",
+ "valueType": "string",
+ "key": "title",
+ "label": "title",
+ "type": "hidden"
+ },
+ {
+ "id": "xAxis",
+ "valueType": "string",
+ "key": "xAxis",
+ "label": "xAxis",
+ "type": "hidden"
+ },
+ {
+ "id": "yAxis",
+ "valueType": "string",
+ "key": "yAxis",
+ "label": "yAxis",
+ "type": "hidden"
+ },
+ {
+ "id": "chartType",
+ "valueType": "string",
+ "key": "chartType",
+ "label": "chartType",
+ "type": "hidden"
+ }
+ ]
+ },
+ {
+ "nodeId": "pluginOutput",
+ "name": "common:core.module.template.self_output",
+ "intro": "workflow:intro_custom_plugin_output",
+ "avatar": "core/workflow/template/pluginOutput",
+ "flowNodeType": "pluginOutput",
+ "showStatus": false,
+ "position": {
+ "x": 2122.252754006148,
+ "y": -63.5218674613718
+ },
+ "version": "481",
+ "inputs": [
+ {
+ "renderTypeList": [
+ "reference"
+ ],
+ "valueType": "string",
+ "canEdit": true,
+ "key": "图片base64数据",
+ "label": "图片base64数据",
+ "description": "可用使用markdown格式展示图片,如:",
+ "value": [
+ "ws0DFKJnCPhk",
+ "bzaYjKyQFOw2"
+ ]
+ }
+ ],
+ "outputs": []
+ },
+ {
+ "nodeId": "ws0DFKJnCPhk",
+ "name": "HTTP 请求",
+ "intro": "可以发出一个 HTTP 请求,实现更为复杂的操作(联网搜索、数据库查询等)",
+ "avatar": "core/workflow/template/httpRequest",
+ "flowNodeType": "httpRequest468",
+ "showStatus": true,
+ "position": {
+ "x": 1216.5166647574395,
+ "y": -206.30162946606856
+ },
+ "version": "481",
+ "inputs": [
+ {
+ "key": "system_addInputParam",
+ "renderTypeList": [
+ "addInputParam"
+ ],
+ "valueType": "dynamic",
+ "label": "",
+ "required": false,
+ "description": "接收前方节点的输出值作为变量,这些变量可以被 HTTP 请求参数使用。",
+ "customInputConfig": {
+ "selectValueTypeList": [
+ "string",
+ "number",
+ "boolean",
+ "object",
+ "arrayString",
+ "arrayNumber",
+ "arrayBoolean",
+ "arrayObject",
+ "any",
+ "chatHistory",
+ "datasetQuote",
+ "dynamic",
+ "selectApp",
+ "selectDataset"
+ ],
+ "showDescription": false,
+ "showDefaultValue": true
+ },
+ "valueDesc": "",
+ "debugLabel": "",
+ "toolDescription": ""
+ },
+ {
+ "key": "system_httpMethod",
+ "renderTypeList": [
+ "custom"
+ ],
+ "valueType": "string",
+ "label": "",
+ "value": "POST",
+ "required": true,
+ "valueDesc": "",
+ "description": "",
+ "debugLabel": "",
+ "toolDescription": ""
+ },
+ {
+ "key": "system_httpTimeout",
+ "renderTypeList": [
+ "custom"
+ ],
+ "valueType": "number",
+ "label": "",
+ "value": 30,
+ "min": 5,
+ "max": 600,
+ "required": true,
+ "valueDesc": "",
+ "description": "",
+ "debugLabel": "",
+ "toolDescription": ""
+ },
+ {
+ "key": "system_httpReqUrl",
+ "renderTypeList": [
+ "hidden"
+ ],
+ "valueType": "string",
+ "label": "",
+ "description": "新的 HTTP 请求地址。如果出现两个“请求地址”,可以删除该模块重新加入,会拉取最新的模块配置。",
+ "placeholder": "https://api.ai.com/getInventory",
+ "required": false,
+ "valueDesc": "",
+ "debugLabel": "",
+ "toolDescription": "",
+ "value": "drawing/baseChart"
+ },
+ {
+ "key": "system_httpHeader",
+ "renderTypeList": [
+ "custom"
+ ],
+ "valueType": "any",
+ "value": [],
+ "label": "",
+ "description": "自定义请求头,请严格填入 JSON 字符串。\n1. 确保最后一个属性没有逗号\n2. 确保 key 包含双引号\n例如:{\"Authorization\":\"Bearer xxx\"}",
+ "placeholder": "common:core.module.input.description.Http Request Header",
+ "required": false,
+ "valueDesc": "",
+ "debugLabel": "",
+ "toolDescription": ""
+ },
+ {
+ "key": "system_httpParams",
+ "renderTypeList": [
+ "hidden"
+ ],
+ "valueType": "any",
+ "value": [],
+ "label": "",
+ "required": false,
+ "valueDesc": "",
+ "description": "",
+ "debugLabel": "",
+ "toolDescription": ""
+ },
+ {
+ "key": "system_httpJsonBody",
+ "renderTypeList": [
+ "hidden"
+ ],
+ "valueType": "any",
+ "value": "{\r\n \"title\": \"{{title-plugin}}\",\r\n \"xAxis\": \"{{xAxis-plugin}}\",\r\n \"yAxis\": \"{{yAxis-plugin}}\",\r\n \"chartType\": \"{{chartType-plugin}}\"\r\n}",
+ "label": "",
+ "required": false,
+ "valueDesc": "",
+ "description": "",
+ "debugLabel": "",
+ "toolDescription": ""
+ },
+ {
+ "key": "system_httpFormBody",
+ "renderTypeList": [
+ "hidden"
+ ],
+ "valueType": "any",
+ "value": [],
+ "label": "",
+ "required": false,
+ "valueDesc": "",
+ "description": "",
+ "debugLabel": "",
+ "toolDescription": ""
+ },
+ {
+ "key": "system_httpContentType",
+ "renderTypeList": [
+ "hidden"
+ ],
+ "valueType": "string",
+ "value": "json",
+ "label": "",
+ "required": false,
+ "valueDesc": "",
+ "description": "",
+ "debugLabel": "",
+ "toolDescription": ""
+ },
+ {
+ "renderTypeList": [
+ "reference"
+ ],
+ "valueType": "string",
+ "canEdit": true,
+ "key": "title-plugin",
+ "label": "title-plugin",
+ "customInputConfig": {
+ "selectValueTypeList": [
+ "string",
+ "number",
+ "boolean",
+ "object",
+ "arrayString",
+ "arrayNumber",
+ "arrayBoolean",
+ "arrayObject",
+ "any",
+ "chatHistory",
+ "datasetQuote",
+ "dynamic",
+ "selectApp",
+ "selectDataset"
+ ],
+ "showDescription": false,
+ "showDefaultValue": true
+ },
+ "required": true,
+ "value": [
+ "pluginInput",
+ "title"
+ ]
+ },
+ {
+ "renderTypeList": [
+ "reference"
+ ],
+ "valueType": "string",
+ "canEdit": true,
+ "key": "xAxis-plugin",
+ "label": "xAxis-plugin",
+ "customInputConfig": {
+ "selectValueTypeList": [
+ "string",
+ "number",
+ "boolean",
+ "object",
+ "arrayString",
+ "arrayNumber",
+ "arrayBoolean",
+ "arrayObject",
+ "any",
+ "chatHistory",
+ "datasetQuote",
+ "dynamic",
+ "selectApp",
+ "selectDataset"
+ ],
+ "showDescription": false,
+ "showDefaultValue": true
+ },
+ "required": true,
+ "value": [
+ "pluginInput",
+ "xAxis"
+ ]
+ },
+ {
+ "renderTypeList": [
+ "reference"
+ ],
+ "valueType": "string",
+ "canEdit": true,
+ "key": "yAxis-plugin",
+ "label": "yAxis-plugin",
+ "customInputConfig": {
+ "selectValueTypeList": [
+ "string",
+ "number",
+ "boolean",
+ "object",
+ "arrayString",
+ "arrayNumber",
+ "arrayBoolean",
+ "arrayObject",
+ "any",
+ "chatHistory",
+ "datasetQuote",
+ "dynamic",
+ "selectApp",
+ "selectDataset"
+ ],
+ "showDescription": false,
+ "showDefaultValue": true
+ },
+ "required": true,
+ "value": [
+ "pluginInput",
+ "yAxis"
+ ]
+ },
+ {
+ "renderTypeList": [
+ "reference"
+ ],
+ "valueType": "string",
+ "canEdit": true,
+ "key": "chartType-plugin",
+ "label": "chartType-plugin",
+ "customInputConfig": {
+ "selectValueTypeList": [
+ "string",
+ "number",
+ "boolean",
+ "object",
+ "arrayString",
+ "arrayNumber",
+ "arrayBoolean",
+ "arrayObject",
+ "any",
+ "chatHistory",
+ "datasetQuote",
+ "dynamic",
+ "selectApp",
+ "selectDataset"
+ ],
+ "showDescription": false,
+ "showDefaultValue": true
+ },
+ "required": true,
+ "value": [
+ "pluginInput",
+ "chartType"
+ ]
+ }
+ ],
+ "outputs": [
+ {
+ "id": "system_addOutputParam",
+ "key": "system_addOutputParam",
+ "type": "dynamic",
+ "valueType": "dynamic",
+ "label": "",
+ "customFieldConfig": {
+ "selectValueTypeList": [
+ "string",
+ "number",
+ "boolean",
+ "object",
+ "arrayString",
+ "arrayNumber",
+ "arrayBoolean",
+ "arrayObject",
+ "any",
+ "chatHistory",
+ "datasetQuote",
+ "dynamic",
+ "selectApp",
+ "selectDataset"
+ ],
+ "showDescription": false,
+ "showDefaultValue": false
+ },
+ "valueDesc": "",
+ "description": ""
+ },
+ {
+ "id": "error",
+ "key": "error",
+ "label": "请求错误",
+ "description": "HTTP请求错误信息,成功时返回空",
+ "valueType": "object",
+ "type": "static",
+ "valueDesc": ""
+ },
+ {
+ "id": "httpRawResponse",
+ "key": "httpRawResponse",
+ "required": true,
+ "label": "原始响应",
+ "description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
+ "valueType": "any",
+ "type": "static",
+ "valueDesc": ""
+ },
+ {
+ "id": "bzaYjKyQFOw2",
+ "valueType": "string",
+ "type": "dynamic",
+ "key": "result",
+ "label": "result"
+ }
+ ]
+ }
+ ],
+ "edges": [
+ {
+ "source": "pluginInput",
+ "target": "ws0DFKJnCPhk",
+ "sourceHandle": "pluginInput-source-right",
+ "targetHandle": "ws0DFKJnCPhk-target-left"
+ },
+ {
+ "source": "ws0DFKJnCPhk",
+ "target": "pluginOutput",
+ "sourceHandle": "ws0DFKJnCPhk-source-right",
+ "targetHandle": "pluginOutput-target-left"
+ }
+ ]
+ }
+}
diff --git a/packages/plugins/src/drawing/template.json b/packages/plugins/src/drawing/template.json
new file mode 100644
index 000000000..c1a36e98f
--- /dev/null
+++ b/packages/plugins/src/drawing/template.json
@@ -0,0 +1,17 @@
+{
+ "author": "",
+ "version": "486",
+ "name": "BI图表功能",
+ "avatar": "core/workflow/template/BI",
+ "intro": "BI图表功能,可以生成一些常用的图表,如饼图,柱状图,折线图等",
+ "showStatus": false,
+ "weight": 100,
+
+ "isTool": true,
+ "templateType": "tools",
+
+ "workflow": {
+ "nodes": [],
+ "edges": []
+ }
+}
diff --git a/packages/web/components/common/Icon/constants.ts b/packages/web/components/common/Icon/constants.ts
index bed30fa3c..44c8d0682 100644
--- a/packages/web/components/common/Icon/constants.ts
+++ b/packages/web/components/common/Icon/constants.ts
@@ -267,6 +267,8 @@ export const iconPaths = {
'core/workflow/undo': () => import('./icons/core/workflow/undo.svg'),
'core/workflow/upload': () => import('./icons/core/workflow/upload.svg'),
'core/workflow/versionHistories': () => import('./icons/core/workflow/versionHistories.svg'),
+ 'core/workflow/template/baseChart': () => import('./icons/core/workflow/template/baseChart.svg'),
+ 'core/workflow/template/BI': () => import('./icons/core/workflow/template/BI.svg'),
date: () => import('./icons/date.svg'),
delete: () => import('./icons/delete.svg'),
edit: () => import('./icons/edit.svg'),
diff --git a/packages/web/components/common/Icon/icons/core/workflow/template/BI.svg b/packages/web/components/common/Icon/icons/core/workflow/template/BI.svg
new file mode 100644
index 000000000..10c52f0a1
--- /dev/null
+++ b/packages/web/components/common/Icon/icons/core/workflow/template/BI.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/packages/web/components/common/Icon/icons/core/workflow/template/baseChart.svg b/packages/web/components/common/Icon/icons/core/workflow/template/baseChart.svg
new file mode 100644
index 000000000..5ac3bea6c
--- /dev/null
+++ b/packages/web/components/common/Icon/icons/core/workflow/template/baseChart.svg
@@ -0,0 +1 @@
+
\ No newline at end of file