Chartjs v2 on retina display has label size issue (text is too large)

匆匆过客 提交于 2019-12-11 15:00:02

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!