Merge pull request #915 from adrima01/tree_as_png

new: downloadable tree as png
pull/919/head
Raphaël Vinot 2024-05-14 18:53:51 +02:00 committed by GitHub
commit ff268a6c18
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 64 additions and 9 deletions

View File

@ -35,8 +35,8 @@
"secure.svg": "H8ni7t0d60nCJDVGuZpuxC+RBy/ipAjWT627D12HlZGg6LUmjSwPTQTUekm3UJupEP7TUkhXyq6WHc5gy7QBjg==",
"stats.css": "/kY943FwWBTne4IIyf7iBROSfbGd82TeBicEXqKkRwawMVRIvM/Pk5MRa7okUyGIxaDjFQGmV/U1vy+PhN6Jbw==",
"stats_graph.js": "S/sMNQK1UMMLD0xQeEa7sq3ce8o6oPxwxGlyKVtaHOODjair86dbBDm7cu6pa/elMRDJT1j09jEFjWp+5GbhTw==",
"tree.css": "AvSJOleYapo+xOCcOPGxTcKg+t1TxFkmr/VvgVJbXaeDOnYECzmJOIVNZii/eFouTh85uDSgr+WLQHq3hft6Kg==",
"tree.js": "MezKYufVkOBLm/Z4ENrMhKzBNDslhXYTlDhjDDAbhHo6XqRzCnTMIgYtikQ1mxkwF5P61Tl1w0kalIPe4Sca6g==",
"tree.css": "xffZ5VGbH0dvaD3pJRj48PttTd29xtU45QozhHi/oJCKy8HU/NkHcGutpx9sOGMuY5tsKn8Pub6Ncsjj9f4TSg==",
"tree.js": "Czw6AAUPQsIawEXi+eM9WG4vqfBw/y9vKbn0EedI3QG5+Y5ryZF05kGEexRc04wj5ec8RNRbR6QGnaVX3DAq3g==",
"up.jpg": "d1ljZJ9f5JekyM6RLFFH2Ua44j6neiQBdUIXOenRTjGppQr3JaeglpQIH6BjPCJL177+TH52U3UIRNS5YAyKIg==",
"up_right.jpg": "OMmz+n+MxR34P8/fn5t4DkqKqdJRzQbXQ7fAi2lhkZIJGhVs2vIyY1f2hpYoBxDAX1OcYsSE2lqIR2vXNDGZsA==",
"video.png": "gJtmkfr8I1Kw43pYEKjg6CAjgmhl1vIBKBQ3ZkxCu3wvxQm+6kf93iLrrFiY2WuiXzxEn2Leu52GJzmVN5id0g==",

View File

@ -8,12 +8,6 @@
font: 12px sans-serif;
}
.link {
fill: none;
stroke: #ccc;
stroke-width: 2px;
}
.flashed-messages {
position: fixed;
bottom: 5px;

View File

@ -824,7 +824,10 @@ function update(root, computed_node_width=0) {
// Enter any new links at the parent's previous position.
.insert('path', "g")
.attr("class", "link")
.attr('d', diagonal),
.attr('d', diagonal)
.style('fill', 'none')
.style('stroke', '#ccc')
.style('stroke-width', '2px'),
update => update,
exit => exit.call(exit => exit.attr('d', diagonal).remove())
).call(link => link.attr('d', diagonal));
@ -833,3 +836,58 @@ function update(root, computed_node_width=0) {
update(root, node_width)
}
}
//download the tree as png file
const downloadSvg = () => {
const svg = document.querySelector('svg');
const svgCopy = svg.cloneNode(true);
const images = svgCopy.querySelectorAll('image');
const promises = [];
images.forEach((imageElement) => {
const promise = new Promise((resolve, reject) => {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const image = new Image();
image.onload = function() {
canvas.width = image.width;
canvas.height = image.height;
ctx.drawImage(image, 0, 0);
const dataURL = canvas.toDataURL("image/svg+xml");
imageElement.setAttribute('href', dataURL);
resolve();
};
image.onerror = function() {
reject(new Error('Error'));
};
image.src = imageElement.getAttribute('href');
});
promises.push(promise);
});
Promise.all(promises).then(() => {
let svgData = new XMLSerializer().serializeToString(svgCopy);
let svgBlob = new Blob([svgData], { type: "image/svg+xml;charset=utf-8" });
let url = URL.createObjectURL(svgBlob);
let img = new Image();
img.onload = function() {
let canvas = document.createElement('canvas');
canvas.width = svgCopy.width.baseVal.value;
canvas.height = svgCopy.height.baseVal.value;
let ctx = canvas.getContext('2d');
ctx.fillStyle='white';
ctx.fillRect(0,0,canvas.width,canvas.height)
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
let png = canvas.toDataURL('image/png');
let a = document.createElement('a');
a.download = 'tree.png';
a.href = png;
a.click();
URL.revokeObjectURL(url);
};
img.src = url;
}).catch((error) => {
console.error('Error:', error);
});
};

View File

@ -867,6 +867,9 @@
</br>
<div class="modal-body">
<ul>
<li>
<a href="#" onclick="downloadSvg()" role="button">Download tree</a>
</li>
<li>
<a href="{{ url_for('image', tree_uuid=tree_uuid) }}" role="button">Download screenshot</a>
</li>