问题
I'm using chart.js with the latest v2.7.1 release. I followed this jsfiddle example for creating a fixed Y-Axis effect when scrolling. It works great but there is one issue with Retina displays (iPhones, Macbooks, etc).
var ctx = document.getElementById("myChart").getContext("2d");
var chart = {
options: {
responsive: true,
maintainAspectRatio: false,
animation: {
onComplete: function(animation) {
var sourceCanvas = myLiveChart.chart.canvas;
var copyWidth = myLiveChart.scales['y-axis-0'].width - 10;
var copyHeight = myLiveChart.scales['y-axis-0'].height + myLiveChart.scales['y-axis-0'].top + 10;
var targetCtx = document.getElementById("myChartAxis").getContext("2d");
targetCtx.canvas.width = copyWidth;
targetCtx.drawImage(sourceCanvas, 0, 0, copyWidth, copyHeight, 0, 0, copyWidth, copyHeight);
}
}
},
type: 'bar',
data: {
labels: ["January", "February", "March", "April", "May", "June", "July"],
datasets: [
{
label: "My First dataset",
fillColor: "rgba(220,220,220,0.2)",
strokeColor: "rgba(220,220,220,1)",
pointColor: "rgba(220,220,220,1)",
pointStrokeColor: "#fff",
pointHighlightFill: "#fff",
pointHighlightStroke: "rgba(220,220,220,1)",
data: [65, 59, 80, 81, 56, 55, 40]
}
]
}};
var myLiveChart = new Chart(ctx, chart);
setInterval(function () {
myLiveChart.data.datasets[0].data.push(Math.random() * 100);
myLiveChart.data.labels.push("Test");
var newwidth = $('.chartAreaWrapper2').width() +60;
$('.chartAreaWrapper2').width(newwidth);
$('.chartAreaWrapper').animate({scrollLeft:newwidth});
}, 5000);
.chartWrapper {
position: relative;
}
.chartWrapper > canvas {
position: absolute;
left: 0;
top: 0;
pointer-events:none;
}
.chartAreaWrapper {
overflow-x: scroll;
position: relative;
width: 100%;
}
.chartAreaWrapper2 {
position: relative;
height: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.1/Chart.bundle.min.js"></script>
<div class="chartWrapper">
<div class="chartAreaWrapper">
<div class="chartAreaWrapper2">
<canvas id="myChart"></canvas>
</div>
</div>
<canvas id="myChartAxis" height="300" width="0"></canvas>
</div>
If you view the code snippet (and wait the 5 seconds for a scroll trigger) on Retina screen, the Y-axis labels are very large, and also appear cut-off as if it wasn't completely rendered. The same view on a non-retina screen looks fine. Are there any js/css workarounds for the sizing issue on Retina screens or any specific chart.js workarounds?
(Credit to this stackoverflow post for the code snippet)
回答1:
I also ran into this issue, the original fiddle works well except that it is not responsive.
The key is that the original fiddle does not take into account the devicePixelRatio
the same way as the chart using the helpers.retinaScale
method from ChartJS core.
After several hours of fiddling, here is the surprisingly simple answer: https://jsfiddle.net/4ydfo4xo/
When copying the scales from the original chart, the devicePixelRatio
must be applied to the sourceWidth and sourceHeight arguments of drawImage
Specifically the pixel ratio is accessed using
var pixelRatio = myLiveChart.chart.currentDevicePixelRatio;
and then the drawImage
arguments are changed..
targetCtx.drawImage(sourceCanvas, 0, 0, copyWidth * pixelRatio, copyHeight * pixelRatio, 0, 0, copyWidth, copyHeight);
来源:https://stackoverflow.com/questions/47038946/chartjs-v2-on-retina-display-has-label-size-issue-text-is-too-large