【Echarts】开发uniapp对话式生成简易版echarts图表(亲测可用)

一.为什么做这个案例?

近期接触的团队项目是关于ai问答的,其中图表输出是一个比较有趣的点,可以增加问答的多样性和丰富性,因此做了一个简单的案例.

二.如何做?

技术栈:uniapp+vue2+echarts

(用其他技术也可以,vue3,react等,这个案例主要是提供学习思想.)

1、思考点:

ai问答中的一问一答?

比如系统根据用户的输入,给出下一步的指示和操作,

如果输入的内容不包含指定关键词,则给出修正提示.

(注意:这里为了方便演示,只给出正确的提示词)

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

图表数据就是根据用户给出的信息得出.

配合代码截图介绍

提示语用currentMessage存储,userInput存储用户输入.

用户的输入会改变当前对话的状态以及提示语(currentMessage).

创建一个对象用于定义对话状态

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

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

输入的响应式绑定(实时监听和改变userInput的值)

@click='xx',点击事件,这里是根据用户当前的输入,进行判断是否进入下一个对话状态.

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

 函数-创建图表实例

(当对话状态执行完正确输入系列数据之后,便会执行这条函数)

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

Examples - Apache ECharts

三.具体实现

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、测试生成的结果

 


如果你喜欢这篇文章,可以点赞收藏关注.

有问题可以留言评论喔!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十八朵郁金香

感恩前行路上有你相伴

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值