dc8c6d138d71dfc4c0be0224de14c2106b9ae61e
kent
  Wed Dec 15 09:21:32 2021 -0800
Making it handle zoomed out views with many bars in the chart better.  Stop making map-boxes for mouse-overs when they are a pixel or less, which sped up the page a lot.  Also expanded sub-pixel scaling with more cases.

diff --git src/hg/hgTracks/barChartTrack.c src/hg/hgTracks/barChartTrack.c
index 9d99304..14dc9ea 100644
--- src/hg/hgTracks/barChartTrack.c
+++ src/hg/hgTracks/barChartTrack.c
@@ -535,43 +535,51 @@
 
 
 filterCategories(tg);
 
 /* Test that configuration matches data file */
 if (bedList != NULL)
     {
     int categCount = getCategoryCount(tg);
     int expCount = bedList->expCount;
     if (categCount != expCount)
         warn("Bar chart track: category count mismatch between trackDb (%d) and data file (%d)",
                             categCount, expCount);
     }
 
 int barCount = filteredCategoryCount(extras);
+
+/* Scaling here is pretty ad-hoc! */
 double scale = 1.0;
 if (barCount <= 20)
     scale = 2.5;
 else if (barCount <= 40)
     scale = 1.6;
 else if (barCount <= 60)
     scale = 1.0;
 else if (barCount <= 120)
     scale = 0.8;
 else if (barCount <= 200)
     scale = 0.6;
-else 
+else  if (barCount <= 300)
     scale = 0.5;
+else  if (barCount <= 500)
+    scale = 0.4;
+else  if (barCount <= 1000)
+    scale = 0.3;
+else
+    scale = 0.2;
 
 long winSize = virtWinBaseCount;
 if (winSize < extras->winMaxGraph && 
         sameString(extras->maxGraphSize, BAR_CHART_MAX_GRAPH_SIZE_LARGE))
     {
     extras->boxModelHeight = MAX_BAR_CHART_MODEL_HEIGHT;
     extras->barWidth = MAX_BAR_WIDTH * scale;
     extras->padding = MAX_GRAPH_PADDING * scale;
     extras->maxHeight = MAX_GRAPH_HEIGHT;
     }
 else if (winSize < extras->winMedGraph)
     {
     extras->boxModelHeight = MED_BAR_CHART_MODEL_HEIGHT;
     extras->barWidth = MED_BAR_WIDTH * scale;
     extras->padding = MED_GRAPH_PADDING * scale;
@@ -838,57 +846,60 @@
 int topGraphHeight = chartHeight(tg, itemInfo);
 topGraphHeight = max(topGraphHeight, tl.fontHeight);        // label
 int yZero = topGraphHeight + y - 1;  // yZero is bottom of graph
 
 // add map box to item label
 
 int labelWidth = mgFontStringWidth(tl.font, itemName);
 getItemX(start, end, &x1, &x2);
 if (x1-labelWidth <= insideX)
     labelWidth = 0;
 // map over label
 int itemHeight = itemInfo->height;
 mapBoxHc(hvg, itemStart, itemEnd, x1-labelWidth, y, labelWidth, itemHeight-3, 
                     tg->track, mapItemName, itemName);
 
-// add maps to category bars
-struct barChartCategory *categs = getCategories(tg);
-struct barChartCategory *categ = NULL;
 
 int graphX = barChartX(bed);
-
 int graphWidth = chartWidth(tg, itemInfo);
-int x0 = insideX + graphX;
 int barCount = filteredCategoryCount(extras);
+
+if (barCount <= graphWidth) // Don't create map boxes if less than one pixel per bar
+    {
+    // add maps to category bars
+    struct barChartCategory *categs = getCategories(tg);
+    struct barChartCategory *categ = NULL;
+    int x0 = insideX + graphX;
     double invCount = 1.0/barCount;
     int i = 0, barsDrawn = 0;
     int extraAtTop = 4;
     for (categ = categs; categ != NULL; categ = categ->next, i++)
 	{
 	if (!filterCategory(extras, categ->name))
 	    continue;
 	x1 = barsDrawn * graphWidth * invCount;
 	barsDrawn += 1;
 	x2 = barsDrawn * graphWidth * invCount;
 	int width = max(1, x2-x1);
 	double expScore = bed->expScores[i];
 	int height = valToClippedHeight(expScore, extras->maxMedian, extras->maxViewLimit,
 					    extras->maxHeight, extras->doLogTransform);
 	height = min(height+extraAtTop, extras->maxHeight);
 	mapBoxHc(hvg, itemStart, itemEnd, x0 + x1, yZero-height, width, height, 
 			    tg->track, mapItemName, chartMapText(tg, categ, expScore));
 	}
+    }
 
 // map over background of chart
 getItemX(start, end, &x1, &x2);
 mapBoxHc(hvg, itemStart, itemEnd, x1, y, graphWidth, itemHeight-3,
                     tg->track, mapItemName, itemName);
 }
 
 /* This is lifted nearly wholesale from gtexGene track.  Could be shared */
 
 static int getBarChartHeight(void *item)
 {
 struct barChartItem *itemInfo = (struct barChartItem *)item;
 assert(itemInfo->height != 0);
 return itemInfo->height;
 }