Chart.js画布调整大小

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Chart.js画布调整大小相关的知识,希望对你有一定的参考价值。

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

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

答案

我遇到了很多问题,因为在鼠标悬停之后我的线条图看起来很糟糕,我找到了一种更简单的方法,希望它会有所帮助:)

使用这些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,
另一答案

我使用Angular CLI遇到了同样的扩展问题。能够通过从index.html中删除此行来使其工作:

<script src="node_modules/chart.js/dist/Chart.bundle.min.js"></script>

然后在angular-cli.json文件的scripts部分中,使用:

"scripts": ["../node_modules/chart.js/dist/Chart.bundle.min.js"]

Source:mikebarr58

另一答案
 let canvasBox = ReactDOM.findDOMNode(this.refs.canvasBox);
 let width = canvasBox.clientWidth;
 let height = canvasBox.clientHeight;
 let charts = ReactDOM.findDOMNode(this.refs.charts);
 let ctx = charts.getContext('2d');
 ctx.canvas.width = width;
 ctx.canvas.height = height;
 this.myChart = new Chart(ctx);
另一答案

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

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

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

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

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

这对我有用:

<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>

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

另一答案

iosandroid中,浏览器会在您滚动时隐藏工具栏,从而更改窗口的大小,该窗口会导致图表调整大小。解决方案是保持纵横比。

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

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

另一答案

正如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); 
}
另一答案

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

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

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

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

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

<canvas height="500"></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);
}

如果它被调用一次就没问题,但是当你多次重绘时,最终会多次改变画布DOM元素的大小,导致重新调整大小。

希望有所帮助!

另一答案

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

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

例:

HTML:

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

JS:

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

我尝试使用jQuery调整画布大小,但它不能很好地工作。我认为CSS3是你可以尝试的最佳选择,如果你想在某个级别悬停缩放。

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

.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);
}

按照我的代码链接:

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

以上是关于Chart.js画布调整大小的主要内容,如果未能解决你的问题,请参考以下文章

上传前调整图像大小 - 将画布转换为文件对象

在 Primeng Carousel 中放置 chart.js 圆环图时,画布内的文本似乎有点模糊/扭曲

如何在 Chart.js 2.9.3 中绘制具有动态厚度的水平条(在浏览器窗口高度调整大小时自动调整大小)?

如何在角度 chart.js 中更改画布高度和宽度

Storybook:更改控件的值不会重新呈现 Chart.js 画布

HTML5 响应式画布:调整浏览器画布绘制的大小消失