一.为什么做这个案例?
近期接触的团队项目是关于ai问答的,其中图表输出是一个比较有趣的点,可以增加问答的多样性和丰富性,因此做了一个简单的案例.
二.如何做?
技术栈:uniapp+vue2+echarts
(用其他技术也可以,vue3,react等,这个案例主要是提供学习思想.)
1、思考点:
ai问答中的一问一答?
比如系统根据用户的输入,给出下一步的指示和操作,
如果输入的内容不包含指定关键词,则给出修正提示.
(注意:这里为了方便演示,只给出正确的提示词)





比如这里,毛衣对应的销量就是22,长袖对应33,短袖对应11,卫衣对应44

图表数据就是根据用户给出的信息得出.
配合代码截图介绍

提示语用currentMessage存储,userInput存储用户输入.
用户的输入会改变当前对话的状态以及提示语(currentMessage).
创建一个对象用于定义对话状态

函数-对话的起始(将状态变量(dialogState)设置为'start')

组件挂载完成时执行"执行对话"函数

输入的响应式绑定(实时监听和改变userInput的值)
@click='xx',点击事件,这里是根据用户当前的输入,进行判断是否进入下一个对话状态.

switch语句判断当前的对话状态是什么,然后进行对应操作.每次完成对话状态的改变,都会清空输入框.

函数-创建图表实例
(当对话状态执行完正确输入系列数据之后,便会执行这条函数)

创建一个图表类(参考官网的基础柱形图)


三.具体实现
1、创建一个uniapp项目
安装对应的包-echarts vue-echarts
npm install echarts@4 vue-echarts@4 --save --force
//--force 忽略风险 强制安装
(下图是我安装echarts和vue-echarts的版本号)

2、完整代码参考
写在src/pages/index/index.vue中即可.

<template>
<view class="content">
<view class="chat-container">
<view class="message">{{ currentMessage }}</view>
<input v-model="userInput" placeholder="请输入..." />
<button @click="handleInput(userInput)">发送</button>
</view>
<!-- 图表判断和渲染 -->
<view v-if="charts.length != 0">
<ECharts
class="echarts-container"
v-for="(item, index) in charts"
:key="index"
:options="item"
autoresize
></ECharts>
</view>
</view>
</template>
<script>
import ECharts from "vue-echarts";
import * as echarts from "echarts";
const DIALOG_STATES = {
START: "start",
TITLE: "title",
SERIES_NAME: "series_name",
X_AXIS_DATA: "x_axis_data",
SERIES_DATA: "series_data",
COMPLETE: "complete",
};
class ChartOptions {
constructor(titleText, seriesName, xAxisData, seriesData) {
this.title = { text: titleText };
this.tooltip = {};
this.legend = { data: [seriesName] };
this.xAxis = { data: xAxisData };
this.yAxis = {};
this.series = [
{
name: seriesName,
type: "bar",
data: seriesData,
},
];
}
}
export default {
components: {
ECharts,
},
data() {
return {
dialogState: DIALOG_STATES.START,
// 图表标题
titleText: "",
// 图表名称
seriesName: "",
// 系列名称
xAxisData: "",
// 系列数据
seriesData: "",
// 存取图表
charts: [],
// 当前引导提示语
currentMessage: "",
// 用户输入
userInput: "",
};
},
methods: {
startDialog() {
this.dialogState = DIALOG_STATES.START;
this.currentMessage = "你好,有什么可以帮到你?";
},
// 用户点击
handleInput(input) {
switch (this.dialogState) {
case DIALOG_STATES.START:
if (input == "生成图表") {
this.titleText = input;
this.dialogState = DIALOG_STATES.TITLE;
this.currentMessage = "好的,请您输入图表标题:";
} else {
this.currentMessage = "如果您想生成图表,则请输入:生成图表";
return;
}
break;
case DIALOG_STATES.TITLE:
if (input) {
this.titleText = input;
this.dialogState = DIALOG_STATES.SERIES_NAME;
this.currentMessage = "请输入系列名称:";
} else {
this.currentMessage = "标题不能为空,请重新输入图表标题:";
}
break;
case DIALOG_STATES.SERIES_NAME:
if (input) {
this.seriesName = input;
this.dialogState = DIALOG_STATES.X_AXIS_DATA;
this.currentMessage = "请输入X轴数据(用逗号分隔):";
} else {
this.currentMessage = "系列名称不能为空,请重新输入系列名称:";
}
break;
case DIALOG_STATES.X_AXIS_DATA:
if (input) {
this.xAxisData = input;
this.dialogState = DIALOG_STATES.SERIES_DATA;
this.currentMessage = "请输入系列数据(用逗号分隔的数字):";
} else {
this.currentMessage = "X轴数据不能为空,请重新输入X轴数据:";
}
break;
case DIALOG_STATES.SERIES_DATA:
if (input) {
try {
const seriesDataArray = input
.split(",")
.map((item) => parseInt(item.trim()));
if (seriesDataArray.some((item) => isNaN(item))) {
throw new Error("系列数据必须是数字");
}
this.seriesData = input;
this.dialogState = DIALOG_STATES.COMPLETE;
this.createChart();
} catch (error) {
this.currentMessage = `系列数据无效,请重新输入系列数据: ${error.message}`;
}
} else {
this.currentMessage = "系列数据不能为空,请重新输入系列数据:";
}
break;
default:
this.currentMessage = "对话已结束。";
break;
}
this.userInput = ""; // 清空输入框
},
// 创建图表类实例
createChart() {
const xAxisDataArray = this.xAxisData
.split(",")
.map((item) => item.trim());
const seriesDataArray = this.seriesData
.split(",")
.map((item) => parseInt(item.trim()));
const chart = new ChartOptions(
this.titleText,
this.seriesName,
xAxisDataArray,
seriesDataArray
);
this.charts.push(chart);
console.log("当前存储的图表数据有", this.charts);
this.currentMessage =
"图表配置已保存!如果要重新生成图表,请输入:生成图表";
this.dialogState = DIALOG_STATES.START;
// 清空输入
this.titleText = "";
this.seriesName = "";
this.xAxisData = "";
this.seriesData = "";
},
},
mounted() {
// 执行对话
this.startDialog();
},
};
</script>
<style>
.content {
padding: 20px;
}
.chat-container {
max-width: 600px;
margin: 0 auto;
}
.echarts-container {
max-width: 400px;
margin: 0 auto;
}
.message {
margin-bottom: 10px;
font-weight: bold;
}
input {
width: 100%;
height: 40px;
padding: 10px;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
margin-bottom: 10px;
}
button {
width: 100%;
height: 40px;
background-color: #1aad19;
color: white;
border: none;
border-radius: 4px;
font-size: 16px;
cursor: pointer;
}
</style>
3、测试生成的结果


如果你喜欢这篇文章,可以点赞收藏关注.
有问题可以留言评论喔!
&spm=1001.2101.3001.5002&articleId=143558630&d=1&t=3&u=7e793c6e356f4887978b00c42542aa70)
4973

被折叠的 条评论
为什么被折叠?



