【问题标题】:Full size download Chartjs canvas on mobile device在移动设备上全尺寸下载 Chartjs 画布
【发布时间】:2022-01-06 07:01:07
【问题描述】:

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

---- 引导是必备的

--- 注意:如果您将示例中的屏幕宽度设置为小,然后单击下载,则输出将是该尺寸且小。

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/

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

我怎样才能下载完整尺寸的 chartjs 画布。

【问题讨论】:

  • 定义“全尺寸”。
  • 像显示所有图例标签的桌面版本一样。最小尺寸 1200 像素?
  • 或在其他定义中显示 xAxes 中的图例标签的完整列表。
  • 所以当我们把屏幕变小(移动版)时,输出会很小,但输出应该是全尺寸版本,就像桌面输出一样。
  • 你不需要向我解释这个问题。我只是不明白你为什么要在1440px 宽显示器上显示1440px 宽图像和在4k 显示器上显示3840px 图表。无论使用什么设备,您在下载时不想要图表图像的标准尺寸吗?如果你这样做,那标准是什么? “全宽” 是您现在在手机上获得的。显然,你不想那样。

标签: javascript html twitter-bootstrap chart.js


【解决方案1】:

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

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

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

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

代码如下所示:

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。目前,如果显示的图表宽度大于该值,您将下载更大的图像,如您在 cmets 中所说。我个人觉得这有点奇怪。

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

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

与

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

看到它的工作:http://jsfiddle.net/websiter/Lzdc3bw1/

【讨论】:

  • 谢谢,但是当点击下载按钮时,它会返回一个损坏的图像。
  • @Farshad。小提琴中的代码不是我在这里发布的代码(有效)。由于某种原因,它没有采用最后一个“设置为基础”。我已经用答案中的内容更新了小提琴。立即尝试。
  • 非常感谢您的时间。
  • 你能告诉我如何在保存的图像中添加标题吗?
  • 我可以想到至少三种方法来实现这一点,但在这里回答它会违反Stack Overflow 规则。这是一个不同的问题,因此您必须单独提出。其次,您必须研究任务,尝试找到的任何解决方案,并且只询问您尝试的方法是否无效,并链接到说明您尝试的方法应该有效的任何文档。如果您正在寻找出租编码服务,那么您来错网站了。还有其他更适合此类请求的地方。
【解决方案2】:

可以通过创建新的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

【讨论】:

  • 当窗口大小为1920 x 1000(在桌面上)时下载生成的图像,然后将窗口大小调整为小于600px的宽度并再次下载图像。你注意到这两张图片有什么不同吗?
  • 我看不出有什么不同。图例 xAxes 仍未完成。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-08
  • 2014-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多