ECharts 交互功能 #

本章将介绍 ECharts 的各种交互功能,帮助你创建具有丰富交互体验的数据可视化图表。

提示框(Tooltip) #

基础配置 #

javascript
tooltip: {
  // 触发类型
  trigger: 'axis',  // 'item' - 数据项图形触发, 'axis' - 坐标轴触发, 'none' - 不触发
  
  // 触发条件
  triggerOn: 'mousemove',  // 'mousemove', 'click', 'mousemove|click'
  
  // 显示延迟
  showDelay: 0,
  
  // 隐藏延迟
  hideDelay: 100,
  
  // 是否显示提示框
  show: true,
  
  // 是否永远显示
  alwaysShowContent: false
}

内容格式化 #

javascript
tooltip: {
  // 字符串模板
  formatter: '{b}: {c}',
  
  // 多系列模板
  formatter: '{b}<br/>{a0}: {c0}<br/>{a1}: {c1}',
  
  // 回调函数
  formatter: function(params) {
    let result = params[0].name + '<br/>';
    params.forEach(item => {
      result += `${item.seriesName}: ${item.value}<br/>`;
    });
    return result;
  },
  
  // 单个数据项格式化
  formatter: function(params) {
    return `${params.name}: ${params.value} (${params.percent}%)`;
  }
}

样式定制 #

javascript
tooltip: {
  // 背景色
  backgroundColor: 'rgba(50, 50, 50, 0.7)',
  
  // 边框
  borderColor: '#333',
  borderWidth: 1,
  
  // 内边距
  padding: [10, 15],
  
  // 文本样式
  textStyle: {
    color: '#fff',
    fontSize: 14
  },
  
  // 额外的 CSS 样式
  extraCssText: 'box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);'
}

指示器配置 #

javascript
tooltip: {
  trigger: 'axis',
  axisPointer: {
    // 指示器类型
    type: 'shadow',  // 'line', 'shadow', 'cross', 'none'
    
    // 线条样式
    lineStyle: {
      color: '#555',
      width: 1,
      type: 'dashed'
    },
    
    // 阴影样式
    shadowStyle: {
      color: 'rgba(150, 150, 150, 0.3)'
    },
    
    // 十字准星
    crossStyle: {
      color: '#999'
    },
    
    // 是否显示标签
    label: {
      show: true,
      formatter: function(params) {
        return params.value;
      }
    }
  }
}

位置控制 #

javascript
tooltip: {
  // 固定位置
  position: ['50%', '50%'],
  
  // 回调函数动态计算
  position: function(point, params, dom, rect, size) {
    // point: 鼠标位置
    // size: 内容尺寸
    return [point[0], point[1] - size.contentSize[1] - 10];
  },
  
  // 预设位置
  position: function(point, params, dom, rect, size) {
    // 固定在顶部
    return [point[0], '10%'];
  }
}

图例(Legend) #

基础配置 #

javascript
legend: {
  // 图例数据
  data: ['系列1', '系列2', '系列3'],
  
  // 显示位置
  left: 'center',  // 'left', 'center', 'right', '20%'
  top: 'top',      // 'top', 'middle', 'bottom', '20%'
  
  // 布局方向
  orient: 'horizontal',  // 'horizontal', 'vertical'
  
  // 图例项间距
  itemGap: 20,
  
  // 图例项宽度
  itemWidth: 25,
  
  // 图例项高度
  itemHeight: 14
}

图例交互 #

javascript
legend: {
  // 选中状态
  selected: {
    '系列1': true,
    '系列2': false,
    '系列3': true
  },
  
  // 允许点击切换
  selectedMode: true,  // true, false, 'single'
  
  // 监听选择变化
  // chart.on('legendselectchanged', function(params) {...})
}

图例样式 #

javascript
legend: {
  // 图标形状
  icon: 'circle',  // 'circle', 'rect', 'roundRect', 'triangle', 'diamond', 'pin', 'arrow'
  
  // 文本样式
  textStyle: {
    color: '#333',
    fontSize: 12,
    fontWeight: 'normal'
  },
  
  // 选中状态样式
  inactiveColor: '#ccc'
}

分页图例 #

javascript
legend: {
  type: 'scroll',  // 'plain', 'scroll'
  orient: 'vertical',
  right: 10,
  top: 20,
  bottom: 20,
  
  // 分页按钮样式
  pageButtonItemGap: 5,
  pageButtonGap: 10,
  pageIconColor: '#2f4554',
  pageIconInactiveColor: '#aaa',
  pageIconSize: 15,
  pageTextStyle: {
    color: '#333'
  }
}

数据区域缩放(DataZoom) #

滑动条型 #

