【问题标题】:Using chartjs, how to define relative width and height of canvas?使用chartjs,如何定义画布的相对宽度和高度?
【发布时间】:2023-02-03 01:27:51
【问题描述】:

使用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时,我得到了下图

【问题讨论】:

  • 根据我的经验,在 div 上设置 maintainAspectRatio: falseresponsive: true 和大小样式,而不是画布(就像您已经做的那样)——就像来自 here 的 html 代码一样,使画布填充 div,达到指定的大小. Here's a fiddle 为我做的,我写了一个插件来显示尺寸。我不确定它不依赖于浏览器/操作系统(我不在 Windows 上)。
  • 谢谢 !我的问题是使用“%”而不是“vh”或“vw”来定义相对高度或宽度。你的评论对我来说是一个很好的答案。小评论:我不会在你写的时候在画布上设置大小样式,而只会在父 div 上设置样式!为不同的 html 元素着色(如您所做)对解决问题非常有帮助。在浏览器中按 F11 也会显示我搜索的内容。
  • 1) 如果评论对您有效,我会将其移至答案,因为它可能与其他人相关 2) 它似乎适用于 100vh80%(虽然不是 %) 3) 我并没有说你设计画布的样式 - 通过“你已经我的意思是你已经设置了 div 的样式,所以这一点已经在你的代码中完成了,尽管我可以将括号短语移动到 div 之后。

标签: css chart.js


【解决方案1】:

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

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

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

  • 至少有一个绝对单位的尺寸,(不是在%) - 在你的情况下

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

    另请参阅文档中的this comment

  • 设置图表选项 maintainAspectRatio: falseresponsive: true - 后者用于在调整窗口大小时重新绘制图表。

这是执行这些操作的代码 sn-p,包括我编写的显示画布、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}
`+
            `canvas: ${canvas.offsetWidth}x${canvas.offsetHeight}
`+
            `window:${window.innerWidth}x${window.innerHeight}
`+
            `0.8 * ${window.innerWidth} = ${Math.round(0.8*window.innerWidth)}
`+
            '---------
'//`aspRatio: ${chart.options.aspectRatio.toFixed(3).replace(/[.]?0*$/, '')}

`;
    },
    
    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>

【讨论】:

    猜你喜欢
    • 2020-08-30
    • 2018-06-21
    • 1970-01-01
    • 2011-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-14
    相关资源
    最近更新 更多