【问题标题】:Chartjs + jsPDF = Blurry imageChartjs + jsPDF = 模糊图像
【发布时间】:2016-04-26 03:35:34
【问题描述】:

我在将图表导出为 PDF 时遇到了一些问题。

我有这个 div

    <div id="chart-area">
    <button type="button" id="btnPrint_" onClick="Print1()">Print</button>
    <?php echo '<h2 id="title">'.$_SESSION['team_name'].'</h2>'; ?>
        <canvas id="myChart" width="800" height="400"></canvas>
        <div id="legend"></div>
    </div>

我正在使用 ChartJS 创建图表

$( document ).ready(function(){
    var helpers = Chart.helpers;
    var canvas = document.getElementById('myChart');
    var data = {
        labels: unique_dates,
        datasets: [
            {
                label: "Ticket Count",
                fillColor: "rgba(107, 110, 111, 0.6)",
                strokeColor: "rgba(107, 110, 111, 0.6)",
                highlightFill: "rgba(107, 110, 111, 0.6)",
                highlightStroke: "rgba(151,137,200,1)",
                data: ticket_count
            },
            {
                label: "Subsidy Count",
                fillColor: "rgba(8, 126, 210,0.5)",
                strokeColor: "rgba(8, 126, 210,0.8)",
                highlightFill: "rgba(220,220,220,0.75)",
                highlightStroke: "rgba(220,220,220,1)",
                data: subsidy_count
            }
        ]
    }


  var bar = new Chart(canvas.getContext('2d')).Bar(data, {
  tooltipTemplate: "<%if (label){%><%=label%>: <%}%><%= value %>kb",
  animation: true,
});
// 
var legendHolder = document.createElement('div');
legendHolder.innerHTML = bar.generateLegend();

document.getElementById('legend').appendChild(legendHolder.firstChild); 

});

当我点击 btnPrint_ 按钮时,我想将我的图表导出为 PDF

喜欢这个

function Print1() {
            var title = $("#title").text();
            var doc = new jsPDF('l', 'mm',[210, 297]);
           html2canvas($("#myChart"), {
                onrendered: function(canvas) {         
                    var imgData = canvas.toDataURL('image/png',1.0);                  
                    doc.text(130,15,title+" GT Log");
                    doc.addImage(imgData, 'PNG',20,30,0,130); 
                    doc.addHTML(canvas);
                    doc.save(title+'gt_log.pdf');             
                    }       
            });

}

问题是我的图表在 pdf 文件中完全模糊。

知道如何解决这个问题吗?

这是我第一次使用 ChartJS 和 jsPDF,所以我可能做错了什么。

谢谢!

