在移动设备上将多个 Dygraph 保存为 PNG 时出现渲染问题

Rendering problems when saving multiple Dygraphs as a PNG on mobile devices

我有一个使用 Dygraphs 创建图表的 Web 应用程序。

该应用程序允许用户创建多个 Dygraph 图表(每个图表都有自己的 Y 轴),这些图表将彼此堆叠。

这里是多个 Dygraphs 在 PC 浏览器上的样子的示例:请注意,该示例显示了三个不同的 Dygraphs,每个都有自己的 Y 轴,但 X 轴对于前 2 个图表是隐藏的并且是可见的在底部图表上。

我将允许用户将图表以 PNG 格式保存到磁盘。 - 我目前将多个 Dygraphs 保存为一个 PNG 的方式是:

  1. 创建一个目标 canvas,它将用于包含所有可见的 Dygraphs
  2. 从每个 Dygraph 中提取每个 canvas,然后将每个 canvas 添加到目标 canvas **
  3. 通过目标上的 .toDataURL() 函数创建 PNG canvas

下面是上面的屏幕截图保存为一个 PNG 时的样子的示例:(这正是我想要的 PNG)

该程序在 PC 上的浏览​​器上运行良好。但是当我试图在 phone/tablet 浏览器上将多个 Dygraphs 保存到一个 PNG 中时,生成的 PNG 与屏幕上可见的图形不匹配。

示例: 这是 iPad 上多个 Dygraph 的样子(屏幕截图)

这是生成的 PNG 的样子(请注意每个图表的宽度和高度如何与实际 iPad 显示不匹配)。

我不明白为什么我使用PC 浏览器时PNG 可以正确呈现,但在移动设备上使用浏览器时无法正确呈现。

我不确定这个问题是由于 Canvas.toDataURL() 函数的限制还是 Dygraphs 问题或其他问题。我正在寻找可能为我指明正确方向的建议 and/or 阐明这个特定问题。

**我应该提到我使用 Juan Manuel Caicedo Carvajal's Dygraph-Export extension

我猜问题出现了,因为生成的 canvas 没有完全呈现到 iPad 的响应屏幕。

您可以尝试使用 toDataUrl https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL

自己导出原始 canvas(而不是使用上述库生成新的)

Dygraphs 生成 2 个 canvas,一个用于图例,一个用于实际图表,并将它们叠加在一起。因此,请确保您选择了正确的(而不是 _hidden_canvas)。如果示例有效,您可以使用 canvas.drawImage(otherCanvas) 将图例绘制到图 canvas 上 How to Copy Contents of One Canvas to Another Canvas Locally

希望这对您有所帮助。让我更新!

我的 workaround/hack 针对我的 OP 中所述的问题是在 Dygraph.getContextPixelRatio 函数中更改 Dygraph 源。

注意下面的代码我设置了devicePixelRatio = 1

dygraph-combined.js

Dygraph.getContextPixelRatio = function (context) {
try {
    //var devicePixelRatio = window.devicePixelRatio;
    var devicePixelRatio = 1; // Hack!!!  
    var backingStoreRatio = context.webkitBackingStorePixelRatio ||
        context.mozBackingStorePixelRatio ||
        context.msBackingStorePixelRatio ||
        context.oBackingStorePixelRatio ||
        context.backingStorePixelRatio || 1;
    if (devicePixelRatio !== undefined) {
        return devicePixelRatio / backingStoreRatio;
    } else {
        // At least devicePixelRatio must be defined for this ratio to make sense.
        // We default backingStoreRatio to 1: this does not exist on some browsers
        // (i.e. desktop Chrome).
        return 1;
    }
} catch (e) {
    return 1;
}
};

就我而言,这个 hack 解决了我的问题(在 OP 中说明)并且没有对我的应用程序中使用 Dygraphs 的任何其他部分产生负面影响。也就是说,如果您找到 better/correct 解决 OP 中所述问题的方法,请分享。