Vue2 + ECharts 实战:动态一个关键词或动态多关键词筛选折线图,告别数据重叠难题

功能一、一次只能搜索一个图例

效果一:

代码:

复制代码
<template>
  <div class="chart-container">
    <input 
      v-model="searchKeyword"
      placeholder="输入关键词搜索图例"
      @input="handleSearch"
    />
    <!-- 确保 ref 名称正确且元素存在 -->
    <div ref="chart" style="width: 800px; height: 400px;"></div>
  </div>
</template>

<script>
// 正确引入 echarts
import * as echarts from 'echarts';

export default {
  data() {
    return {
      searchKeyword: '',
      chartInstance: null, // 存储图表实例
      option: {
        legend: {
          data: ['销售额', '成本', '利润'],
          selected: {} // 初始化 selected 对象
        },
        xAxis: { type: 'category', data: ['1月', '2月', '3月', '4月', '5月', '6月'] },
        yAxis: { type: 'value' },
        series: [
          { name: '销售额', type: 'line', data: [120, 200, 150, 80, 70, 110] },
          { name: '成本', type: 'line', data: [80, 120, 100, 60, 50, 90] },
          { name: '利润', type: 'line', data: [40, 80, 50, 20, 20, 20] }
        ]
      }
    };
  },
  mounted() {
    // 确保在 mounted 钩子中初始化图表
    this.initChart();
  },
  beforeDestroy() {
    // 销毁图表实例
    if (this.chartInstance) {
      this.chartInstance.dispose();
    }
  },
  methods: {
    initChart() {
      // 确保 DOM 元素已渲染
      if (this.$refs.chart) {
        // 初始化图表
        this.chartInstance = echarts.init(this.$refs.chart);
        // 设置默认选中所有图例
        this.option.legend.selected = this.option.legend.data.reduce((acc, name) => {
          acc[name] = true;
          return acc;
        }, {});
        // 渲染图表
        this.chartInstance.setOption(this.option);
      } else {
        console.error('DOM 元素未找到,请检查 ref="chart"');
      }
    },
    handleSearch() {
      const keyword = this.searchKeyword.trim().toLowerCase();
      const newSelected = this.option.legend.data.reduce((acc, name) => {
        acc[name] = name.toLowerCase().includes(keyword);
        return acc;
      }, {});
      // 更新图例显隐状态
      this.chartInstance.setOption({
        legend: { selected: newSelected }
      });
    }
  }
};
</script>

功能二、一次可以搜索多个图例,以英文逗号分隔

效果展示:

代码:

复制代码
<template>
  <div class="chart-container">
    <input 
      v-model="searchKeywords"
      placeholder="请输入图例名称,多个关键词以英文逗号分隔"
      class="search-input"
      @input="handleSearch"
    />
    <div ref="chart" class="chart"></div>
  </div>
</template>

<script>
import * as echarts from 'echarts';

export default {
  data() {
    return {
      searchKeywords: '',      // 搜索关键词(支持逗号分隔)
      chartInstance: null,     // ECharts 实例
      baseOption: {            // 图表基础配置
        legend: {
          data: ['北京销售额', '上海销售额', '广州成本', '深圳利润'],
          selected: {}
        },
        xAxis: { type: 'category', data: ['Q1', 'Q2', 'Q3', 'Q4'] },
        yAxis: { type: 'value' },
        series: [
          { name: '北京销售额', type: 'line', data: [120, 200, 150, 80] },
          { name: '上海销售额', type: 'line', data: [180, 240, 210, 160] },
          { name: '广州成本', type: 'line', data: [80, 100, 70, 50] },
          { name: '深圳利润', type: 'line', data: [40, 80, 60, 30] }
        ]
      }
    };
  },
  mounted() {
    this.initChart();
  },
  beforeDestroy() {
    if (this.chartInstance) {
      this.chartInstance.dispose();
    }
  },
  methods: {
    // 初始化图表
    initChart() {
      this.chartInstance = echarts.init(this.$refs.chart);
      // 默认全部显示
      const initialSelected = this.baseOption.legend.data.reduce((acc, name) => {
        acc[name] = true;
        return acc;
      }, {});
      this.baseOption.legend.selected = initialSelected;
      this.chartInstance.setOption(this.baseOption);
    },

    // 处理搜索输入(支持逗号分隔多个关键词)
    handleSearch() {
      // 分割关键词并处理格式
      const keywords = this.searchKeywords
        .split(',')
        .map(k => k.trim().toLowerCase())
        .filter(k => k !== '');

      // 生成新的 selected 对象(任一关键词匹配即显示)
      const newSelected = this.baseOption.legend.data.reduce((acc, name) => {
        const nameLower = name.toLowerCase();
        acc[name] = keywords.length === 0 || keywords.some(k => nameLower.includes(k));
        return acc;
      }, {});

      // 更新图表
      this.chartInstance.setOption({
        legend: { selected: newSelected }
      });
    }
  }
};
</script>

<style scoped>
.chart-container {
  width: 1000px;
  margin: 20px auto;
}
.search-input {
  width: 400px;
  padding: 8px 12px;
  margin-bottom: 15px;
  border: 1px solid #ddd;
  border-radius: 4px;
  font-size: 14px;
}
.chart {
  width: 100%;
  height: 500px;
}
</style>
相关推荐
葡萄城技术团队4 小时前
1000 人协同压测的环境瓶颈排查:CPU 争用与 Wi\-Fi
前端
excel5 小时前
Marked 与 Markdown 有什么区别?该怎么选?
前端
Da Da 泓6 小时前
五子棋 Web 端测试用例报告
前端·网络·websocket·网络协议·测试用例·项目
zxcvb1537 小时前
远程查看本地文档:一条轻量 Web 文件服务的工程化链路
前端·远程查看文档
niucloud-admin7 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php
程序员大阳7 小时前
副队长JavaScript教程(50)-DOM:网页开发的起点
javascript·dom·es·节点·概念·document·关系
北岛贰7 小时前
啵啵音乐迎来全新升级!
前端
hkNaruto9 小时前
【AI】基于大模型的AI游戏地图生成、控制方案:AI Native Game Harness 迁移操作手册
前端·人工智能·游戏
IT_陈寒9 小时前
Java序列化踩坑记:对象循环引用让我加班两小时
前端·人工智能·后端
Acro10 小时前
快给macOS 上的Grok Bot换一套皮肤
前端