Chart.jscanvasresize

在( Android WebView HTML5canvas错误 )我发布了一个关于使用Graph.js库绘制图的问题。 我现在遇到的问题是,如果我多次调用绘制graphics的函数,canvas每次都会resize。 每次graphics重绘到同一个canvas时,其大小也会改变。 我也尝试设置canvas的大小,但没有成功。

可能是什么原因? 为什么canvas每次resize?

我遇到了很多问题,因为在鼠标hover的时候,我的线条看起来很糟糕,而且我发现了一个更简单的方法,希望这会有所帮助:)

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, 

发生了什么事是Chart.js在调用时将canvas大小放大,然后尝试使用CSS将其缩小,目的是为高dpi设备提供更高分辨率的graphics。

问题是,它没有意识到它已经做到了这一点,所以当连续调用时,它将已经(加倍或不pipe)大小再次乘以直到事情开始中断。 (实际发生的是检查是否应该通过改变DOM属性的宽度和高度来增加更多的像素到canvas,如果它应该乘以一些因素,通常是2,然后改变它,然后改变CSS样式属性在页面上保持相同的大小。)

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

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

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

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

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

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

这适用于我:

 <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标签中设置canvas的大小。

正如jcmiller11build议,设置宽度和高度有帮助。 稍微好一点的解决scheme是在绘制图表之前检索canvas的宽度和高度。 然后使用这些数字在图表的每个后续重绘上设置图表。 这确保在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); } 

我有一个类似的问题,并find你的答案..我最终来到一个解决scheme。

它看起来像Chart.js的来源有以下(可能是因为它不应该重新呈现,并在同一canvas中完全不同的图):

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

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

希望有所帮助!

我有使用Angular CLI的同类缩放问题。 能够通过从index.html中删除这一行来得到它的工作:

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

然后在angular-cli.json文件的脚本部分使用:

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

资料来源 :mikebarr58

如果有人有问题,我find了一个解决scheme,不涉及牺牲响应等

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

例:

HTML:

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

JS:

 $("#chartContainer").html('<canvas id="myChart"></canvas>'); //call new Chart() as usual 
  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);