Skip to content

我经常使用echarts来绘制的图形类型 折线图,柱状图,k线图,饼图,散点图,雷达图...

以下是 ECharts 常见复杂场景的处理方案及实践技巧,结合实际开发经验和性能优化策略:


一、大数据量渲染(万级数据点)

1. 数据降采样与优化

  • 问题:万级数据直接渲染导致卡顿。
  • 方案
    • 数据聚合:后端预处理数据,返回聚合后的统计结果(如按时间区间分桶)。
    • 前端降采样:使用 ECharts 内置的 数据采样策略(如 series.sampling: 'lttb' 保留趋势特征)。
    • 分页加载:大数据分片动态加载,结合 dataZoom 组件实现滚动加载。
  • 代码示例
    javascript
    series: [{
      type: 'line',
      sampling: 'lttb',  // 使用 Largest-Triangle-Three-Buckets 算法采样
      data: hugeDataArray
    }]

2. WebGL 加速

  • 问题:Canvas 渲染性能不足。
  • 方案:使用 ECharts GLWebGL 渲染引擎。
    javascript
    import 'echarts-gl';
    series: [{
      type: 'scatterGL',  // WebGL 渲染的散点图
      data: pointsData,
      itemStyle: { opacity: 0.8 }
    }]

二、动态数据实时更新

1. 流式数据(如实时监控)

  • 方案
    • 增量更新:使用 appendData 方法追加数据,避免全量重绘。(行情信号图)
    • 窗口滑动:固定显示最新 N 个数据点,动态移除旧数据。
  • 代码示例
    javascript
    // 初始化图表
    let chart = echarts.init(dom);
    chart.setOption({ /* 初始配置 */ });
    
    // 每秒追加新数据
    setInterval(() => {
      const newData = getNewData();
      chart.appendData({
        seriesIndex: 0,  // 目标系列索引
        data: [newData]  // 增量数据
      });
    }, 1000);

2. 交互动画同步

  • 场景:拖拽 dataZoomvisualMap 时,联动更新其他图表。
  • 方案:监听 datazoom 事件,更新关联图表数据。
    javascript
    chart.on('datazoom', (params) => {
      const { start, end } = params;
      // 根据窗口范围过滤数据,更新其他图表
      otherChart.setOption({ dataset: { source: filteredData } });
    });

三、复杂图表组合

1. 多坐标系混合

  • 场景:同一图表中混合折线图、柱状图、散点图,使用不同 Y 轴。
  • 方案:配置多个 yAxisxAxis,绑定到不同系列。
    javascript
    option = {
      xAxis: [{ /* 主 X 轴 */ }, { /* 副 X 轴(如时间轴) */ }],
      yAxis: [{ /* 主 Y 轴 */ }, { /* 副 Y 轴 */ }],
      series: [
        { type: 'line', xAxisIndex: 0, yAxisIndex: 0 },
        { type: 'bar', xAxisIndex: 1, yAxisIndex: 1 }
      ]
    };

2. 自定义叠加图形

  • 场景:在图表上叠加自定义标记、辅助线、区域。
  • 方案:使用 graphic 组件或 markLine/markArea
    javascript
    option = {
      graphic: [{
        type: 'rect',  // 绘制矩形区域
        shape: { x: 100, y: 100, width: 200, height: 50 },
        style: { fill: 'rgba(255,0,0,0.3)' }
      }],
      series: [{
        type: 'line',
        markLine: {  // 标记线
          data: [{ type: 'average', name: '平均值' }]
        }
      }]
    };

四、交互与联动

1. 跨图表联动

  • 场景:点击 A 图表的数据项,高亮 B 图表对应项。
  • 方案:通过 connect 关联多个图表实例。
    javascript
    // 创建关联组
    const group = echarts.connect([chart1, chart2, chart3]);
    
    // 任一图表触发事件,其他图表响应
    chart1.on('click', (params) => {
      chart2.dispatchAction({ type: 'highlight', seriesIndex: params.seriesIndex });
    });

2. 自定义 Tooltip

  • 场景:复杂 Tooltip 内容(如图片、交互按钮)。
  • 方案:使用 formatter 返回 HTML 或 Vue/React 组件。
    javascript
    tooltip: {
      formatter: (params) => {
        return `<div>
          <img src="${params[0].data.image}" width="50"/>
          <span>值:${params[0].data.value}</span>
        </div>`;
      }
    }

五、性能优化

1. 渲染优化

  • 策略
    • 关闭动画:animation: false
    • 减少重绘:使用 throttle 限制频繁的 setOption 调用。
    • 按需渲染:隐藏不可见区域的图表(如 IntersectionObserver 监听可视区域)。

2. 内存管理

  • 场景:单页应用(SPA)中图表内存泄漏。
  • 方案:组件销毁时调用 dispose 释放资源。
    javascript
    // Vue 组件
    beforeUnmount() {
      if (this.chart) {
        this.chart.dispose();
        this.chart = null;
      }
    }

六、自定义主题与样式

1. 全局主题

  • 方案:通过 echarts.registerTheme 注册自定义主题。
    javascript
    echarts.registerTheme('myTheme', {
      color: ['#c23531', '#2f4554', '#61a0a8'],
      backgroundColor: '#f0f0f0'
    });
    const chart = echarts.init(dom, 'myTheme');

2. 条件样式

  • 场景:根据数据值动态设置颜色、大小。
  • 方案:使用 visualMapitemStyle 回调。
    javascript
    series: [{
      type: 'scatter',
      itemStyle: {
        color: (params) => params.value > 100 ? 'red' : 'green'
      }
    }]

七、服务端渲染(SSR)

1. Node.js 渲染图表

  • 方案:使用 echarts-node-canvasnode-echarts 在服务端生成图表图片。
    javascript
    const { createCanvas } = require('canvas');
    const echarts = require('echarts-node-canvas');
    
    const canvas = createCanvas(800, 600);
    const chart = echarts.init(canvas);
    chart.setOption(option);
    const buffer = canvas.toBuffer('image/png');

八、地图可视化

1. 自定义 GeoJSON 地图

  • 方案:注册自定义地图数据并绑定到系列。
    javascript
    // 加载 GeoJSON
    fetch('custom-map.json')
      .then(res => res.json())
      .then(geoJson => {
        echarts.registerMap('myRegion', geoJson);
        chart.setOption({
          series: [{
            type: 'map',
            map: 'myRegion',
            data: regionData
          }]
        });
      });

2. 热力地图优化

  • 策略
    • 使用 heatmap 系列替代散点图。
    • 调整 blurSizepointSize 平衡精度与性能。
    javascript
    series: [{
      type: 'heatmap',
      data: heatData,
      blurSize: 30,
      pointSize: 10
    }]

总结

  • 数据优化:降采样、分页、WebGL 加速应对大数据场景。
  • 交互设计:通过事件监听和 connect 实现复杂联动。
  • 性能调优:关闭非必要动画、按需渲染、内存管理。
  • 扩展能力:自定义主题、服务端渲染、地图集成满足定制需求。

图表场景总结

  1. 分时图怎么画的