I’ve made a dashboard with streamlit elements and use this js code in the callback on buttons to download:
js_code = f"""
function saveGraphAsPNG() {{
var box = document.getElementById('{unique_id}');
if (!box) {{
alert('No box found to export');
return;
}}
var svg = box.querySelector('svg'); // Select the SVG within the specific box
if (!svg) {{
alert('No SVG found within the box');
return;
}}
// Get the SVG's bounding box dimensions
var bbox = svg.getBBox();
var svgWidth = bbox.width;
var svgHeight = bbox.height;
// Define the DPI scaling factor (e.g., 2 for 2x resolution)
var dpiScalingFactor = {scaling_factor}; // Adjust as needed
// Create a canvas with the dimensions of the SVG
var canvas = document.createElement('canvas');
canvas.width = svgWidth * dpiScalingFactor;
canvas.height = svgHeight * dpiScalingFactor;
var ctx = canvas.getContext('2d');
// Set canvas scale to match the DPI scaling factor
ctx.scale(dpiScalingFactor, dpiScalingFactor);
// Convert the SVG to a PNG image and draw it on the canvas
var svgData = new XMLSerializer().serializeToString(svg);
var img = new Image();
img.onload = function() {{
ctx.drawImage(img, 0, 0);
var png = canvas.toDataURL('image/png');
var a = document.createElement('a');
a.href = png;
a.download = '{filename}.png';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
}};
img.src = 'data:image/svg+xml;base64,' + btoa(svgData);
}}
"""
where unique_id is the id of the box container. This works perfectly.
However, I’m trying to adapt a callback so that all the svgs on the page created by elements is downloaded into a temporary directory which I can later use to create an automated report.
I have looked and everywhere is saying you need to send the data from the frontend to the backend using flask, but I’m aware that flask doesnt work with streamlit very well.
Another proposal was to use session state with this code:
f"""
function captureNivoChartInBox() {{
var box = document.getElementById('{box_id}');
if (!box) {{
console.error(`Box with ID not found.`);
return;
}}
var svg = box.querySelector('svg'); // Select the SVG within the specific box
if (!svg) {{
console.error(`No SVG found within box with ID.`);
return;
}}
// Capture the SVG using html2canvas or another method
html2canvas(box).then(canvas => {{
var imgData = canvas.toDataURL('image/png');
// Send the Base64 image data back to Python
const imageId = boxId + '_image';
var inputElement = document.createElement('input');
inputElement.setAttribute('type', 'hidden');
inputElement.setAttribute('name', imageId);
inputElement.setAttribute('value', imgData);
var form = document.createElement('form');
form.appendChild(inputElement);
document.body.appendChild(form);
// Use Streamlit to handle the data
form.submit();
}});
}}
"""
However, I can’t seem to find the data in the session state.
Has anyone got any ideas?