【问题标题】:How to fix size of mixed chart with bubble chart in Chart.js?如何在 Chart.js 中使用气泡图修复混合图表的大小?
【发布时间】:2022-01-19 11:13:39
【问题描述】:

我正在使用Chart.js 3.7.0 实现一个混合了bubble 和bar 图表的图表。

为了防止canvas调整大小,我将大小值保存在canvas标签中,并修改选项值如下。也就是说,我们希望canvas 具有固定大小。

HTML 标记

<canvas id="mixed_graph_canvas" width="1320" height="685"></canvas>

选项

options : {
   responsive : false,
   maintainAspectRation : false
}

但是,如果您修改bubble 图表的y、r 值,canvas 的大小会发生如下变化。

当bubble图表中的值为0、0、20时

...
{
   x : 0,
   y : 0,
   z : 20
}

当bubble图表中的值为0、80、50时

... 
{
   x : 0,
   y : 80,
   r : 50
}

这是绘制上述图表的完整源代码。

const chartData = {
        labels   : [
            '', 
            '0,0~49,10',
            '0,50~74,10',
            '0,75~99,10',
            '0,100~124,10',
            '0,125~149,10',
            '0,150~174,10',
            '0,175~199,10',
            '0,200~229,10',
            '0,230,10',
            ''
        ],
        datasets : [
            {
                type            : 'bar',
                label           : '',
                data            : [0, 50, 50, 50, 50, 50, 50, 50, 50, 50, 0],
                backgroundColor : 'rgba(241, 246, 0, 1)',
                borderColor     : 'rgba(241, 246, 0, 1)',
                borderWidth     : 0.1,
                barPercentage   : 0.05,
                order           : 1
            },
            {
                type : 'bubble',
                data : [
                    {   
                        x : 0,
                        y : 0,
                        r : 0
                    },
                    {   
                        x : 0,
                        y : 0,
                        r : 20
                    },
                    {   
                        x : 0,
                        y : 50,
                        r : 20
                    },
                    {   
                        x : 0,
                        y : 0,
                        r : 20
                    },
                    {   
                        x : 0,
                        y : 0,
                        r : 20
                    },
                    {   
                        x : 0,
                        y : 0,
                        r : 20
                    },
                    {   
                        x : 0,
                        y : 0,
                        r : 20
                    },
                    {   
                        x : 0,
                        y : 0,
                        r : 20
                    },
                    {   
                        x : 0,
                        y : 0,
                        r : 20
                    },
                    {   
                        x : 0,
                        y : 0,
                        r : 20
                    },
                    {   
                        x : 0,
                        y : 0,
                        r : 0
                    }
                ],
                backgroundColor : 'rgba(148, 181, 115, 0.7)',
                borderColor     : 'rgba(228, 248, 188, 0.92)',
                order           : 2
            }
        ]
    };

    const chartConfig = {
        type    : 'bar',
        data    : chartData,
        options : {
            responsive          : false,
            maintainAspectRatio : false,
            plugins             : {
                legend          : {
                    display : false
                },
                chartAreaBorder : {
                    borderColor : 'rgba(255, 255, 255, 0.2)',
                    borderWidth : 2
                },
                tooltip         : {
                    titleFont     : {
                        size : 24
                    },
                    bodyFont      : {
                        size : 14
                    },
                    footerFont    : {
                        size : 0
                    },
                    titleAlign    : 'center',
                    bodyAlign     : 'left',
                    borderColor   : 'rgba(119, 119, 119, 0.9)',
                    borderWidth   : 1,
                    displayColors : false,
                    filter        : function(tooltipItem) {
                        return tooltipItem.datasetIndex === 0;
                    },
                    callbacks     : {
                        title : function(tooltipItem) {
                            let percentage = tooltipItem[0].label.split(',');

                            return percentage[0] + '%';
                        },
                        label : function(tooltipItem) {
                            let percentage = tooltipItem.label.split(',');
                            let distance   = percentage[1];

                            return `Distance ${distance}m`;
                        },
                        afterLabel : function(tooltipItem) {
                            let percentage = tooltipItem.label.split(',');
                            let targetSize = percentage[2];

                            return `Target     ${targetSize}m`;
                        }
                    }
                }
            },
            scales              : {
                x  : {
                    display  : false,
                    position : 'bottom',
                    max      : 100,
                    min      : 0,
                    ticks    : {
                        beginAtZero : true,
                        stepSize    : 10,
                        callback    : () => ('')
                    },
                    grid     : {
                        drawTicks   : false,
                        color       : 'rgba(255, 255, 255, 0.2)',
                        borderWidth : 2
                    }
                },
                y  : {
                    position : 'left',
                    max      : 100,
                    min      : 0,
                    ticks : {
                        display     : false,
                        stepSize    : 5,
                        beginAtZero : true,
                        callback    : () => ('')
                    },
                    grid  : {
                        color            : 'rgba(255, 255, 255, 0.2)',
                        drawTicks        : false,
                        drawBorder       : true,
                        borderDash       : [5, 5],
                        borderDashOffset : 2,
                        borderWidth      : 2,
                        lineWidth        : context => context.index % 5 ? 1 : 0
                    }
                },
                y2 : {
                    max   : 100,
                    min   : 0,
                    ticks : {
                        display  : false,
                        stepSize : 25
                    },
                    grid  : {
                        drawTicks  : false,
                        drawBorder : false,
                        color      : 'rgba(255, 255, 255, 0.2)'
                    }
                }
            },
            interaction         : {
                mode            : 'index',
                position        : 'custom',
                xAlign          : 'center',
                yAlign          : 'bottom',
                backgroundColor : 'rgba(85, 85, 85, 0.9)'
            },
            datasets            : {
                bubble : {
                    responsive          : false,
                    maintainAspectRatio : false,
                    elements  : {
                        point : {
                            radius : function(context) {
                                const size = context.chart.width;
                                const base = Math.abs(context.raw.v) / 1000;

                                return (size / 24) * base;
                            }
                        }
                    },
                    animation : {
                        easing   : 'linear',
                        duration : 1000,
                        x : {
                            from : true
                        }
                    }
                }
            }
        },
        plugins : [chartAreaBorder]
    };

    const distanceAccuracyMixedChart = new Chart(context, chartConfig);

