Chart.js 条形图中的数据集缩放,以便更好地进行比较

问题描述 投票:0回答:1

我使用 Chart.js 在同一个条形图上绘制两个数据集,以进行基于时间的比较(x 轴)。然而,我遇到了一个问题,一个图形的高度会被压缩或扩展以适应另一个图形的高度,从而很难有效地比较它们。

例如,下面的紫色图增加了 26 倍,而蓝色图仅增加了 5 倍。由于缩放,很难评估这些变化的影响,因为紫色图被挤压到蓝色图的高度。

我认为在第一个数据点处与蓝色图处于同一水平可能会有所帮助,但我担心数据仍然会被压缩以适合蓝色图的高度。

我可以调整特定的 Chart.js 设置或配置来提高这些数据集的可比性吗?

我的图表比例代码如下:

y: {
    beginAtZero: true,
    grid:  {
        display: false,
        drawBorder: false,
        drawOnChartArea: false,
     },
     ticks: {
        display: true,
     },
   },
},
y1: {
     beginAtZero: true,
     position: 'right',
     grid: {
        display: false,
        drawBorder: false,
        drawOnChartArea: false,
     },
     ticks: {
        display: true,
     },
   },
}

当前图表

Multi dataset bar chart

预期图表

enter image description here

javascript charts chart.js dataset bar-chart
1个回答
0
投票

没有一个 Chart.js 选项可以排列这些值,使得第一个柱形图 两个数据集高度相等,但可以通过计算轴的值来排列

max
动态:

function computeMax(which, data){
    // computes max for scale `which` (0 -> 'y', 1 -> 'y1') such that the first
    // bars of the two datasets have the same height
    const other = 1 - which,
        dataValues = data.datasets.map(dataset=>dataset.data),
        dataMax = dataValues.map(data => Math.max(...data)),
        firstToMax = dataValues.map((data, i) => data[0] / dataMax[i])
    if(firstToMax[which] > firstToMax[other]){
        return firstToMax[which]/firstToMax[other] * dataMax[which];
    }
    else{
        return dataMax[which];
    }
}

scriptable
调用函数 computeMax
max
每个轴的属性,如下所示:

options: {
    ........... other options
    scales: {
        y: {
            .......... other y axis options
             ticks: {
                 display: true,
                 includeBounds: false
             },
             max: ({chart}) => computeMax(0, chart.data)
        },
        y1: {
            .......... other y1 axis options
            ticks: {
                 display: true,
                 includeBounds: false
             },
             max: ({chart}) => computeMax(1, chart.data)
        }
    }
}      

这是包含该代码段的片段:

function computeMax(which, data){
    // computes max for scale `which` (0 -> 'y', 1 -> 'y1') such that the first
    // bars of the two datasets have the same height
    const other = 1 - which,
        dataValues = data.datasets.map(dataset=>dataset.data),
        dataMax = dataValues.map(data => Math.max(...data)),
        firstToMax = dataValues.map((data, i) => data[0] / dataMax[i])
    if(firstToMax[which] > firstToMax[other]){
        return firstToMax[which]/firstToMax[other] * dataMax[which];
    }
    else{
        return dataMax[which];
    }
}


const config = {
    type: "bar",

    data: {
        labels: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
        datasets: [
            {
                label: 2023,
                data: [20, 65, 80, 102, 55, 56, 65, 59, 80, 81, 56, 55],
            },
            {
                label: 2024,
                data: [50, 59, 80, 81, 56, 55, 65, 108, 80, 81, 56, 55].map(x => x * 10),
                yAxisID: 'y1'
            },
        ]
    },

    options: {
        maintainAspectRatio: false,
        scales: {
            y: {
                grid: {
                    display: false,
                    drawBorder: false,
                    drawOnChartArea: false
                },
                ticks: {
                    display: true,
                    includeBounds: false
                },
                max: ({chart}) => computeMax(0, chart.data)
            },
            y1: {
                beginAtZero: true,
                position: 'right',
                grid: {
                    display: false,
                    drawBorder: false,
                    drawOnChartArea: false,
                },
                ticks: {
                    display: true,
                    includeBounds: false
                },
                max: ({chart}) => computeMax(1, chart.data)
            },
        }
    }
};

new Chart('myChart', config);
<div style="height: 300px">
    <canvas id="myChart">
    </canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

由于轴已设置

beginAtZero
true
,很明显,所有值都是 积极的。具有多个数据集并包含负值的概括 可以在这个小提琴中找到。

© www.soinside.com 2019 - 2024. All rights reserved.