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

Chart.js如何将坐标轴与刻度分别渲染到独立canvas画布中

实现方案

你可以通过创建两个仅渲染坐标轴的独立Chart实例,和主图表保持刻度、范围、尺寸完全同步来实现需求,具体实现步骤如下:

  • 第一步:尺寸同步
    保证Y轴画布price_bar_canvas的高度与主图表高度完全一致,X轴画布time_bar_canvas的宽度与主图表宽度完全一致,避免刻度错位。
  • 第二步:创建Y轴独立图表实例
    仅配置Y轴显示,隐藏所有其他元素(图例、提示框、网格、绘图区等),刻度规则完全复用主图表Y轴配置,同步主图表的Y轴数值范围。
  • 第三步:创建X轴独立图表实例
    仅配置X轴显示,隐藏所有其他元素,刻度规则、时间格式完全复用主图表X轴配置,同步主图表的X轴时间范围。
  • 第四步:联动更新逻辑
    主图表触发resize、缩放、平移、数据更新时,同步更新两个坐标轴实例的轴范围,调用update()方法保持和主图表对齐。
完整修改后的JS代码示例
// 提前声明坐标轴实例,方便全局调用
let yAxisChart, xAxisChart, myChart;

async function chartit(){
    await fetchData();
    var data ={
        datasets:[{
            data:each_data,
        }]
    };

    var options = {
        onResize: resize(),
        responsive: true,
        maintainAspectRatio: false,
        plugins:{
            legend: {
                display: false,
            },
            // 新增主图表更新后同步坐标轴的钩子
            afterUpdate: function(chart) {
                // 同步Y轴范围并更新
                if(yAxisChart) {
                    yAxisChart.scales.y.min = chart.scales.y.min;
                    yAxisChart.scales.y.max = chart.scales.y.max;
                    yAxisChart.update('none'); // 加none参数避免动画抖动
                }
                // 同步X轴范围并更新
                if(xAxisChart) {
                    xAxisChart.scales.x.min = chart.scales.x.min;
                    xAxisChart.scales.x.max = chart.scales.x.max;
                    xAxisChart.update('none');
                }
            }
        },
        scales: {
            y: {
                grid:{
                    drawBorder:false,
                    display: true,
                },
                ticks: {
                    display: false,
                    callback: function(val) {
                        return val;
                    },
                },
                position: 'right',
            },
            x:{
                type: 'time',
                display:false,
                grid:{
                    display: false,
                },
                ticks: {
                    display: true,
                    callback: function(val, index) {
                        if(!(index%5))return val;
                    },
                },
            }
        },
    };

    myChart = new Chart(document.getElementById('main_chart'), {
        type: 'candlestick',
        options: options,
        data: data
    });

    // 初始化Y轴(价格轴)独立实例
    yAxisChart = new Chart(document.getElementById('price_bar_canvas'), {
        type: 'line',
        data: { datasets: [] },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: { display: false },
                tooltip: { enabled: false }
            },
            scales: {
                x: { display: false },
                y: {
                    position: 'right',
                    grid: { display: false },
                    // 完全复用主图表Y轴刻度配置
                    ticks: {
                        callback: function(val) {
                            return val;
                        }
                    },
                    // 初始同步主图表Y轴范围
                    min: myChart.scales.y.min,
                    max: myChart.scales.y.max
                }
            }
        }
    });

    // 初始化X轴(时间轴)独立实例
    xAxisChart = new Chart(document.getElementById('time_bar_canvas'), {
        type: 'line',
        data: { datasets: [] },
        options: {
            responsive: true,
            maintainAspectRatio: false,
            plugins: {
                legend: { display: false },
                tooltip: { enabled: false }
            },
            scales: {
                y: { display: false },
                x: {
                    type: 'time',
                    grid: { display: false },
                    // 完全复用主图表X轴刻度配置
                    ticks: {
                        callback: function(val, index) {
                            if(!(index%5))return val;
                        }
                    },
                    // 初始同步主图表X轴范围
                    min: myChart.scales.x.min,
                    max: myChart.scales.x.max
                }
            }
        }
    });
}
注意事项
  • 需保证Y轴容器的高度和主图表容器高度完全一致,X轴容器的宽度和主图表容器宽度完全一致,可通过CSS强制设置宽高对齐
  • 如果主图表支持缩放平移功能,需同步在缩放事件触发时调用两个坐标轴实例的update()方法
  • 代码中的update('none')参数是为了关闭坐标轴更新时的动画,避免和主图表不同步产生抖动

内容的提问来源于stack exchange,提问作者Avichal Jain

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 14:24:00