【问题讨论】:

    标签: chart.js jspdf html2canvas


    【解决方案1】:

    自从几个版本以来,Chart.js 都有参数 devicePixelRatio。 默认情况下,画布由监视器以 DPI 数字呈现,因此 96 或 Retina - 不适合打印输出,但非常适合屏幕。

    如果增加此值,则会创建更多像素。展开该值,以便您可以将打印质量的图表导出为 Base64 图像。该值不影响图表在监视器上的显示。

    在我的例子中,我将值设置为 1.5。

    options:{
          devicePixelRatio: 1.5
    }
    

    文档:https://www.chartjs.org/docs/3.0.2/configuration/device-pixel-ratio.html 效果很好...

    【讨论】:

      【解决方案2】:

      我一直在从事一个项目,尝试使用 chartjs 生成图表,然后使用 Chrome 的打印到 PDF 功能打印它们,我发现 chartjs 图表看起来很糟糕。在阅读了 stackoverflow 和 github 上的各种线程后,我开发了一个对我来说效果很好的解决方案。

      在我的特定情况下,我需要固定大小的图表,但我不能让它们响应,因为我需要它们正确地适合打印的页面。我使用样式标签来设置大小:

      &lt;canvas style="width: 300px; height: 300px" /&gt;

      我发现如果你在图表中设置 responsive: false 然后使用这样的样式标签,Chartjs 不会弄乱图表的大小。使用任何其他方法,如设置宽度或高度(不是样式宽度或高度)或使用 css 类将无法正确设置它。 Chartjs 似乎只在我为此设置元素的内联样式标签时才起作用。

      无论如何,让我获得更好的 PDF 输出的诀窍是让 Chartjs 呈现一个更大的图表,然后将其缩小到更小的尺寸,以便它正确地适合我的页面。

      假设出于某种原因我们想要一个 300x300 像素的图表,但当我们将其打印为 PDF 时它看起来很糟糕。我们需要让 Chartjs 将此图表绘制成更大的图表,然后将其缩小到 300x300。在我自己的项目中,我让 Chartjs 将其绘制 2 倍大。所以对于这个例子,我将制作一个 600x600 的画布元素,如下所示:

      <canvas style="width: 600px; height: 600px;" class="graph" />
      

      同时,我有一个高度和宽度设置为 300 像素的“图形”css 类。然而,由于内联样式,图表不会以 300px 呈现。

      然后您可以像往常一样制作图表,但在制作图表的代码行之后,您会立即从图表中删除内联样式标签。我发现当你这样做时,chartjs 会将图表绘制到更大的 600x600 大小,但图表立即调整为 300x300。以下是代码的示例:

      var ctx = canvas.getContext('2d'); var mychart = new Chart( ctx ,{ .... }); canvas.removeAttribute("style");

      canvas.removeAttribute 移除了内联样式标签,因此 css 类 生效并立即导致画布以较小的尺寸重新渲染。没有闪光或任何迹象表明发生了这种情况,但我发现您获得了更高质量的图表。

      还有另一个问题。例如,您必须为更大的 600x600 尺寸设计图表,以使其看起来正确。当您以较大的尺寸绘制图表时,线条和字体不会调整大小,因此一切看起来都很小。我必须手动将我的图表设置为更大的尺寸来设计它并首先为图表找出好的字体和线条大小,然后在这里进行调整大小的技巧。

      我还发现,简单地使用较小尺寸的图表并制作较粗的线条或较大的字体似乎与先放大所有内容然后将其呈现为较小尺寸的效果不同。

      【讨论】:

        【解决方案3】:

        分辨率来自画布尺寸。增加画布(宽度和高度)的次数越多,下载 PDF 时的分辨率就越高。

        但是,您可能不想过多地增加画布大小,因此,您可以使用的一个技巧是创建一个隐藏的 Canvas,具有更高的宽度和高度,用它来打印图表并创建 PDF ,获得更好的 PDF 质量。

        这是一个演示此功能的小提琴,它可以选择下载从原始画布/图表创建的 PDF,以及从隐藏的画布/图表下载新 PDF 的另一个选项。比较两个结果时,您可以看到质量如何提高很多。

        https://jsfiddle.net/crabbly/kL68ey5z/

        我认为这不是最好的解决方案,但是,这是我想出的提高 PDF 图表文件质量的唯一方法。我目前正在玩这两个库,特别是 jsPDF 在创建文档时如何处理 wh 参数。

        此外,Chart.js 确实带有从图表中提取图像的内置函数 (.toBase64Image()),但是,当我测试时,质量似乎更差。

        【讨论】:

        • 我知道已经有一段时间了,但是您是否尝试过输出 PNG 文件而不是 JPEG 文件?我质疑用于生成 JPEG 文件的压缩方案,以及它们失去了图表中内置的透明度的事实。
        • @Ecksters,我可能在大多数情况下使用 png,它运行良好。另外,正如您所提到的,它将保持图表的透明度。 jsfiddle.net/crabbly/kL68ey5z/380
        猜你喜欢
        • 1970-01-01
        • 2014-10-19
        • 2015-06-10
        • 1970-01-01
        • 2014-06-13
        • 2015-09-19
        • 2019-02-02
        • 2019-05-13
        • 1970-01-01
        相关资源
        最近更新 更多