framework
framework copied to clipboard
download button
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?
Related #906?
For SVGs we have the classic crowbar extension. For automation we can rely on playwright screenshots.
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.
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 Thanks for these links. For various reasons I'm struggling to implement these into my project.
-
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.
-
OSS analytics This example is only exporting/downloading SVG via a data loader, correct?
-
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!
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?
Correct. You could try with bubkoo/html-to-image though.
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);
});
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 !