使用chartjs,如何定义canvas的相对宽度和高度?

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

使用

Chart.js
版本 4.2.0,我尝试在 Windows 11 上的最大化窗口上显示图表,其中图表高度为屏幕高度的 100%,图表宽度为屏幕宽度的 80%。

我尝试使用以下代码

<body>
    <div height="100%" width="80%">
        <canvas id="canvas">

但是这个简单的属性并不能完成任务。

终于找到这个解决方案了

<body>
    <div>
        <canvas id="canvas">
        </canvas>
    </div>

, options:
    { responsive: true
    , maintainAspectRatio: true
    , aspectRatio: 1.65

var ctx = document.getElementById("canvas").getContext("2d");
var myChart = new Chart(ctx, config);
myChart.canvas.parentNode.style.width = '80%';

这可以正常工作,但有点棘手,因为

width
(不是
height
)是在 Javascript 代码中动态设置的,并且
aspectRatio
必须在
options
中手动修复。

是否有一个简单的解决方案来将宽度定义为屏幕的 80%,将高度定义为屏幕的 100%?

我当前的屏幕尺寸是1920x1080。

我得到的是

当我在选项中抑制

aspectRatio
时,我得到以下图表

css chart.js
2个回答
1
投票

chart.js 绘图用 css 中设置的尺寸填充特定区域的标准方法似乎是执行以下操作:

  • 将画布包含在不包含任何其他内容的div中

  • 按照 div 的样式设置大小,而不是画布(这已经在代码中完成了)

  • 至少有一种以绝对单位表示的尺寸(这两种尺寸都不是

    %
    ) - 根据您的情况

      <div style="height:100vh; width:80vw">
          <canvas id="myChart"></canvas>
      </div>
    

    另请参阅文档中的此评论

  • 设置图表选项

    maintainAspectRatio: false
    responsive: true
    - 后者用于在调整窗口大小时重新绘制图表。

这是执行这些操作的代码片段,包括我编写的一个插件,用于显示画布、div 和窗口的当前大小

const plugin = {
    id: 'canvasSizeMonitor',
    currentWidth: 0,
    currentHeight: 0,
    resizing: false,
    
    displaySizes(chart){
        const canvas = chart.canvas,
            div = canvas.parentElement;
        document.querySelector('#sizes').innerText+=
            `div: ${div.offsetWidth}x${div.offsetHeight}\n`+
            `canvas: ${canvas.offsetWidth}x${canvas.offsetHeight}\n`+
            `window:${window.innerWidth}x${window.innerHeight}\n`+
            `0.8 * ${window.innerWidth} = ${Math.round(0.8*window.innerWidth)}\n`+
            '---------\n'//`aspRatio: ${chart.options.aspectRatio.toFixed(3).replace(/[.]?0*$/, '')}\n\n`;
    },
    
    afterRender(chart){
        if(!plugin.resizing &&
            (chart.canvas.offsetWidth !== plugin.currentWidth ||
                chart.canvas.offsetHeight !== plugin.currentHeight)){
            plugin.resizing = true;
            setTimeout(
                function(){
                    plugin.resizing = false;
                    plugin.currentWidth = chart.canvas.offsetWidth;
                    plugin.currentHeight = chart.canvas.offsetHeight;
                    plugin.displaySizes(chart);
                }, 500
            )
        }
    }
};


chart = new Chart(document.getElementById("myChart"), {
    type: 'line',
    data: {
        datasets: Array.from({length: 8}, (_, i)=>({
            label: `k = ${i+1}`,
            data: Array.from({length: 100}, (_, j)=>({
                x: j/50, y: Math.exp(-j/10)*Math.cos((i+1)*j*Math.PI/100)
            }))
        }))
    },
    options: {
        parsing: {
            xAxisKey: 'x',
            yAxisKey: 'y'
        },
        pointStyle: false,
        borderWidth: 1,
        
        responsive: true,
        maintainAspectRatio: false,
        //aspectRatio: 1,
        scales: {
            x: {
                type: 'linear',
                grid: {
                    drawOnChartArea: true,
                    lineWidth: 1
                },
                border:{
                    color: '#000',
                },
                ticks: {
                    display: true,
                    color: '#000',
                    padding: 10
                },
                title: {
                    display: true,
                    text: 'x',
                    align: 'end'
                }
            },
            y: {
                type: 'linear',
                ticks: {
                    padding: 10,
                    color: '#000',
                },
                grid: {
                    drawOnChartArea: true,
                    lineWidth: 1
                },
                border:{
                    color: '#000',
                },
                title: {
                    display: true,
                    text: 'f[k](x)',
                    align: 'end'
                }
            }
        },
        plugins:{
            legend:{
                position: 'right'
            }
        },
        animation: {duration: 0}
    },
    plugins: [plugin]
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.1.2/chart.umd.js"
        integrity="sha512-t41WshQCxr9T3SWH3DBZoDnAT9gfVLtQS+NKO60fdAwScoB37rXtdxT/oKe986G0BFnP4mtGzXxuYpHrMoMJLA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

<body style="margin: 0">

<pre id="sizes" style="position: absolute; top: 0; right: 10px; text-align: right;background-color:rgba(255, 200, 100,0.4)"></pre>

<div style="height:100vh; width:80vw; padding:0; margin: 0; background: red">
<canvas style="background: #ddd" id="myChart"></canvas>
</div>

</body>


0
投票

这个答案是我将 Chartjs 从 v3.9 更新到 4.4 后从 google 得到的第一个答案,所以我想我应该添加一个 CSS 示例,以防也对某人有帮助。

在 CSS 中:

.chart-container {
    position: relative;
    height: 100vh;
    width: 80%;
} 

使用“chart-container”类在特定的div中添加chartjs画布,该类的CSS属性在您的css文件中定义。

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

在您的 Chartjs 选项新图表中,确保添加“maintainAspectRatio: false” 因为默认值为 true 根据文档:

Note that in order for the above code to correctly resize the chart height, the maintainAspectRatio option must also be set to false.

...=new Chart(canvas_id,
{
    type:'line',
    data:{},
    options: {
            responsive: true,
            maintainAspectRatio: false,
            }
}
);
© www.soinside.com 2019 - 2024. All rights reserved.