diff --git a/html/table.html b/html/table.html
index aa1a8cf..e9b54f7 100644
--- a/html/table.html
+++ b/html/table.html
@@ -2,6 +2,15 @@
+
+
ArborView
@@ -223,7 +254,9 @@
const DATA = __DEADFOOD__;
const DEBUG = false;
const TREE_OFFSET = 100;
+ const TREE_LEFT_MARGIN_VIEWBOX_OFFSET = 30; //Space to accommodate near the root inner node labels
var METDATA_TABLE_NON_FULL_SCREEEN_HEIGTH = null; //before changing to full screen mode save the current size of the metadata table
+ var LAST_METADATA_COLUMN_SELECTED = null; //last metadata column selected for legend rendering. useful for subtree legend generation
var NEWICK = null;
var tree_root = null;
var METADATA = null;
@@ -233,8 +266,8 @@
var ORIGINAL_DATA = null;
var ORIGINAL_VIEW_BOX = null;
var ORIGINAL_WIDTH_SVG = 0;
- var LAST_MOVE_X = 0;
- var LAST_MOVE_Y = 0;
+ var LAST_SCROLL_X = 0; // Store last scroll x-position making legend position updates smarter
+ var LAST_SCROLL_Y = 0; // Store last scroll y-position making legend position updates smarter
var SHOW_BRANCH_LENGTHS = true;
var SHOW_METADATA_IN_NAME = false;
var LINE_THICKNESS = 2.0;
@@ -273,6 +306,37 @@
// These are messy due to the way in which they were created, and there has not been time
// to refactor them yet sadly.
+ // ===== CHANGE: Font Size to Average Width Mapping =====
+ // This table defines average character width multipliers for different font sizes in a typical sans-serif font (like Arial or Helvetica)
+ // E.g. Each character averages 0.62 × 12px = 7.44px wide
+ // We need to do approximate max label width calculation as DOM is not rendered at this stage preventing usage of bbox()
+ const FONT_METRICS = {
+ 8: 0.52, // avg width multiplier for 8px font
+ 9: 0.55,
+ 10: 0.58,
+ 11: 0.60,
+ 12: 0.62, // default size
+ 14: 0.65,
+ 16: 0.68,
+ 18: 0.70
+ };
+
+ /**
+ * Estimates the pixel width of text based on font size and average character width metrics.
+ * Uses predefined font metrics for accurate estimation without DOM measurement.
+ *
+ * @function estimateTextWidth
+ * @param {string} text - The text string to measure
+ * @param {number} fontSize - Font size in pixels (must match FONT_METRICS keys for best accuracy)
+ * @returns {number} Estimated width in pixels
+ *
+ **/
+ function estimateTextWidth(text, fontSize) {
+ const AVG_CHAR_WIDTH = FONT_METRICS[fontSize];
+ return text.length * AVG_CHAR_WIDTH * fontSize;
+ }
+
+
function addDisplayDistance(d, rd){
let next_rd = null;
@@ -405,7 +469,10 @@
* scale bar is slightly difficult to add, as the svg viewport dat only shows up AFTER rendering
*/
- // --- Input Validation ---
+ const padding = {
+ top: -2, // Gap above the scale bar text
+ }
+ // --- Input Validation ---
try {
if (!svg || typeof svg.append !== 'function' || svg.empty()) {
throw new Error("Invalid 'svg' parameter: expected a D3 selection.");
@@ -426,7 +493,10 @@
console.error("drawScale() failed due to invalid input:", error.message);
return; // Exit early to avoid rendering with bad input
}
- const scaleBarGroup = svg.append("g").attr("id", "scale-bar-group") //group all svg path elements under single group
+ const scaleBarGroup = svg.append("g")
+ .attr("id", "scale-bar-group") //group all svg path elements under single group
+ .attr("transform", `translate(0, ${padding.top})`);
+
enableVerticalElementDrag(scaleBarGroup); //enables vertical drag of the scale bar
let scale_bar_menu = `