You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ECharts:time轴+empty过滤模式下缩放K线不增宽的解决方法

问题描述

在使用ECharts时,当同时配置以下参数时,缩放操作无法让candlestick(K线)宽度自动增加:

  • xAxis类型为time
  • dataZoom的filterMode设为empty
  • series类型为candlestick

完整复现代码如下:

JavaScript代码

var dom = document.getElementById("chart-container");
var myChart = echarts.init(dom);
var app = {};
var option;

// Generate time series data
const baseDate = new Date(2023, 0, 1);
const ohlcData = [];
const dateData = [];
let prevClose = 50;
const volatility = 0.02;
for (let i = 0; i < 300; i++) {
  const date = new Date(baseDate);
  date.setDate(date.getDate() + i);
  dateData.push(date);
  const dailyReturn =
    (Math.random() + Math.random() + Math.random() - 1.5) * volatility;
  const open = prevClose * (1 + (Math.random() - 0.5) * 0.001);
  const close = open * (1 + dailyReturn);
  const high = Math.max(open, close) * (1 + Math.random() * 0.005);
  const low = Math.min(open, close) * (1 - Math.random() * 0.005);
  ohlcData.push([open, close, low, high]);
  prevClose = close;
}

// Create chart
option = {
  xAxis: {
    type: "time",
  },
  yAxis: {
    type: "value",
    scale: true,
  },
  series: [
    {
      type: "candlestick",
      data: ohlcData.map((item, index) => [dateData[index], ...item]),
    },
  ],
  dataZoom: [
    {
      type: "inside",
      xAxisIndex: [0],
      filterMode: "empty",
    },
    {
      type: "slider",
      xAxisIndex: [0],
      filterMode: "empty",
    },
  ],
};

myChart.setOption(option);

CSS代码

* {
  margin: 0;
  padding: 0;
}

#chart-container {
  position: relative;
  height: 100vh;
  overflow: hidden;
}

HTML代码

<script src="https://fastly.jsdelivr.net/npm/echarts@5.5.1/dist/echarts.min.js"></script>

<div id="chart-container"></div>
问题原因

当dataZoom的filterMode设为empty时,ECharts不会过滤掉视野范围外的数据,只是将这些数据置为空白状态。图表仍会基于原始数据的总数量计算K线宽度,因此缩放时不会自动调整K线的宽度。

解决方案

通过监听ECharts的datazoom事件,实时计算当前可视范围内的K线数量,动态调整candlestick系列的barWidth属性,实现缩放时K线宽度自动适配。

修改后的JavaScript代码如下:

var dom = document.getElementById("chart-container");
var myChart = echarts.init(dom);
var app = {};
var option;

// Generate time series data
const baseDate = new Date(2023, 0, 1);
const ohlcData = [];
let prevClose = 50;
const volatility = 0.02;
for (let i = 0; i < 300; i++) {
  const date = new Date(baseDate);
  date.setDate(date.getDate() + i);
  const dailyReturn =
    (Math.random() + Math.random() + Math.random() - 1.5) * volatility;
  const open = prevClose * (1 + (Math.random() - 0.5) * 0.001);
  const close = open * (1 + dailyReturn);
  const high = Math.max(open, close) * (1 + Math.random() * 0.005);
  const low = Math.min(open, close) * (1 - Math.random() * 0.005);
  ohlcData.push([date, open, close, low, high]);
  prevClose = close;
}

// Create chart
option = {
  xAxis: {
    type: "time",
  },
  yAxis: {
    type: "value",
    scale: true,
  },
  series: [
    {
      type: "candlestick",
      data: ohlcData,
      barMaxWidth: 30,
      barMinWidth: 2
    },
  ],
  dataZoom: [
    {
      type: "inside",
      xAxisIndex: [0],
      filterMode: "empty",
    },
    {
      type: "slider",
      xAxisIndex: [0],
      filterMode: "empty",
    },
  ],
};

myChart.setOption(option);

// 监听datazoom事件,动态调整K线宽度
myChart.on('datazoom', function(params) {
  const xAxis = myChart.getModel().getComponent('xAxis', 0);
  const [startValue, endValue] = xAxis.axis.scale.getExtent();
  
  // 计算可视范围内的K线数量
  let visibleCount = 0;
  for (let i = 0; i < ohlcData.length; i++) {
    const itemTime = ohlcData[i][0].getTime();
    if (itemTime >= startValue && itemTime <= endValue) {
      visibleCount++;
    }
  }
  
  if (visibleCount === 0) return;
  
  // 根据可视数量计算合适的barWidth
  const chartWidth = dom.offsetWidth;
  const barWidth = Math.floor((chartWidth * 0.8) / visibleCount);
  
  // 更新K线宽度,限制在预设的最小/最大范围内
  myChart.setOption({
    series: [{
      barWidth: Math.max(option.series[0].barMinWidth, Math.min(option.series[0].barMaxWidth, barWidth))
    }]
  });
});
说明
  1. 通过datazoom事件获取当前x轴的可视区间,统计该区间内的有效K线数量;
  2. 基于图表宽度和可视K线数量计算合理的barWidth,同时用barMinWidth和barMaxWidth限制宽度范围,避免K线过窄或过宽;
  3. 调用setOption动态更新K线宽度,实现缩放时的自适应调整。

内容的提问来源于stack exchange,提问作者Xavier Patiño

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 22:29:57