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

ECharts蜡烛图鼠标拖动时K线被截断的问题求助

ECharts蜡烛图拖动时K线截断问题解决

蜡烛图拖动截断效果演示

问题描述

使用ECharts实现蜡烛图鼠标拖动功能时,拖动图表K线会被截断,期望实现类似TradingView的效果:拖动或缩放时,即使K线部分超出视野也不会被截断。

问题原因及解决方案

  1. dataZoom配置笔误:第二个inside类型的dataZoom中,xAxisIndexA是错误属性名,需改为xAxisIndex: 0,否则x轴拖动控制不生效。
  2. xAxis边界设置冲突:xAxis设置的min: 'dataMin'和max: 'dataMax'会强制显示全部数据范围,与dataZoom的控制逻辑冲突,需移除这两个配置。
  3. 边界间隙调整:将xAxis的boundaryGap设为true(或[0.02, 0.02]这类数值),给边缘K线留出显示空间,避免被容器边缘截断。

修改后的完整代码

var dom = document.getElementById('chart-container');
var myChart = echarts.init(dom, null, {
    renderer: 'canvas',
    useDirtyRect: false
});
var app = {};
var option;
const upColor = '#ec0000';
const upBorderColor = '#8A0000';
const downColor = '#00da3c';
const downBorderColor = '#008F28';
// Each item: open,close,lowest,highest
const data0 = splitData([
    ['2013/1/24', 2320.26, 2320.26, 2287.3, 2362.94],
    ['2013/1/25', 2300, 2291.3, 2288.26, 2308.38],
    ['2013/1/28', 2295.35, 2346.5, 2295.35, 2346.92],
    ['2013/1/29', 2347.22, 2358.98, 2337.35, 2363.8],
    ['2013/1/30', 2360.75, 2382.48, 2347.89, 2383.76],
    ['2013/1/31', 2383.43, 2385.42, 2371.23, 2391.82],
    /*...  完整数据请参考原代码 */
]);

function splitData(rawData) {
    const categoryData = [];
    const values = [];
    for (var i = 0; i < rawData.length; i++) {
        categoryData.push(rawData[i].splice(0, 1)[0]);
        values.push(rawData[i]);
    }
    return {
        categoryData: categoryData,
        values: values
    };
}

function calculateMA(dayCount) {
    var result = [];
    for (var i = 0, len = data0.values.length; i < len; i++) {
        if (i < dayCount) {
            result.push('-');
            continue;
        }
        var sum = 0;
        for (var j = 0; j < dayCount; j++) {
            sum += +data0.values[i - j][1];
        }
        result.push(sum / dayCount);
    }
    return result;
}
option = {
    title: {
        text: '上证指数',
        left: 0
    },
    tooltip: {
        trigger: 'axis',
        axisPointer: {
            type: 'cross'
        }
    },
    legend: {
        data: ['日K', 'MA5', 'MA10', 'MA20', 'MA30']
    },
    grid: {
        left: '10%',
        right: '10%',
        bottom: '15%'
    },
    xAxis: {
        type: 'category',
        data: data0.categoryData,
        boundaryGap: true,
        axisLine: {
            onZero: false
        },
        splitLine: {
            show: false
        },
        clip: false
    },
    yAxis: {
        type: 'value',
        scale: true,
        splitArea: {
            show: true
        },
        boundaryGap: false,
        clip: false,
    },
    dataZoom: [{
        type: 'inside',
        start: 50,
        clip: false,
        end: 100,
        zoomLock: true,
        zoomOnMouseWheel: true,
        moveOnMouseMove: true,
        moveOnMouseWheel: false,
        yAxisIndex: 0
    }, {
        type: 'inside',
        start: 50,
        clip: false,
        end: 100,
        zoomOnMouseWheel: true,
        moveOnMouseMove: true,
        moveOnMouseWheel: false,
        xAxisIndex: 0 // 修正笔误
    }, {
        show: true,
        type: 'slider',
        top: '90%',
        start: 50,
        end: 100
    }],
    series: [{
        name: '日K',
        type: 'candlestick',
        clip: false,
        data: data0.values,
        itemStyle: {
            color: upColor,
            color0: downColor,
            borderColor: upBorderColor,
            borderColor0: downBorderColor
        },
        markPoint: {
            label: {
                formatter: function(param) {
                    return param != null ? Math.round(param.value) + '' : '';
                }
            },
            data: [{
                name: 'Mark',
                coord: ['2013/5/31', 2300],
                value: 2300,
                itemStyle: {
                    color: 'rgb(41,60,85)'
                }
            }, {
                name: 'highest value',
                type: 'max',
                valueDim: 'highest'
            }, {
                name: 'lowest value',
                type: 'min',
                valueDim: 'lowest'
            }, {
                name: 'average value on close',
                type: 'average',
                valueDim: 'close'
            }],
            tooltip: {
                formatter: function(param) {
                    return param.name + '<br>' + (param.data.coord || '');
                }
            }
        },
        markLine: {
            symbol: ['none', 'none'],
            data: [
                [{
                    name: 'from lowest to highest',
                    type: 'min',
                    valueDim: 'lowest',
                    symbol: 'circle',
                    symbolSize: 10,
                    label: {
                        show: false
                    },
                    emphasis: {
                        label: {
                            show: false
                        }
                    }
                }, {
                    type: 'max',
                    valueDim: 'highest',
                    symbol: 'circle',
                    symbolSize: 10,
                    label: {
                        show: false
                    },
                    emphasis: {
                        label: {
                            show: false
                        }
                    }
                }], {
                    name: 'min line on close',
                    type: 'min',
                    valueDim: 'close'
                }, {
                    name: 'max line on close',
                    type: 'max',
                    valueDim: 'close'
                }
            ]
        }
    }, {
        name: 'MA5',
        type: 'line',
        data: calculateMA(5),
        smooth: true,
        lineStyle: {
            opacity: 0.5
        }
    }, {
        name: 'MA10',
        type: 'line',
        data: calculateMA(10),
        smooth: true,
        lineStyle: {
            opacity: 0.5
        }
    }, {
        name: 'MA20',
        type: 'line',
        data: calculateMA(20),
        smooth: true,
        lineStyle: {
            opacity: 0.5
        }
    }, {
        name: 'MA30',
        type: 'line',
        data: calculateMA(30),
        smooth: true,
        lineStyle: {
            opacity: 0.5
        }
    }]
};
if (option && typeof option === 'object') {
    myChart.setOption(option);
}
window.addEventListener('resize', myChart.resize);

内容的提问来源于stack exchange,提问作者Luiz Lucca

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 20:54:53