本文作者:krryguo,腾讯高级前端开发工程师
本文将 ChatGPT 接入图表配置化工具,支持用一段话描述图表信息,生成图表后直接进入配置页面,输入一句话生成图表内容,并可进行配置和导出,效果如下:
介绍
可视化图表配置工具:提供图表、数据可配置式的 BI 能力,支持多种基础图表属性并结合业务衍生更多业务型属性配置,可导出预览图、数据源和配置信息,并可保存用户配置过的图表。
接入 ChatGPT(GPT3.5-turbo),根据用户输入的内容生成图表,总的流程如下:
预置属性和 ChatGPT 返回的内容解析后 merge
,后者覆盖相同属性,从而顺利接入到现有流程:
实现方法
主要分三步实现。
prompt 规则
用户输入一句话,我们需要追加一些内容使其返回我们想要的格式,本质是通过它返回一段能描述图表信息的 DSL。
用户描述窗口:
用户可以指定生成图类型,未指定将默认按折线图渲染
GPT3.5-turbo API 参数:
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Who won the world series in 2020?"},
{"role": "assistant", "content": "The Los Angeles Dodgers won the World Series in 2020."},
{"role": "user", "content": "Where was it played?"}
]
可以增加 system
or assistant
约束返回规则,更好支持上下文,但我这边暂时不需要上下文,且 user prompt
遵循力度更高,所以我采用 user
追加 prompt 的方式实现。
为增加安全和隐私性,需要隐藏下面两个内容:
-
开发者工具接口调用追加的
prompt
-
具体 API 地址
还需要控制 API 的访问权限,因此在工具的后端服务重新封装此 API,进一步规范提供给前端的接口服务,现在前端能够看到的就只有用户自己输入的 prompt
:
后端服务调用,部分 code 示例:
import { BaseController } from './base';
const system =
'。请你根据前面的描述回复一段json数据结构,包含四个同级属性,title:名称,data:纵坐标数组,xAxis:横坐标数组,column:列名数组(第一列是横坐标名称,第二列是纵坐标名称)';
export default class ChatgptController extends BaseController {
/**
* @description: chatGPT
* @return {*}
*/
async getMessage() {
const { ctx } = this;
const { prompt } = ctx.request.body;
const { data } = await ctx.curl('http://***', {
method: 'POST',
contentType: 'json',
data: {
message: [{ role: 'user', content: prompt + system }],
},
dataType: 'json',
});
console.log('回答内容:', data.data);
const response = data.data[0].message.content;
this.success({ result: getJSONConfig(response) });
}
}
约束的 prompt
可进一步优化,这里给一个示例。
获取 JSON 数据
一般通过正则表达式或字符串 substring 方式获取 GPT 返回内容里包含的 json 代码。
若出现各种不规范的 json 数据,JSON.parse
就会解析错误。如存在单引号、对象字面量项尾存在逗号、存在中文逗号 等等,采用字符串 replace + 正则的方式替换成规范的 JSON 格式。
解析数据
后端服务解析后返回到前端的 response:
通过 AI 生成的数据视为上传数据,保存表格数据和图表数据格式供后续步骤的渲染和导出。
数据注入 pinia:
// pinia
const customTable = ref({
name: '',
data: {},
table: {
data: [] as CustomMapType[],
column: [] as string[],
},
});
// 数据存入 pinia
const [itemName, valueName] = result.column ?? result.columns;
chartStore.setDefindTable(
result.title + '.xlsx',
{
[itemName]: result.xAxis,
[valueName]: result.data,
},
{
data: result.xAxis.map((ele, i) => ({
[itemName]: ele,
[valueName]: result.data[i],
})),
column: result.column,
},
);
注入 option.series:
// 数据
const tableData = isUpload ? customTable.data : tableMap[selectTable];
// 数据列
const tableDataKey = customTable.table.column;
option.series.push({
type: currentChart.type, // 解析的图类型
name: tableDataKey[1],
data: tableData[tableDataKey[1]],
...cloneDeep(option.seriesOption), // 该图类型的预置属性
});
option.xAxis.data = tableData[tableDataKey[0]];
渲染效果图:
导出界面:
当前 ChatGPT 生成的图表布局和样式还是采用默认预置的属性,后续会继续支持用户在输入信息时定制图表样式。
其他示例
最后贴一些其他展示用例(以下 AI 生成的数据均为随机且仅供参考),用地图描述中国北方地区降雨量:
用面积图描绘海南一年平均气温变化:
用南丁格尔玫瑰图描绘李华对各项运动的喜爱程度:
后记
ChatGPT 接入图表配置化工具,可以让用户通过简单的自然语言输入,快速生成各种类型的图表,并且可以让用户自定义图表的样式和布局,从而满足不同用户的需求,如做设计、发邮件、写报告。ChatGPT 与图表配置化工具的结合,将会为用户提供更加便捷和灵活的数据分析服务。
# 技术人说 #
本周三晚19:30,有趣有料:
一键预约⬇️
# 腾讯技术直播 #
腾讯工程师分享技术干货:
一键预约⬇️
往期文章:
设为星标,下次再见👋