javascript
dataZoom: [{
  type: 'slider',  // 'slider', 'inside'
  
  // 显示位置
  xAxisIndex: 0,   // 控制的 x 轴
  yAxisIndex: 0,   // 控制的 y 轴
  
  // 初始范围
  start: 0,        // 开始百分比
  end: 100,        // 结束百分比
  
  // 显示位置
  left: 'center',
  right: 10,
  bottom: 10,
  
  // 是否显示详情
  showDetail: true,
  
  // 是否显示数据阴影
  showDataShadow: true,
  
  // 手柄样式
  handleIcon: 'M10.7,11.9v-1.3H9.3v1.3c-4.9,0.3-8.8,4.4-8.8,9.4c0,5,3.9,9.1,8.8,9.4v1.3h1.3v-1.3c4.9-0.3,8.8-4.4,8.8-9.4C19.5,16.3,15.6,12.2,10.7,11.9z M13.3,24.4H6.7V23h6.6V24.4z M13.3,19.6H6.7v-1.4h6.6V19.6z',
  handleSize: '80%',
  handleStyle: {
    color: '#fff',
    shadowBlur: 3,
    shadowColor: 'rgba(0, 0, 0, 0.6)',
    shadowOffsetX: 2,
    shadowOffsetY: 2
  }
}]

内置型 #

javascript
dataZoom: [{
  type: 'inside',
  xAxisIndex: 0,
  
  // 缩放范围
  start: 0,
  end: 100,
  
  // 缩放比例
  zoomOnMouseWheel: true,     // 鼠标滚轮缩放
  moveOnMouseMove: true,      // 鼠标移动平移
  moveOnMouseWheel: false,    // 鼠标滚轮平移
  preventDefaultMouseMove: true
}]

组合使用 #

javascript
dataZoom: [
  {
    type: 'slider',
    xAxisIndex: 0,
    start: 0,
    end: 50
  },
  {
    type: 'inside',
    xAxisIndex: 0,
    start: 0,
    end: 50
  }
]

Y 轴缩放 #

javascript
dataZoom: [{
  type: 'slider',
  yAxisIndex: 0,
  start: 0,
  end: 100,
  orient: 'vertical',
  right: 10
}]

工具栏(Toolbox) #

基础配置 #

javascript
toolbox: {
  // 显示位置
  left: 'right',
  top: 'top',
  
  // 布局方向
  orient: 'horizontal',  // 'horizontal', 'vertical'
  
  // 项间距
  itemGap: 10,
  
  // 图标大小
  itemSize: 15,
  
  // 显示标题
  showTitle: true
}

功能配置 #

javascript
toolbox: {
  feature: {
    // 保存为图片
    saveAsImage: {
      show: true,
      title: '保存为图片',
      type: 'png',  // 'png', 'jpeg', 'svg'
      name: 'chart',
      pixelRatio: 2,
      backgroundColor: '#fff'
    },
    
    // 数据视图
    dataView: {
      show: true,
      title: '数据视图',
      readOnly: false,  // 是否只读
      optionToContent: function(opt) {
        // 自定义数据视图内容
        return '<table>...</table>';
      },
      contentToOption: function(html) {
        // 从数据视图恢复数据
        return option;
      }
    },
    
    // 还原
    restore: {
      show: true,
      title: '还原'
    },
    
    // 数据区域缩放
    dataZoom: {
      show: true,
      title: {
        zoom: '区域缩放',
        back: '区域还原'
      },
      xAxisIndex: 0,
      yAxisIndex: false
    },
    
    // 动态类型切换
    magicType: {
      show: true,
      type: ['line', 'bar', 'stack'],
      title: {
        line: '切换为折线图',
        bar: '切换为柱状图',
        stack: '切换为堆叠'
      }
    },
    
    // 刷新
    brush: {
      show: true,
      title: {
        rect: '矩形选择',
        polygon: '多边形选择',
        lineX: '横向选择',
        lineY: '纵向选择',
        keep: '保持选择',
        clear: '清除选择'
      }
    }
  }
}

刷选(Brush) #

基础配置 #

javascript
brush: {
  // 刷选类型
  brushType: 'rect',  // 'rect', 'polygon', 'lineX', 'lineY'
  
  // 刷选模式
  brushMode: 'single',  // 'single', 'multiple'
  
  // 变换类型
  transformable: true,
  
  // 刷选框样式
  brushStyle: {
    borderWidth: 1,
    color: 'rgba(120, 140, 180, 0.3)',
    borderColor: 'rgba(120, 140, 180, 0.8)'
  },
  
  // 缩略框样式
  throttleType: 'fixRate',
  throttleDelay: 0,
  
  // 范围
  xAxisIndex: 'all',
  yAxisIndex: 'all'
}

刷选交互 #

