在移动设备上完整大小下载 Chartjs canvas

Full size download Chartjs canvas on mobile device

这是我在 bootstrap 和 chartjs 框架内构建的 Chartjs canvas。问题是我无法在移动设备等小屏幕上下载全宽图像。

---- Bootstrap 是必备的

--- 注意:如果您将示例中的屏幕宽度调小,然后单击下载,输出将是那个大小和小。

HTML:

<div class="card">

  <div class="card-body">
    <h4 class="card-title mb-0"> Average </h4>

    <a data-name="avg-chart" id="downloadavg" download="searchtrends-average-position-chart.jpg" href="" class="download">
      <button class="btn btn-primary" type="button">
        <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="white" class=" bi bi-cloud-arrow-down-fill" viewBox="0 0 16 16">
          <path d="M8 2a5.53 5.53 0 0 0-3.594 1.342c-.766.66-1.321 1.52-1.464 2.383C1.266 6.095 0 7.555 0 9.318 0 11.366 1.708 13 3.781 13h8.906C14.502 13 16 11.57 16 9.773c0-1.636-1.242-2.969-2.834-3.194C12.923 3.999 10.69 2 8 2zm2.354 6.854-2 2a.5.5 0 0 1-.708 0l-2-2a.5.5 0 1 1 .708-.708L7.5 9.293V5.5a.5.5 0 0 1 1 0v3.793l1.146-1.147a.5.5 0 0 1 .708.708z" />
        </svg>
      </button>
    </a>
    <div class="c-chart-wrapper" id="avg-chart_parent">
      <canvas class="chart" id="avg-chart" style="height:300px;width:100%" height="300"></canvas>
    </div>
  </div>
</div>

JS:

new Chart(document.getElementById("avg-chart"),{"type":"line",
                      "data":{"labels":["2020.11.1","2020.11.2","2020.11.3","2020.11.4","2020.11.5","2020.11.6","2020.11.7","2020.11.7","2020.11.9","2020.11.10","2020.11.11","2020.11.12","2020.11.13","2020.11.14","2020.11.15","2020.11.16","2020.11.17","2020.11.18","2020.11.19","2020.11.20","2020.11.21","2020.11.22","2020.11.23","2020.11.24","2020.11.25","2020.11.26","2020.11.27","2020.11.28","2020.11.29","2020.11.30",],
                      "datasets":[{"label":"Average Position ",
                      "data":["11","12","13","14","15","16","17","18","19","19","19","19","19","19","19","19","19","19","19","20","21","22","23","24","25","26","27","28","29","30",],
                      "fill":false,"borderColor":"rgb(37,154,71)","lineTension":0.1}]}, options: {
        scales: {
            yAxes: [{
                ticks: {
                        reverse: true,
                }
            }],
            xAxes: [{
                type: 'time',
                distribution: 'series',
                time: {
          tooltipFormat:'MM/DD/YYYY', 
              }
        
                    }]
        },
        legend: {
            display: false,
            maxWidth: 9999
             
        }
    }});
    
    
        function downloadpng(chartname,chartid){
      var canvas = document.getElementById(chartname);
   var url_base64jp =canvas.toDataURL("image/jpg");
  var a =  document.getElementById(chartid);
  a.href = url_base64jp;
  }
//Download Chart Image
$('.download').on( 'click', function (event) {
  var chartname =  $(this).attr('data-name');
  var chartid =  $(this).attr('id'); 
    downloadpng(chartname,chartid);
 
}); 

我在这里做了一个例子:

http://jsfiddle.net/aneeshtan/vu27aew3/49/

如您所见,我无法在小屏幕中保存全尺寸 canvas (Chartjs),它会自动更改比例。

如何下载完整尺寸的 chartjs canvas。

可以通过创建新的 canvas 元素以及新的 canvas context

来应用自定义维度
function downloadpng(chartname, chartid) {
  var canvas = document.getElementById(chartname);
  var url_base64jp = canvas.toDataURL("image/jpg");
  var a = document.getElementById(chartid);
  
  var resizedCanvas = document.createElement("canvas");
  var resizedContext = resizedCanvas.getContext("2d");

  resizedCanvas.height = "1080";
  resizedCanvas.width = "1920";
  
  resizedContext.drawImage(canvas, 0, 0, 1920, 1080);
  
  url_base64jp = resizedCanvas.toDataURL("image/jpg");


  a.href = url_base64jp;
}

Updated Fiddle Link

为了获得更高分辨率的图表快照,您首先需要调整它的大小,然后等待它重新绘制。

最简单的方法是调整父级的大小并等待 ~ 300ms
注意:如果您的图表更复杂(要绘制的数据明显更多),调整大小和重绘可能需要更长的时间,请随意相应地增加超时间隔 - 它是 321ms现在。

由于您需要等待图表调整大小,您不能再使用初始点击。您需要在调整图表大小后触发另一个。

最后,我将在下载后删除 href 值。如果我不这样做,任何后续单击该按钮都会 return 第一个快照,如果图表是动态的并且您希望能够再次对其进行快照而无需刷新页面。

代码如下所示:

function downloadImage(name, id) {
  setTimeout(() => {
    const a = $(id)[0];
    a.href = $(name)[0].toDataURL("image/jpg");
    a.click();
  }, 321)
}
$('.download').on('click', function(e) {
  const name = '#' + $(this).data('name');
  const id = '#' + this.id;
  const parent = $(name).parent();
  if (!$(this).attr('href')) {
    parent.css({ width: Math.max(1200, parent.width()) });
    downloadImage(name, id);
    e.preventDefault();
  } else {
    parent.css({ width: '' });
    setTimeout(() => $(id).attr('href', ''));
  }
});

随意将 1200 更改为您想要的任何图表 min-width。目前,如果显示的图表宽度大于该值,您将下载更大的图像,如您在评论中所说。我个人觉得有点奇怪。

如果您改变主意,并希望下载的图表始终具有相同的大小(即使是从较大的显示器下载时),请替换

parent.css({ width: Math.max(1200, parent.width()) });

parent.css({ width: 1920 }); // or whatever fixed chart width you want

看到它有效:http://jsfiddle.net/websiter/Lzdc3bw1/