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>
相关推荐
To_OC4 小时前
LC 131 分割回文串:刚学回溯时,我连怎么切字符串都想不明白
javascript·算法·leetcode
咩咩啃树皮5 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
阳光是sunny5 小时前
LangGraph中的Reducer是什么
前端·人工智能·后端
触底反弹5 小时前
一文搞懂 Tailwind CSS 弹性布局:从原理到实战
前端·css·html
阳光是sunny5 小时前
从链到图:LangGraph 入门基础全解析
前端·人工智能·后端
To_OC6 小时前
LC 42 接雨水:暴力超时卡半天?前后缀数组一用就通了
javascript·算法·leetcode
小林ixn6 小时前
从 ??= 到 onKeyDown:一个 React 组件的“自我修养”
前端·javascript·react.js
REDcker6 小时前
显示分辨率标准对照详解
前端·网络·分辨率·显示·屏幕
এ慕ོ冬℘゜7 小时前
前端实战:jQuery 多条件联合搜索(标题模糊查询 + 日历时间段筛选)
前端·javascript·jquery
武子康7 小时前
Search Console Platform Properties 扩大 SEO 资产边界:从 Page Ranking 到 Topic Coverage(5 类误读边界 + 3 表数据层设计)
前端·人工智能·后端