javascript
// 监听刷选事件
chart.on('brushSelected', function(params) {
  const selected = params.batch[0].selected;
  selected.forEach(item => {
    console.log(item.seriesIndex, item.dataIndex);
  });
});

// 编程式设置刷选范围
chart.dispatchAction({
  type: 'brush',
  areas: [
    {
      brushType: 'rect',
      coordRange: [[10, 20], [30, 40]],
      xAxisIndex: 0,
      yAxisIndex: 0
    }
  ]
});

视觉映射(VisualMap) #

连续型 #

javascript
visualMap: {
  type: 'continuous',  // 'continuous', 'piecewise'
  
  // 最小值、最大值
  min: 0,
  max: 100,
  
  // 颜色映射
  inRange: {
    color: ['#50a3ba', '#eac736', '#d94e5d']
  },
  
  // 显示位置
  left: 'left',
  top: 'bottom',
  
  // 文本
  text: ['高', '低'],
  
  // 是否显示手柄
  calculable: true,
  
  // 尺寸
  itemWidth: 20,
  itemHeight: 140
}

分段型 #

javascript
visualMap: {
  type: 'piecewise',
  
  // 分段定义
  pieces: [
    { min: 0, max: 20, label: '0-20', color: '#c6e48b' },
    { min: 20, max: 40, label: '20-40', color: '#7bc96f' },
    { min: 40, max: 60, label: '40-60', color: '#239a3b' },
    { min: 60, max: 80, label: '60-80', color: '#196127' },
    { min: 80, label: '80+', color: '#08306b' }
  ],
  
  // 显示位置
  left: 'left',
  top: 'bottom',
  
  // 布局方向
  orient: 'vertical',  // 'horizontal', 'vertical'
  
  // 是否显示分段标签
  showLabel: true
}

事件系统 #

鼠标事件 #

javascript
// 点击事件
chart.on('click', function(params) {
  console.log(params.name, params.value);
});

// 双击事件
chart.on('dblclick', function(params) {});

// 鼠标移入
chart.on('mouseover', function(params) {});

// 鼠标移出
chart.on('mouseout', function(params) {});

组件事件 #

javascript
// 图例选择变化
chart.on('legendselectchanged', function(params) {
  console.log(params.selected);
});

// 数据区域缩放
chart.on('datazoom', function(params) {
  console.log(params.start, params.end);
});

// 刷选
chart.on('brushSelected', function(params) {});

// 地图区域选中
chart.on('geoselectchanged', function(params) {});

自定义事件 #

javascript
// 触发高亮
chart.dispatchAction({
  type: 'highlight',
  seriesIndex: 0,
  dataIndex: 1
});

// 触发显示提示框
chart.dispatchAction({
  type: 'showTip',
  seriesIndex: 0,
  dataIndex: 1
});

// 触发数据区域缩放
chart.dispatchAction({
  type: 'dataZoom',
  start: 20,
  end: 80
});

动画效果 #

入场动画 #

javascript
option = {
  animation: true,
  animationThreshold: 2000,  // 动画阈值
  animationDuration: 1000,   // 动画时长
  animationEasing: 'cubicOut',  // 缓动效果
  animationDelay: 0,         // 动画延迟
  
  // 或使用函数
  animationDelay: function(idx) {
    return idx * 100;
  }
};

更新动画 #

javascript
option = {
  animationDurationUpdate: 300,
  animationEasingUpdate: 'cubicInOut'
};

缓动效果 #

javascript
// 可用的缓动效果
animationEasing: 'linear';
animationEasing: 'quadraticIn';
animationEasing: 'quadraticOut';
animationEasing: 'quadraticInOut';
animationEasing: 'cubicIn';
animationEasing: 'cubicOut';
animationEasing: 'cubicInOut';
animationEasing: 'elasticIn';
animationEasing: 'elasticOut';
animationEasing: 'elasticInOut';
animationEasing: 'bounceIn';
animationEasing: 'bounceOut';
animationEasing: 'bounceInOut';

交互最佳实践 #

1. 合理的提示框 #

javascript
tooltip: {
  trigger: 'axis',
  confine: true,  // 限制在图表区域内
  transitionDuration: 0.2
}

2. 响应式交互 #

javascript
// 根据屏幕尺寸调整
const isMobile = window.innerWidth < 768;

option = {
  tooltip: {
    triggerOn: isMobile ? 'click' : 'mousemove'
  },
  dataZoom: isMobile ? [{
    type: 'inside'
  }] : [{
    type: 'slider'
  }]
};

3. 性能优化 #

javascript
// 大数据量时关闭动画
option = {
  animation: data.length < 1000,
  animationThreshold: 2000
};

下一步 #

现在你已经掌握了交互功能,接下来学习 主题样式,了解如何定制图表的外观!

最后更新:2026-03-28