fc877f32c3c4a79095cdfc916bf463bd25948ef9
angie
  Sat May 30 08:35:31 2026 -0700
Fixing SVG-saving bug and minor issues found by Claude review.

diff --git src/hg/js/hgPhyloPlace.js src/hg/js/hgPhyloPlace.js
index 8d583e8f8c9..bffba7e02d6 100644
--- src/hg/js/hgPhyloPlace.js
+++ src/hg/js/hgPhyloPlace.js
@@ -351,31 +351,31 @@
             console.error("baseColor: Invalid base '" + base + "'");
             color = '#FFFF00';
         }
         return color;
     }
 
     function addBase(svg, base, x, y, isRef, isInformative) {
         // Draw a base as a rectangle colored by value and informativeness with the base value in white
         addRectFill(svg, x, y, cfg.baseWidth, cfg.baseWidth, baseColor(base, isRef, isInformative));
         addText(svg, base, x + cfg.baseTextPad, y + cfg.baseWidth - cfg.baseTextPad, { 'fill': 'white' });
     }
 
     function addBaseArray(svg, x, y, combinedMuts) {
         // Add base value at each position for acceptor, recombinant, donor and reference
         for (let column of combinedMuts) {
-            const isInformative = (column.aAl !== column.dAl && (column.rAl === column.aAl || column.rAl == column.dAl));
+            const isInformative = (column.aAl !== column.dAl && (column.rAl === column.aAl || column.rAl === column.dAl));
             let yBase = y;
             let isRef = (column.aAl === column.ref);
             addBase(svg, column.aAl, x, yBase, isRef, isInformative && !isRef);
             yBase += cfg.basePitch;
             isRef = (column.rAl === column.ref);
             addBase(svg, column.rAl, x, yBase, isRef, isInformative && !isRef);
             yBase += cfg.basePitch;
             isRef = (column.dAl === column.ref);
             addBase(svg, column.dAl, x, yBase, isRef, isInformative && !isRef);
             yBase += cfg.basePitch;
             addBase(svg, column.ref, x, yBase, true, true);
             x += cfg.basePitch;
         }
     }
 
@@ -432,31 +432,30 @@
         }
         return out;
     }
 
     function estimateTextWidth(text) {
         // SVG text won't reveal its size until it's rendered.  Return a guess based on an assumption of font size
         // relative to baseWidth, and font width relative to font height.
         return text.length * cfg.baseWidth * 0.5;
     }
 
     function addGenomeScale(svg, x, y, width, genomeSize, genomeScale) {
         // Add tick marks and centered text labels underneath the genome graph
         const genomeSizeString = commafy(genomeSize);
         const maxLabelWidth = estimateTextWidth(genomeSizeString);
         const maxBins = Math.floor(width / (maxLabelWidth * 1.5));
-        const powerOf10 = Math.ceil(Math.log10(genomeSize));
         const tickTextY = y + 3 * cfg.topPad;
         for (let binSize of [100, 200, 500, 1000, 200, 5000, 10000, 20000, 50000, 100000, 200000, 500000, 1000000]) {
             let binCount = Math.ceil(genomeSize / binSize);
             if (binCount < maxBins) {
                 for (let gx = 0;  gx < genomeSize;  gx += binSize) {
                     const xOff = gx * genomeScale;
                     const tickX = x + xOff;
                     addTick(svg, tickX, y, cfg.tickHeight);
                     // Don't write label if it might overlap with the label at the end of the genome
                     if (width - xOff > maxLabelWidth) {
                         addText(svg, commafy(gx), tickX, tickTextY, { fill: 'black', 'text-anchor': 'middle' });
                     }
                 }
                 break;
             }
@@ -517,31 +516,31 @@
         y += cfg.posLabelAreaHeight;
         addBaseArray(svg, x, y, combinedMuts);
 
         // Connectors between base values and genomic coordinates
         y += cfg.baseArrayHeight;
         const genomeScale = baseAreaWidth / genomeSize;
         const genomeY = y + cfg.connectorAreaHeight;
         addConnectors(svg, x, y, genomeY, genomeScale, combinedMuts);
 
         // Genomic coordinate graph with mut lines
         y += cfg.connectorAreaHeight;
         addGenomeGraph(svg, x, y, baseAreaWidth, cfg.genomeGraphHeight, genomeScale, combinedMuts);
 
         // Genome coordinate scale ticks and labels
         y += cfg.genomeGraphHeight;
-        addGenomeScale(svg, x, y, baseAreaWidth, genomeSize, genomeScale, genes);
+        addGenomeScale(svg, x, y, baseAreaWidth, genomeSize, genomeScale);
 
         // Gene graph with embedded labels
         y += cfg.genomeScaleHeight;
         addGeneGraph(svg, x, y, baseAreaWidth, cfg.geneGraphHeight, genomeScale, genes);
         return svg;
     }
 
     return { draw: draw };
 
 }()); // recombinantGraph
 
 
 
   ////////////////////////////////////////////////////////////
  //// popupRecombinant: pop up a recombinantGraph dialog ////
@@ -629,31 +628,31 @@
             }
         });
         $nextBtn.on('click', function() {
             if (recombinantIndex < recombinantData.recombinants.length - 1) {
                 recombinantIndex++;
                 $prevBtn.prop('disabled', recombinantIndex < 1);
                 $nextBtn.prop('disabled', recombinantIndex >= recombinantData.recombinants.length - 1);
                 recombAttrs = recombinantData.recombinants[recombinantIndex];
                 $div.children("svg").remove();
                 $div.append(recombinantGraph.draw(recombAttrs, genomeSize, genes, showInformativeOnly));
             }
         });
         // Save image button
         let $saveImgBtn = $('#saveSvg');
         $saveImgBtn.on('click', function() {
-            saveSvg(svg, "recombinant.svg");
+            saveSvg($div.children("svg")[0], "recombinant.svg");
         });
 
         var uiDialogButtons = {
             Close: function() {
                 $(this).dialog("close");
             }
         };
         $('#recombinantDialog').dialog({
             resizable: false,
             height: popMaxHeight,
             width: popMaxWidth,
             minHeight: 200,
             minWidth: 400,
             modal: true,
             closeOnEscape: true,