Closed josefwilfinger closed 4 months ago
all the interactive stuff that is clickable or moves is in the dom for perf reasons.
you can render it all into an image using an svg foreignObject. demo is here: https://leeoniya.github.io/uPlot/demos/svg-image.html
oh thx :) i am 2 stupid. have not seen this example. searched for PNG and save export etc :)
i am 2 stupid
no, definitely not.
i want to improve the demo index by adding a search/filter and add relevant tags to each demo since many of them show off multiple things.
a remark regarding export function possibility. As an additional demo the following function triggers a save as png. It is as you will see nearly the same as your svg plot demo.
function saveUPlot(u, fileName)
{
let pxRatio = devicePixelRatio;
let rect = u.root.getBoundingClientRect();
// rect of uPlot's canvas to get y shift due to title above it (if any)
let rect2 = u.ctx.canvas.getBoundingClientRect();
let htmlContent = u.root.outerHTML;
let uPlotCssRules = "";
//take the uplotcss
for (let i = 0; i < document.styleSheets.length; i++) {
let styleSheet = document.styleSheets[i];
if(styleSheet.href!== null && styleSheet.href.search('uPlot')>=0)
{
uPlotCssRules = styleSheet.cssRules;
break;
}
}
let cssContent = "";
for (let { cssText } of uPlotCssRules)
cssContent += `${cssText} `;
let width = Math.ceil(rect.width * pxRatio);
let height = Math.ceil(rect.height * pxRatio);
let viewBox = `0 0 ${Math.ceil(rect.width)} ${Math.ceil(rect.height)}`;
let svgText = `
<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="${viewBox}">
<style>
body { margin: 0; padding: 0; }
${cssContent}
</style>
<foreignObject width="100%" height="100%">
<body xmlns="http://www.w3.org/1999/xhtml">${htmlContent}</body>
</foreignObject>
</svg>
`;
let can = document.createElement('canvas');
let ctx = can.getContext('2d');
can.width = width;
can.height = height;
can.style.width = Math.ceil(rect.width) + "px";
can.style.height = Math.ceil(rect.height) + "px";
let DOMURL = window.URL || window.webkitURL || window;
let img = new Image();
//let blob = new Blob([svgText], {type: 'image/svg+xml;charset=utf-8'});
//let url = DOMURL.createObjectURL(blob);
//using the following instead above mitigates crossOrigin problems with tainted canvas
let url = "data:image/svg+xml;charset=utf-8," + svgText;
ctx.drawImage(u.ctx.canvas, 0, (rect2.top - rect.top) * pxRatio);
img.onload = () => {
ctx.drawImage(img, 0, 0);
let link = document.createElement('a');
link.download = fileName+'.png';
link.href = can.toDataURL("image/png");
link.click();
DOMURL.revokeObjectURL(url);
};
img.src = url;
}
Hi,
do you think it would be possible to bring the title and the legend onto the canvas? In this way when in export the canvas as png. This information is also on the png.
Best Regards and thx 4 your work Josef