Html Chart.js 画布调整大小

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19847582/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 15:09:24  来源:igfitidea点击:

Chart.js canvas resize

htmlcanvaschart.js

提问by Jaka

In (Android WebView HTML5 canvas error) i posted a question regarding plotting graphs using Graph.js library. The problem i have now is that if i call the function to plot the graph multiple times, the canvas resizes every time. Each time the graph is redrawn to the same canvas, its size also changes. I also tried setting the size of the canvas but without success.

在(Android WebView HTML5 画布错误)中,我发布了一个关于使用 Graph.js 库绘制图形的问题。我现在遇到的问题是,如果我多次调用该函数来绘制图形,则画布每次都会调整大小。每次将图形重新绘制到同一画布上时,其大小也会发生变化。我也尝试设置画布的大小,但没有成功。

What could be the reason? Why does the canvas resize every time?

可能是什么原因?为什么画布每次都会调整大小?

回答by NoFlag

I had a lot of problems with that, because after all of that my line graphic looked terrible when mouse hovering and I found a simpler way to do it, hope it will help :)

我遇到了很多问题,因为毕竟当鼠标悬停时我的线条图形看起来很糟糕,我找到了一种更简单的方法来做到这一点,希望它会有所帮助:)

Use these Chart.js options:

使用这些 Chart.js 选项:

// Boolean - whether or not the chart should be responsive and resize when the browser does.

responsive: true,

// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container

maintainAspectRatio: false,

回答by jcmiller11

What's happening is Chart.js multiplies the size of the canvas when it is called then attempts to scale it back down using CSS, the purpose being to provide higher resolution graphs for high-dpi devices.

发生的事情是 Chart.js 在调用时乘以画布的大小,然后尝试使用 CSS 将其缩小,目的是为高 dpi 设备提供更高分辨率的图形。

The problem is it doesn't realize it has already done this, so when called successive times, it multiplies the already (doubled or whatever) size AGAIN until things start to break. (What's actually happening is it is checking whether it should add more pixels to the canvas by changing the DOM attribute for width and height, if it should, multiplying it by some factor, usually 2, then changing that, and then changing the css style attribute to maintain the same size on the page.)

问题是它没有意识到它已经这样做了,所以当连续调用时,它会再次乘以已经(加倍或其他)的大小,直到事情开始破裂。(实际发生的事情是检查它是否应该通过更改宽度和高度的 DOM 属性来向画布添加更多像素,如果应该,将其乘以某个因子,通常为 2,然后更改它,然后更改 css 样式属性以在页面上保持相同的大小。)

For example, when you run it once and your canvas width and height are set to 300, it sets them to 600, then changes the style attribute to 300... but if you run it again, it sees that the DOM width and height are 600 (check the other answer to this question to see why) and then sets it to 1200 and the css width and height to 600.

例如,当您运行一次并且您的画布宽度和高度设置为 300 时,它会将它们设置为 600,然后将样式属性更改为 300...但是如果您再次运行它,它会看到 DOM 的宽度和高度是 600(检查这个问题的另一个答案以了解原因),然后将其设置为 1200,并将 css 宽度和高度设置为 600。

Not the most elegant solution, but I solved this problem while maintaining the enhanced resolution for retina devices by simply setting the width and height of the canvas manually before each successive call to Chart.js

不是最优雅的解决方案,但我解决了这个问题,同时通过在每次连续调用 Chart.js 之前手动设置画布的宽度和高度来保持视网膜设备的增强分辨率

var ctx = document.getElementById("canvas").getContext("2d");
ctx.canvas.width = 300;
ctx.canvas.height = 300;
var myDoughnut = new Chart(ctx).Doughnut(doughnutData);

回答by Patrick Pirzer

This works for me:

这对我有用:

