可能的原因是什么?为什么画布每次都重新调整大小呢?
这个问题困扰了我很久,因为即使在鼠标悬停时我的折线图看起来很糟糕,但我找到了一种更简单的方法,希望能有所帮助 :)
请使用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在调用时会将画布的大小加倍,然后尝试使用CSS将其缩小,目的是为了为高分辨率设备提供更高分辨率的图表。
问题是它没有意识到自己已经这样做过了,因此当连续调用时,它会再次将已经(加倍或其他)大小乘以某个因子,直到出现问题。(实际上正在发生的是它正在检查是否应该通过更改宽度和高度的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标签中设置画布的大小。
var options = {
responsive: true,
maintainAspectRatio: true
}
这应该能解决你的问题。
在这里,我不得不使用多个答案的组合,并进行一些微调。
首先,必须将画布元素包裹在块级容器中。我告诉你,不要让画布元素有任何兄弟姐妹;让它成为孤独的孩子,因为它是 固执己见 和 被宠坏了。(包装器可能不需要放置任何尺寸限制,但出于安全考虑,最好对其应用最大高度。)
确认满足上述条件后,在启动图表时,请确保使用以下选项:
var options = {
"responsive": true,
"maintainAspectRatio": false
}
如果你想要调整图表的高度,请在画布元素层级进行操作。<canvas height="500"></canvas>
不要试图以任何其他方式处理孩子。这应该会产生一个令人满意且正确布置的图表,使其在婴儿床上保持安静。
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);
}
我遇到了类似的问题并找到了你的答案...最终我找到了解决方法。
看起来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元素的大小,引起重新调整大小。
希望这能有所帮助!
将选项设置为:
responsive: false,
maintainAspectRatio: true,
showScale: false,
并在HTML中使用canvas标签来创建画布。
#canvasContainer {
width: 300px;
}
canvas {
width: 300px;
}
在调整大小时,设置具有响应性的图表的最简单方法是:
const ctx = document.getElementById('chart');
const handleResize = (chart) => {
chart.resize();
}
new Chart(ctx, {
type: 'bar',
data: {
labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
borderWidth: 1
}]
},
options: {
responsive: true,
onResize: handleResize,
maintainAspectRatio: false
}
});
.chart-parent{
position: relative;
width: 90vw;
height: 90vh;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.3.0/dist/chart.umd.min.js"></script>
<div class="chart-parent">
<canvas id="chart"></canvas>
</div>
onResize()
函数中调用了chart.resize()
,导致进入了循环。 - infografnet.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);
}
请访问我的CodePen链接:
<div>
中,并在该<div>
上设置高度和/或宽度,而不是在画布上设置。 - totymedli