5839fc5f68fc919fc61fad936929af799c52f577
angie
  Fri Apr 3 12:08:21 2020 -0700
Add RGB colors to Nextstrain trees as fake branch lengths.  Make hapClusterMethod treeFile use branch lengths as RGB colors.  refs #25278

diff --git src/hg/hgTracks/vcfTrack.c src/hg/hgTracks/vcfTrack.c
index 76913db..90b611f 100644
--- src/hg/hgTracks/vcfTrack.c
+++ src/hg/hgTracks/vcfTrack.c
@@ -1387,118 +1387,120 @@
     coords->depth = maxDepth + 1;
     }
 else
     {
     // Leaf (sample)
     double rankStart = leafOrderToHapOrderStart[leafIx];
     double rankEnd = leafOrderToHapOrderStart[leafIx];
     coords->rank = (rankStart + rankEnd) / 2.0;
     leafIx++;
     coords->depth = 0;
     }
 return leafIx;
 }
 
 static void rDrawPhyloTreeInLabelArea(struct phyloTree *node, struct hvGfx *hvg, int x,
-                                      int yOff, double pxPerHap, Color color, MgFont *font,
+                                      int yOff, double pxPerHap, MgFont *font,
                                       boolean drawRectangle)
-/* Recursively draw the tree in the left label area.
- * Returns pixel height for use at non-leaf levels of tree. */
+/* Recursively draw the tree in the left label area. */
 {
 const int branchW = 4;
 int labelEnd = leftLabelX + leftLabelWidth;
-
+// Misuse the branch length value as RGB color (if it's the typical small number, will still
+// draw as approximately black):
+unsigned int rgb = node->ident->length;
+Color color = MAKECOLOR_32( ((rgb>>16)&0xff), ((rgb>>8)&0xff), (rgb&0xff) );
 
 if (node->numEdges > 0)
     {
     // Draw each child and a horizontal line to child
     int minY = -1, maxY = 0;
     int ix;
     for (ix = 0;  ix < node->numEdges;  ix++)
         {
         struct phyloTree *child = node->edges[ix];
-        rDrawPhyloTreeInLabelArea(child, hvg, x+branchW, yOff, pxPerHap, color, font, drawRectangle);
+        rDrawPhyloTreeInLabelArea(child, hvg, x+branchW, yOff, pxPerHap, font, drawRectangle);
         struct nodeCoords *childCoords = child->priv;
         int childY = yOff + ((0.5 + childCoords->rank) * pxPerHap);
-        hvGfxLine(hvg, x, childY, x+branchW, childY, MG_BLACK);
+        hvGfxLine(hvg, x, childY, x+branchW, childY, color);
         if (minY < 0 || childY < minY)
             minY = childY;
         if (childY > maxY)
             maxY = childY;
         }
     // Draw a vertical line to connect the children
-    hvGfxLine(hvg, x, minY, x, maxY, MG_BLACK);
+    hvGfxLine(hvg, x, minY, x, maxY, color);
     }
 else
     {
-    // Leaf node -- draw a horizontal line
+    // Leaf node -- draw a horizontal line, and label if there is space to right of tree
     struct nodeCoords *coords = node->priv;
     int y = yOff + ((0.5 + coords->rank) * pxPerHap);
     hvGfxLine(hvg, x, y, x+branchW, y, color);
     int textX = x + branchW + 3;
     if (pxPerHap >= tl.fontHeight+1 && textX < labelEnd)
-        hvGfxText(hvg, textX, y, color, font, node->ident->name);
+        hvGfxText(hvg, textX, y, MG_BLACK, font, node->ident->name);
     }
 }
 
 static void drawPhyloTreeInLabelArea(struct phyloTree *tree, struct hvGfx *hvg, int yOff,
                                      int clipHeight, int gtHapCount,
-                                     Color color, MgFont *font, boolean drawRectangle,
+                                     MgFont *font, boolean drawRectangle,
                                      unsigned short *leafOrderToHapOrderStart,
                                      unsigned short *leafOrderToHapOrderEnd)
 {
 struct hvGfx *hvgLL = (hvgSide != NULL) ? hvgSide : hvg;
 int clipXBak, clipYBak, clipWidthBak, clipHeightBak;
 hvGfxGetClip(hvgLL, &clipXBak, &clipYBak, &clipWidthBak, &clipHeightBak);
 hvGfxUnclip(hvgLL);
 hvGfxSetClip(hvgLL, leftLabelX, yOff, leftLabelWidth, clipHeight);
 // Figure out rank (vertical position) and depth (horizontal position) of every node in tree:
 phyloTreeAddNodeCoords(tree, leafOrderToHapOrderStart, leafOrderToHapOrderEnd, 0);
 // Draw the tree:
 int x = leftLabelX;
 double pxPerHap = (double)clipHeight / gtHapCount;
-rDrawPhyloTreeInLabelArea(tree, hvgLL, x, yOff, pxPerHap, color, font, drawRectangle);
+rDrawPhyloTreeInLabelArea(tree, hvgLL, x, yOff, pxPerHap, font, drawRectangle);
 // Restore the prior clipping:
 hvGfxUnclip(hvgLL);
 hvGfxSetClip(hvgLL, clipXBak, clipYBak, clipWidthBak, clipHeightBak);
 }
 
 static void vcfGtHapTreeFileDraw(struct track *tg, int seqStart, int seqEnd,
                                  struct hvGfx *hvg, int xOff, int yOff, int width,
                                  MgFont *font, Color color, enum trackVisibility vis)
 /* Draw rows in the same fashion as vcfHapClusterDraw, but instead of clustering, use the
  * order in which samples appear in the VCF file. */
 {
 struct vcfFile *vcff = tg->extraUiData;
 enum hapColorMode colorMode;
 if (!vcfHapClusterDrawInit(tg, vcff, hvg, &colorMode))
     return;
 struct phyloTree *tree = getTreeFromFile(tg->tdb);
 int gtHapCount;
 unsigned short *leafOrderToHapOrderStart, *leafOrderToHapOrderEnd;
 unsigned short *gtHapOrder = gtHapOrderFromTree(vcff, tree,
                                                 &leafOrderToHapOrderStart, &leafOrderToHapOrderEnd,
                                                 &gtHapCount);
 struct vcfRecord *rec;
 for (rec = vcff->records;  rec != NULL;  rec = rec->next)
     drawOneRec(rec, gtHapOrder, gtHapCount, tg, hvg, xOff, yOff, width, FALSE, FALSE,
                colorMode);
 int extraPixel = (colorMode == altOnlyMode) ? 1 : 0;
 int hapHeight = tg->height - CLIP_PAD - 2*extraPixel;
 char *treeAngle = cartOrTdbString(cart, tg->tdb, VCF_HAP_TREEANGLE_VAR, VCF_DEFAULT_HAP_TREEANGLE);
 boolean drawRectangle = sameString(treeAngle, VCF_HAP_TREEANGLE_RECTANGLE);
-drawPhyloTreeInLabelArea(tree, hvg, yOff+extraPixel, hapHeight, gtHapCount, color, font,
+drawPhyloTreeInLabelArea(tree, hvg, yOff+extraPixel, hapHeight, gtHapCount, font,
                          drawRectangle, leafOrderToHapOrderStart, leafOrderToHapOrderEnd);
 drawSampleTitles(vcff, yOff+extraPixel, hapHeight, gtHapOrder, gtHapCount, tg->track);
 }
 
 static int vcfHapClusterTotalHeight(struct track *tg, enum trackVisibility vis)
 /* Return height of haplotype graph (2 * #samples * lineHeight);
  * 2 because we're assuming diploid genomes here, no XXY, tetraploid etc. */
 {
 const struct vcfFile *vcff = tg->extraUiData;
 if (vcff->records == NULL)
     return 0;
 int ploidy = sameString(chromName, "chrY") ? 1 : 2;
 int simpleHeight = ploidy * vcff->genotypeCount * tg->lineHeight;
 int defaultHeight = min(simpleHeight, VCF_DEFAULT_HAP_HEIGHT);
 char *tdbHeight = trackDbSettingOrDefault(tg->tdb, VCF_HAP_HEIGHT_VAR, NULL);