<body>
    <form>
        [...]
        <div style="position:absolute; top:60px; left:10px; width:500px; height:500px;">
            <canvas id="cv_values"></canvas>

            <script type="text/javascript">
                var indicatedValueData = {
                    labels: ["1", "2", "3"],
                    datasets: [
                        {
                            [...]
                        };

                var cv_values = document.getElementById("cv_values").getContext("2d");
                var myChart = new Chart(cv_values, { type: "line", data: indicatedValueData });
            </script>
        </div>
    </form>
</body>

The essential fact is that we have to set the size of the canvas in the div-tag.

基本事实是我们必须在 div-tag 中设置画布的大小。

回答by Pradeep Rajashekar

In IOS and Android the browser hides the toolbar when you are scrolling, thereby changing the size of the window which inturn lead chartjs to resize the graph. The solution is to maintain the aspect ratio.

在 IOS 和 Android 中,浏览器在滚动时隐藏工具栏,从而改变窗口的大小,从而导致 chartjs 调整图形大小。解决办法是保持纵横比。

var options = { 
    responsive: true,
    maintainAspectRatio: true
}

This should solve your problem.

这应该可以解决您的问题。

回答by Anon

As jcmiller11 suggested, setting the width and height helps. A slightly nicer solution is to retrieve the width and height of the canvas before drawing the chart. Then using those numbers for setting the chart on each subsequent re-draw of the chart. This makes sure there are no constants in the javascript code.

正如 jcmiller11 建议的那样,设置宽度和高度有帮助。一个更好的解决方案是在绘制图表之前检索画布的宽度和高度。然后使用这些数字在每次重新绘制图表时设置图表。这确保了 javascript 代码中没有常量。

ctx.canvas.originalwidth = ctx.canvas.width;
ctx.canvas.originalheight = ctx.canvas.height;

function drawchart() {
    ctx.canvas.width = ctx.canvas.originalwidth;
    ctx.canvas.height = ctx.canvas.originalheight;

    var chartctx = new Chart(ctx);
    myNewBarChart = chartctx.Bar(data, chartSettings); 
}

回答by truefusion

I had to use a combination of multiple answers here with some minor tweaks.

我不得不在这里使用多个答案的组合,并进行一些小的调整。

First, it is necessarythat you wrap the canvas element within a block-level container. I say to you, do notlet the canvas element have any siblings; let it be a lonely child, for it is stubbornand spoiled. (The wrapper may not need any sizing restrictions placed on it, but for safety it may be good to have a max-height applied to it.)

首先,有必要将画布元素包装在块级容器中。我对你说,千万不能让canvas元素有兄弟姐妹; 让它成为一个孤独的孩子,因为它是固执被宠坏的。(包装纸可能不需要任何尺寸限制,但为了安全起见,对它应用最大高度可能会很好。)

After assuring that the previous conditions are met, when initiating the chart, make sure the following options are used:

在确保满足前面的条件后,在启动图表时,请确保使用以下选项:

var options = { 
    "responsive": true,
    "maintainAspectRatio": false
}

If you want to adjust the height of the chart, do so at the canvas element level.

如果要调整图表的高度,请在画布元素级别进行。

<canvas height="500"></canvas>

Do not try to deal with the child in any other manner. This should result in a satisfyingly, properly laid-out chart, one that stays in its crib peacefully.

不要试图以任何其他方式与孩子打交道。这应该会产生一个令人满意的、布局合理的图表,一个安静地留在它的婴儿床里。

回答by yahfree

I had a similar problem and found your answer.. I eventually came to a solution.

我遇到了类似的问题并找到了您的答案。我最终找到了解决方案。

It looks like the source of Chart.js has the following(presumably because it is not supposed to re-render and entirely different graph in the same canvas):

看起来 Chart.js 的源代码如下(大概是因为它不应该在同一画布中重新渲染和完全不同的图形):

    //High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.
if (window.devicePixelRatio) {
    context.canvas.style.width = width + "px";
    context.canvas.style.height = height + "px";
    context.canvas.height = height * window.devicePixelRatio;
    context.canvas.width = width * window.devicePixelRatio;
    context.scale(window.devicePixelRatio, window.devicePixelRatio);
}

This is fine if it is called once, but when you redraw multiple times you end up changing the size of the canvas DOM element multiple times causing re-size.

如果它被调用一次,这很好,但是当您多次重绘时,您最终会多次更改画布 DOM 元素的大小,从而导致重新调整大小。

Hope that helps!

希望有帮助!

回答by Hiten Patel

I tried to Resize Canvas using jQuery but it din't work well. I think CSS3is the best option you can try on, if you want on hover zooming at certain level.

我尝试使用 jQuery 调整画布大小,但效果不佳。我认为CSS3是您可以尝试的最佳选择,如果您想在某个级别进行悬停缩放。

Following hover option from other codepan link:

以下来自其他 codepan 链接的悬停选项:

.style_prevu_kit:hover{
    z-index: 2;
    -webkit-transition: all 200ms ease-in;
    -webkit-transform: scale(1.5);
    -ms-transition: all 200ms ease-in;
    -ms-transform: scale(1.5);   
    -moz-transition: all 200ms ease-in;
    -moz-transform: scale(1.5);
    transition: all 200ms ease-in;
    transform: scale(1.5);
}

Follow my codepan link:

按照我的代码盘链接:

https://codepen.io/hitman0775/pen/XZZzqN

https://codepen.io/hitman0775/pen/XZZzqN

回答by fpscolin

If anyone is having problems, I found a solution that doesn't involve sacrificing responsiveness etc.

如果有人遇到问题,我找到了一个不涉及牺牲响应能力等的解决方案。

Simply wrap your canvas in a div container (no styling) and reset the contents of the div to an empty canvas with ID before calling the Chart constructor.

在调用 Chart 构造函数之前,只需将画布包装在 div 容器中(无样式),并将 div 的内容重置为带有 ID 的空画布。

Example:

例子:

HTML:

HTML:

<div id="chartContainer">
    <canvas id="myChart"></canvas>
</div>

JS:

JS:

$("#chartContainer").html('<canvas id="myChart"></canvas>');
//call new Chart() as usual

回答by Nova Qiu

I was having the same problem. I was able to solve it by setting option:

我遇到了同样的问题。我能够通过设置选项来解决它:

responsive: false,
maintainAspectRatio: true,
showScale: false,

And in css, set the width of the container div the same as the canvas:

并且在 css 中,将容器 div 的宽度设置为与画布相同:

    #canvasContainer { 
      width: 300px;
    }
    
    canvas {
      width: 300px;
    }