5770f49f480bbfe5d920ece22f96961954e43116
angie
  Mon Aug 29 15:23:51 2011 -0700
Feature #3711 (VCF haplotype-sorting display): Changing appearance ofcluster tree in the left label area.  I was drawing trees as I had seen
in microarray & other clustering tools, but David wants something more
compatible with the species-tree view... I'll just quote David here:

It has to look like a legitmate species tree, exactly like the ones on
the details page of the vertebrate conservation track. The only
difference here is that some leaf objects are fatter than other, and it
is not clear where one leaf begins and the other ends.

You need to

1. always draw the branch all the way to the right side (leaf level) so
all the leaves are at the leaf level.

2. The vertical bar representing the "footprint" of each leaf (i.e. the
span of the rows of that cluster) needs to terminate at least 1 or 2
pixels before the edge of the cluster of rows for a given leaf, so there
is white space between clusters. (Or put a colored or bold or vertical
mark at the edge of a cluster of rows.)

diff --git src/hg/hgTracks/vcfTrack.c src/hg/hgTracks/vcfTrack.c
index 65088f8..944cedc 100644
--- src/hg/hgTracks/vcfTrack.c
+++ src/hg/hgTracks/vcfTrack.c
@@ -490,95 +490,103 @@
     {
     yrtMidPoint,
     yrtStart,
     yrtEnd,
     };
 
 /* Callback for calculating y (in pixels) for a cluster node: */
 typedef int yFromNodeFunc(const struct slList *itemOrCluster, void *extraData,
 			  enum yRetType yType);
 
 static int rDrawTreeInLabelArea(struct hacTree *ht, struct hvGfx *hvg, enum yRetType yType, int x,
 				yFromNodeFunc *yFromNode, void *extraData)
 /* Recursively draw the haplotype clustering tree in the left label area.
  * Returns pixel height for use at non-leaf levels of tree. */
 {
-const int branchW = 4;
-int labelEnd = leftLabelX + leftLabelWidth;
+const int branchW = 3;
+const Color boundaryColor = MG_RED;
+const int labelEnd = leftLabelX + leftLabelWidth;
+const int rightEdge = labelEnd - 1;
 if (yType == yrtStart || yType == yrtEnd)
     {
     // We're just getting vertical span of a leaf cluster, not drawing any lines.
     int yLeft, yRight;
     if (ht->left)
 	yLeft = rDrawTreeInLabelArea(ht->left, hvg, yType, x, yFromNode, extraData);
     else
 	yLeft = yFromNode(ht->itemOrCluster, extraData, yType);
     if (ht->right)
 	yRight = rDrawTreeInLabelArea(ht->right, hvg, yType, x, yFromNode, extraData);
     else
 	yRight = yFromNode(ht->itemOrCluster, extraData, yType);
     if (yType == yrtStart)
 	return min(yLeft, yRight);
     else
 	return max(yLeft, yRight);
     }
 // Otherwise yType is yrtMidPoint.  If we have 2 children, we'll be drawing some lines:
 if (ht->left != NULL && ht->right != NULL)
     {
+    const int nextX = x + branchW;
     int midY;
     if (ht->childDistance == 0 || x+(2*branchW) > labelEnd)
 	{
 	// Treat this as a leaf cluster.
 	// Recursing twice is wasteful. Could be avoided if this, and yFromNode,
 	// returned both yStart and yEnd. However, the time to draw a tree of
 	// 2188 hap's (1kG phase1 interim) is in the noise, so I consider it
 	// not worth the effort of refactoring to save a sub-millisecond here.
-	int yStartLeft = rDrawTreeInLabelArea(ht->left, hvg, yrtStart, x+branchW,
+	int yStartLeft = rDrawTreeInLabelArea(ht->left, hvg, yrtStart, nextX,
 					      yFromNode, extraData);
-	int yEndLeft = rDrawTreeInLabelArea(ht->left, hvg, yrtEnd, x+branchW,
+	int yEndLeft = rDrawTreeInLabelArea(ht->left, hvg, yrtEnd, nextX,
 					    yFromNode, extraData);
-	int yStartRight = rDrawTreeInLabelArea(ht->right, hvg, yrtStart, x+branchW,
+	int yStartRight = rDrawTreeInLabelArea(ht->right, hvg, yrtStart, nextX,
 					       yFromNode, extraData);
-	int yEndRight = rDrawTreeInLabelArea(ht->right, hvg, yrtEnd, x+branchW,
+	int yEndRight = rDrawTreeInLabelArea(ht->right, hvg, yrtEnd, nextX,
 					     yFromNode, extraData);
 	int yStart = min(yStartLeft, yStartRight);
 	int yEnd = max(yEndLeft, yEndRight);
 	midY = (yStart + yEnd) / 2;
-	hvGfxLine(hvg, x+branchW-1, yStart, x+branchW-1, yEnd-1, MG_BLACK);
-	hvGfxLine(hvg, x+branchW, yStart, labelEnd, yStart, MG_BLACK);
-	hvGfxLine(hvg, x+branchW, yEnd-1, labelEnd, yEnd-1, MG_BLACK);
+	Color branchColor = (ht->childDistance == 0) ? MG_BLACK : shadesOfGray[5];
+	hvGfxLine(hvg, x, midY, rightEdge, midY, branchColor);
+	hvGfxLine(hvg, rightEdge, yStart, rightEdge, yEnd-1, branchColor);
+	hvGfxLine(hvg, max(rightEdge-1, x), yStart, rightEdge, yStart, boundaryColor);
+	hvGfxLine(hvg, max(rightEdge-1, x), yEnd-1, rightEdge, yEnd-1, boundaryColor);
 	}
     else
 	{
-	int leftMid = rDrawTreeInLabelArea(ht->left, hvg, yrtMidPoint, x+branchW,
+	int leftMid = rDrawTreeInLabelArea(ht->left, hvg, yrtMidPoint, nextX,
 					   yFromNode, extraData);
-	int rightMid = rDrawTreeInLabelArea(ht->right, hvg, yrtMidPoint, x+branchW,
+	int rightMid = rDrawTreeInLabelArea(ht->right, hvg, yrtMidPoint, nextX,
 					    yFromNode, extraData);
 	midY = (leftMid + rightMid) / 2;
-	hvGfxLine(hvg, x+branchW-1, leftMid, x+branchW-1, rightMid, MG_BLACK);
+	hvGfxLine(hvg, nextX-1, leftMid, nextX-1, rightMid, MG_BLACK);
+	hvGfxLine(hvg, x, midY, nextX-1, midY, MG_BLACK);
 	}
-    hvGfxLine(hvg, x, midY, x+branchW-1, midY, MG_BLACK);
     return midY;
     }
 else if (ht->left != NULL)
     return rDrawTreeInLabelArea(ht->left, hvg, yType, x, yFromNode, extraData);
 else if (ht->right != NULL)
     return rDrawTreeInLabelArea(ht->right, hvg, yType, x, yFromNode, extraData);
 // Leaf node -- return pixel height. Draw a line if yType is midpoint.
 int y = yFromNode(ht->itemOrCluster, extraData, yType);
 if (yType == yrtMidPoint && x < labelEnd)
-    hvGfxLine(hvg, x, y, labelEnd, y, MG_BLACK);
+    {
+    hvGfxLine(hvg, x, y, rightEdge, y, MG_BLACK);
+    hvGfxLine(hvg, max(rightEdge-1, x), y, rightEdge, y, boundaryColor);
+    }
 return y;
 }
 
 struct yFromNodeHelper
 /* Pre-computed mapping from cluster nodes' gtHapIx to pixel heights. */
     {
     unsigned short gtHapCount;
     unsigned short *gtHapIxToPxStart;
     unsigned short *gtHapIxToPxEnd;
     };
 
 void initYFromNodeHelper(struct yFromNodeHelper *helper, int yOff, int height,
 			 unsigned short gtHapCount, unsigned short *gtHapOrder)
 /* Build a mapping of genotype and haplotype to pixel y coords. */
 {