1f5a7c5b430943462e3fed00385b4112a65e5f9d jcasper Thu May 12 15:31:45 2022 -0700 First pass - fixing a barChart draw issue and enabling the trackDb minimum width/padding variables, refs #28062 diff --git src/hg/hgTracks/barChartTrack.c src/hg/hgTracks/barChartTrack.c index 162287f..3c967e2 100644 --- src/hg/hgTracks/barChartTrack.c +++ src/hg/hgTracks/barChartTrack.c @@ -763,67 +763,63 @@ drawGraphBox(tg, itemInfo, hvg, x0, yZero+1); struct rgbColor lineColor = {.r=0}; int lineColorIx = hvGfxFindColorIx(hvg, lineColor.r, lineColor.g, lineColor.b); int barWidth = extras->barWidth; char *colorScheme = cartUsualStringClosestToHome(cart, tg->tdb, FALSE, BAR_CHART_COLORS, BAR_CHART_COLORS_DEFAULT); Color clipColor = MG_MAGENTA; // draw bar graph int i; int expCount = bed->expCount; struct barChartCategory *categ; int barCount = filteredCategoryCount(extras), barsDrawn = 0; double invCount = 1.0/barCount; -char *userSettingMinBarWidth = trackDbSetting(tg->tdb, BAR_CHART_USER_BAR_MIN_WIDTH); -int userMinBarWidth = 0; -if (userSettingMinBarWidth) - userMinBarWidth = sqlUnsigned(userSettingMinBarWidth); + for (i=0, categ=extras->categories; i<expCount && categ != NULL; i++, categ=categ->next) { if (!filterCategory(extras, categ->name)) continue; + + int cStart = barsDrawn * graphWidth * invCount; + int cEnd = (barsDrawn+1) * graphWidth * invCount; + // note - removed userMinBarWidth here, as it's already been imposed in the initial barWidth calculation. + // Stretch mode only ever extends bars, not shrinks them, so the minimum doesn't need to be re-imposed here. + barWidth = cEnd - cStart - extras->padding; + // stop before going off the right edge + if (x1 + barWidth > x0 + graphWidth) + break; + struct rgbColor fillColor = extras->colors[i]; int fillColorIx = hvGfxFindColorIx(hvg, fillColor.r, fillColor.g, fillColor.b); double expScore = bed->expScores[i]; int height = valToClippedHeight(expScore, extras->maxMedian, extras->maxViewLimit, extras->maxHeight, extras->doLogTransform); boolean isClipped = (!extras->doLogTransform && expScore > extras->maxViewLimit); int barTop = yZero - height + 1; + if (extras->padding == 0 || sameString(colorScheme, BAR_CHART_COLORS_USER)) - { - int cStart = barsDrawn * graphWidth * invCount; - int cEnd = (barsDrawn+1) * graphWidth * invCount; - if (i >= 1) - x1 += barWidth + extras->padding; - barWidth = max(userMinBarWidth, cEnd - cStart - extras->padding); - if (x1 + barWidth > x0 + graphWidth) - break; hvGfxBox(hvg, x1, barTop, barWidth, height, fillColorIx); - if (isClipped) - hvGfxBox(hvg, x1, barTop, barWidth, 2, clipColor); - barsDrawn += 1; - } else - { hvGfxOutlinedBox(hvg, x1, barTop, barWidth, height, fillColorIx, lineColorIx); + // mark clipped bar with magenta tip if (isClipped) hvGfxBox(hvg, x1, barTop, barWidth, 2, clipColor); - x1 = x1 + barWidth + extras->padding; - } + x1 += barWidth + extras->padding; + barsDrawn += 1; } } static char *chartMapText(struct track *tg, struct barChartCategory *categ, double expScore) /* Construct mouseover text for a chart bar */ { static char buf[256]; struct barChartTrack *extras = (struct barChartTrack *)tg->extraUiData; safef(buf, sizeof(buf), "%s (%.1f %s)", categ->label, expScore, extras->unit); subChar(buf, '_', ' '); return buf; } static int barChartItemStart(struct track *tg, void *item) /* Return end chromosome coordinate of item, including graph */ @@ -895,65 +891,64 @@ 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); int graphX = barChartX(bed); int graphWidth = chartWidth(tg, itemInfo); int barCount = filteredCategoryCount(extras); char label[256]; -char *userSettingMinBarWidth= trackDbSetting(tg->tdb, BAR_CHART_USER_BAR_MIN_WIDTH); -int userMinBarWidth = 0; -if (userSettingMinBarWidth) - userMinBarWidth = sqlUnsigned(userSettingMinBarWidth); 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; int x1 = x0; double invCount = 1.0/barCount; int i = 0, barsDrawn = 0, width = 0; int extraAtTop = 4; for (categ = categs; categ != NULL; categ = categ->next, i++) { if (!filterCategory(extras, categ->name)) continue; x1 += width; int cStart = barsDrawn * graphWidth * invCount; barsDrawn += 1; int cEnd = barsDrawn * graphWidth * invCount; - width = max(userMinBarWidth, max(1, cEnd - cStart)); + width = max(1, cEnd - cStart); + int boxWidth = min(1, width - extras->padding); // forcing min 1 shouldn't ever actually happen, I think 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, x1, yZero-height, width, height, + mapBoxHc(hvg, itemStart, itemEnd, x1, yZero-height, boxWidth, height, tg->track, mapItemName, chartMapText(tg, categ, expScore)); } safef(label, sizeof(label), "%s - click for faceted view or hover over a bar for sample values", itemName); } else + // We should never get here; chartWidth always returns a value where at least one pixel + // of width is allocated to every category being drawn safef(label, sizeof(label), "%s - zoom in to resolve individual bars or click for details", itemName); // map over background of chart getItemX(start, end, &x1, &x2); mapBoxHc(hvg, itemStart, itemEnd, x1, y, graphWidth, itemHeight-3, tg->track, mapItemName, label); } /* 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);