framework icon indicating copy to clipboard operation
framework copied to clipboard

download button

Open Fil opened this issue 1 year ago • 3 comments
trafficstars

A way for a user to point at a visual (figure, canvas, svg…) and download it as png (or maybe svg).

If activated, it should be available everywhere, but not get in the way.

maybe this should be a Chrome extension?

Fil avatar Feb 19 '24 15:02 Fil

Related #906?

mbostock avatar Mar 07 '24 05:03 mbostock

For SVGs we have the classic crowbar extension. For automation we can rely on playwright screenshots.

Fil avatar Jul 15 '24 15:07 Fil

I think the purpose of the download button would be more for dashboard viewers to get easily access to a high resolution screenshot or svg file. Without the requirement of installing an extension or having access to the dev environment. Manual screenshots always shift a few pixels.

Also, in Notebook, the PNG is saved in 2x resolution, which is great.

The DOM.... finction in Notebooks is a great solution, would be nice to see the same in framework.

spandl avatar Oct 02 '24 16:10 spandl

You can copy over the DOM.download module directly from https://github.com/observablehq/stdlib/blob/main/src/dom/download.js

If you want to download data as xlsx, you can try SheetJS: https://observablehq.observablehq.cloud/pangea/party/xlsx-downloads (solution contributed by @cedricr)

For screenshots we recommend making them as data loaders, with "build-time rendering" (colloquially called server-side rendering, SSR). There are examples of that in https://github.com/observablehq/oss-analytics and in the d3-geo-polygon documentation (see https://github.com/d3/d3-geo-polygon/blob/main/docs/snapshots/%5Bsnapshot%5D.png.js).

Fil avatar Oct 29 '24 19:10 Fil

@Fil Thanks for these links. For various reasons I'm struggling to implement these into my project.

  1. Download module This module is creating a button and downloads the object. This part is understood, but how do you get from a Plot, that is using css and Google custom fonts to an image blob? While I managed to download simpler SVGs and PNGs, it fails with more complex SVGs files.

  2. OSS analytics This example is only exporting/downloading SVG via a data loader, correct?

  3. Geo-polygon example This is exporting/downloading images, but from a canvas object, not from a plot that generates SVG.

I'm not sure which part I am missing. With Observable notebooks, images are (almost) pixel perfect and double resolution (which is great). I guess, where I struggle is to create a blob from more complex SVG code/plots.

Do you have recommendations where to get more code examples?

Thanks!

spandl avatar Oct 31 '24 18:10 spandl

Let me try this first... https://observablehq.com/plot/getting-started#plot-in-node-js

This is probably what you mean with "build-time-rendering". I'm just afraid, that if the page offers the user some dynamic filters via select inputs, this won't work... will it?

spandl avatar Oct 31 '24 22:10 spandl

Correct. You could try with bubkoo/html-to-image though.

Fil avatar Nov 01 '24 10:11 Fil

Wow. html-to-image works surprisingly well. Together with download there isn't much to do and it handles the complex SVG structure of Plot, as well as custom fonts when integrated with @import.

In case someone is looking for the same functionality (straight from the doc + double resolution):

htmlToImage
  .toPng(plot, { pixelRatio: 2 })
  .then(function (dataUrl) {
    download(dataUrl, "my-node.png");
  })
  .catch(function (error) {
    console.error("Image download failed: ", error);
  });

Image

IMO, this is a very good solution. I let you decide if you really want to integrate this natively in Framework or not. In any case: Thanks a ton @Fil !

spandl avatar Nov 01 '24 14:11 spandl