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 小时前
React Native 鸿蒙跨平台开发:实现一个多功能单位转换器
javascript·react native·react.js
南半球与北海道#4 小时前
前端打印(三联纸票据打印)
前端·vue.js·打印
摘星编程4 小时前
React Native for OpenHarmony 实战:ToggleSwitch 切换开关详解
javascript·react native·react.js
董世昌414 小时前
深入浅出 JavaScript 常用事件:从原理到实战的全维度解析
前端
满栀5854 小时前
分页插件制作
开发语言·前端·javascript·jquery
qq_406176145 小时前
深入剖析JavaScript原型与原型链:从底层机制到实战应用
开发语言·前端·javascript·原型模式
弓.长.5 小时前
React Native 鸿蒙跨平台开发:BottomSheet 底部面板详解
javascript·react native·react.js
开开心心_Every5 小时前
免费窗口置顶小工具:支持多窗口置顶操作
服务器·前端·学习·macos·edge·powerpoint·phpstorm
摘星编程5 小时前
React Native for OpenHarmony 实战:Permissions 权限管理详解
javascript·react native·react.js
闲蛋小超人笑嘻嘻6 小时前
Vue 插槽:从基础到进阶
前端·javascript·vue.js