即使bubble 值更改或bar 值更改,如何修改canvas 以具有固定的canvas 大小?

即使数据集中的值发生变化,我也希望使用1320px 宽和685px 垂直的固定值绘制canvas。

【问题讨论】:

    标签: javascript canvas chart.js chart.js3


    【解决方案1】:

    下面的图表options 似乎是一个不错的方法。

    options : {
       responsive : false,
       maintainAspectRation : false,
       ...
    }
    

    您还可以尝试在div 元素中包含canvas,并在canvas 中省略width 和height。

    <div class="chart-container">
      <canvas id="mixed_graph_canvas"></canvas>
    </div>
    

    那么你需要定义如下CSS。

    .chart-container {
      width: 1320px;
      height: 685px;  
    }
    
    #mixed_graph_canvas {
      width: 100%;
      height: 100%;
    } 
    

    【讨论】:

    • 感谢您的发言。但是,只要气泡的值发生变化,“Y”轴的高度就会调整大小。我对画布样式代码做了!important,但问题仍然存在。
    【解决方案2】:

    如果将canvas 包装在div 中无法解决问题,或者如果响应选项不起作用,那么下面的options 可能会给您想要的结果。

    options : {
      responsive : false,
      maintainAspectRatio : false,
      layout : {
        autoPadding : false
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2018-03-30
      • 2011-12-23
      • 2022-01-13
      • 2018-05-03
      • 2016-10-17
      • 2018-06-13
      • 1970-01-01
      • 1970-01-01
      • 2015-05-10
      相关资源
      最近更新 更多