diff --git a/html/table.html b/html/table.html
index 1f84939..28afd1a 100644
--- a/html/table.html
+++ b/html/table.html
@@ -1679,7 +1679,7 @@
class SelectedNodes {
static nodes = new Map();
static #circle_pos = 1;
- static #name_pos = 3;
+ static #name_pos = 0;
static #circle_size_selected = LEAF_NODE_SIZE * 1.5;
static #circle_size_default = LEAF_NODE_SIZE;
static #default_color = "#999";
@@ -3557,9 +3557,34 @@
css_export.appendChild(link_style_sheet);
svg.insertBefore(css_export, svg.firstChild);
+
+ let longest_label = 10
+ if(ORIGINAL_DATA){
+ let leaves = svg.querySelectorAll(".leaf-node")
+ leaves.forEach((ele) => {
+ let [element, circle, text] = SelectedNodes.getNodeData(ele)
+ let input_text = text.textContent;
+ if(ORIGINAL_DATA.has(input_text) && input_text){
+ let row = ORIGINAL_DATA.get(input_text)
+ let new_label = `${input_text}\t${row.slice(1, -1).join('\t')}`
+ text.textContent = new_label
+ let text_length = new_label.length;
+ if(text_length > longest_label){
+ longest_label = text_length;
+ }
+ }
+ })
+ }
+ svg.style.overflow = "visible"
const tree_svg = svg.querySelector("#TreeSVG");
- const offset_safety_factor = 20;
- tree_svg.style.marginLeft = legend_width + offset_safety_factor;
+ tree_svg.style.overflow = "visible"
+ tree_svg.style.paddingLeft = "4em"
+ tree_svg.style.height = "auto"
+ tree_svg.style.width = "auto"
+ tree_svg.width = tree_svg.width.baseVal.value + (longest_label*4);
+ const attr = tree_svg.getAttributeNode("height")
+ tree_svg.removeAttributeNode(attr);
+ tree_svg.setAttribute("viewBox", `${0} -${tree_svg.viewBox.baseVal.height} ${tree_svg.width.baseVal.value + (longest_label*4)} ${tree_svg.viewBox.baseVal.height + (longest_label*4)}`);
const serializer = new window.XMLSerializer;
const xml_string = serializer.serializeToString(svg);
@@ -3572,6 +3597,7 @@
let downloadLink = document.createElement("a");
downloadLink.download = 'tree_snapshot_'+date.getDate()+'-'+
(date.getMonth()+1)+'-'+date.getFullYear()+'_'+date.getHours()+'h.svg';
+
let svg = document.getElementById("TreeData").cloneNode(true)
//remove duplicated leaf nodes text duplication for more accurate searches
svg.querySelectorAll('g .tree-node').forEach(node => {
@@ -3580,8 +3606,15 @@
text_nodes_leafs[0].remove()
}
})
- svg.querySelector("#TreeSVG").style.overflow = "visible"
- const blob = serialize2svg(svg)[0];
+
+ const tree_svg = svg.querySelector("#TreeSVG");
+ const [minX, minY, width, height] = tree_svg.getAttribute("viewBox").split(/[\s,]+/).map(Number);
+ svg.style.height = `${height*1.15}px`
+ svg.style.width = `${width*1.05}px`
+
+ svg.style.overflow = "visible";
+
+ const blob = serialize2svg(svg)[0];
downloadLink.href = window.URL.createObjectURL(blob);
downloadLink.click(); //Trigger a click on the element
downloadLink.remove();
@@ -3589,72 +3622,69 @@
/*Adapted from https://gist.github.com/tatsuyasusukida/1261585e3422da5645a1cbb9cf8813d6 and https://zooper.pages.dev/articles/how-to-convert-a-svg-to-png-using-canvas*/
export_tree_to_png = function(){
+ let svg = document.getElementById("TreeSVG").cloneNode(true);
+ let remove_svg = false;
+ if(ORIGINAL_DATA){
+ // SVG value needs to be in DOM to be rendered in the canvas,
+ // but we also need ta copy to update the text attributes in the tree
+ // or else the displayed tree is modified
+ // Copies are only needed if metadata is included as well
+ let leaves = svg.querySelectorAll(".leaf-node")
+ let longest_label = 10
+ svg = svg.cloneNode(true);
+ svg.style.zIndex = '-1';
+ document.getElementById("TreeData").appendChild(svg);
+ remove_svg = true;
+ leaves.forEach((ele) => {
+ let [element, circle, text] = SelectedNodes.getNodeData(ele)
+ let input_text = text.textContent;
+ if(ORIGINAL_DATA.has(input_text) && input_text){
+ let row = ORIGINAL_DATA.get(input_text)
+ // End is not included in the slice, as it is simply a bool added on the program to track changed values
+ let new_label = `${input_text}\t${row.slice(1, -1).join('\t')}`
+ text.textContent = new_label
+ let text_length = new_label.length;
+ if(text_length > longest_label){
+ longest_label = text_length;
+ }
+ }
+ })
+ }
+ // Get the view box required for setting the correct output size
+ const viewbox = svg.getAttribute("viewBox");
+ const [minX, minY, width, height] = viewbox.split(/[\s,]+/).map(Number);
+ let svg_width = width;
+ let svg_height = height;
+
+ //extract SVG element
+ const svgData = new XMLSerializer().serializeToString(svg);
+
+ //create canvas to the size of the SVG
+ let canvas = document.createElement('canvas')
+ canvas.width = svg_width+svg_width*0.05;
+ canvas.height = svg_height+svg_width*0.15;
- let svg = document.getElementById("TreeSVG").cloneNode(true);
-
- let {x, y, width, height} = svg.viewBox.baseVal;
- let svg_width = width;
- let svg_height = height;
- let modified_width = svg_width + (svg_width * 0.15);
- let modified_height = svg_height + (svg_height * 0.15);
-
- // Change the width of the svg element allowing for more of the viewbox to show up
- svg.setAttribute("width", modified_width)
-
- /*
- Create a temporary svg expanding increasing the size of the final
- canvas the elelment is rendered in. Having this seperate wrapper
- also allows for seperate modifications of the PNG before export allowing
- for translationst to be performed.
- */
- let wrapping_svg = d3.select("body")
- .append("svg")
- .attr("id", "temporary_svg")
- .attr("height", modified_height)
- .attr("width", modified_width)
- .append('g')
- .attr("id", "translation_element")
- .attr("height", modified_height)
- .attr("width", modified_width)
- .append(() => {
- return svg
- })
-
-
- //extract SVG element
- const svgData = new XMLSerializer().serializeToString(document.getElementById("temporary_svg"));
-
- //create canvas to the size of the SVG
- let canvas = document.createElement('canvas')
- canvas.width = modified_width;
- canvas.height = modified_height;
-
- //create SVG image element
- let img = new Image();
- img.src = "data:image/svg+xml;base64," + btoa(svgData);
-
- img.onload = function () { //must be inside this image onload event function due to async image load nature
- //render SVG image onto canvas element
- let ctx = canvas.getContext('2d');
- ctx.fillStyle = "white";
- ctx.fillRect(0, 0, canvas.width, canvas.height);
-
- ctx.drawImage(img, 0, 0, modified_width, modified_height);
-
- //create PNG image from the canvas
- let pngUrl = canvas.toDataURL('image/png').replace('image/png', 'octet/stream');
- //create download link
- let downloadLink = document.createElement("a");
- downloadLink.download = 'tree_snapshot.png';
- downloadLink.href = pngUrl;
- downloadLink.click();
- downloadLink.remove();
- }
-
- // Remove temporary elements
- document.getElementById("temporary_svg").remove();
-
-
+ //create SVG image element
+ let img = new Image();
+ img.src = "data:image/svg+xml;base64," + btoa(svgData);
+
+ img.onload = function () { //must be inside this image onload event function due to async image load nature
+ //render SVG image onto canvas element
+ let ctx = canvas.getContext('2d');
+ ctx.fillStyle = "white";
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
+ ctx.drawImage(img, 0, 0);
+ //create PNG image from the canvas
+ let pngUrl = canvas.toDataURL('image/png').replace('image/png', 'octet/stream');
+ //create download link
+ let downloadLink = document.createElement("a");
+ downloadLink.download = 'tree_snapshot.png';
+ downloadLink.href = pngUrl;
+ downloadLink.click();
+ downloadLink.remove();
+ canvas.remove();
+ if(remove_svg) svg.remove();
+ }
}
tree_full_screen_mode = function(){