b37fd074677d8316e79536f2755106cf50ba2b8b kent Sun Jan 24 12:02:07 2021 -0800 Making dense/squish behavior same as old barChart since it already is proportional. Making the squish mode's notion of tissue specificity scale to a greater or lesser number of bars in a somewhat sensible way while maintaining compatibility with GTEX in 54 bar case. diff --git src/hg/hgTracks/barChartTrack.c src/hg/hgTracks/barChartTrack.c index 7b3e8f4..2a00a72 100644 --- src/hg/hgTracks/barChartTrack.c +++ src/hg/hgTracks/barChartTrack.c @@ -169,60 +169,60 @@ static int filteredCategoryCount(struct barChartTrack *extras) /* Count of categories to display */ { return hashNumEntries(extras->categoryFilter); } static boolean filterCategory(struct barChartTrack *extras, char *name) /* Does category pass filter */ { if (name == NULL) return FALSE; return (hashLookup(extras->categoryFilter, name) != NULL); } -static int maxCategoryForItem(struct bed *bed, int threshold) +static int maxCategoryForItem(struct bed *bed) /* Return id of highest valued category for an item, if significantly higher than median. * If none are over threshold, return -1 */ { double maxScore = 0.0, expScore; double totalScore = 0.0; int maxNum = 0, i; int expCount = bed->expCount; for (i=0; iexpScores[i]; if (expScore > maxScore) { maxScore = max(maxScore, expScore); maxNum = i; } totalScore += expScore; } -// threshold to consider this item category specific -- a category contributes > threshold % to -// total level -if (totalScore < 1 || maxScore <= (totalScore * threshold * .01)) +double threshold = 5.4 * totalScore / bed->expCount; /* The 54 cats in and 10% of that for backwards + * compatability */ +if (totalScore < 1 || maxScore <= threshold) return -1; return maxNum; } static Color barChartItemColor(struct track *tg, void *item, struct hvGfx *hvg) /* A bit of category-specific coloring in squish mode only, on bed item */ { struct bed *bed = item; -int id = maxCategoryForItem(bed, SPECIFICITY_THRESHOLD); +int id = maxCategoryForItem(bed); if (id < 0) return MG_BLACK; struct barChartTrack *extras = (struct barChartTrack *)tg->extraUiData; struct rgbColor color = extras->colors[id]; return hvGfxFindColorIx(hvg, color.r, color.g, color.b); } // Convenience functions for draw static int valToHeight(double val, double maxVal, int maxHeight, boolean doLogTransform) /* Log-scale and convert a value from 0 to maxVal to 0 to maxHeight-1 */ { if (val == 0.0) return 0; double scaled = 0.0; @@ -258,37 +258,44 @@ int i; double maxExp = 0.0; int expCount = bed->expCount; double expScore; for (i=0; iexpScores[i]; maxExp = max(maxExp, expScore); } return valToClippedHeight(maxExp, extras->maxMedian, extras->maxViewLimit, extras->maxHeight, extras->doLogTransform); } -static int chartItemHeightOptionalMax(struct track *tg, void *item, boolean isMax) +enum trackVisibility trackVisAfterLimit(struct track *tg) +/* Somewhat carefully figure out track visibility after limits may or may not have been set */ { -// It seems that this can be called early or late -struct barChartTrack *extras = (struct barChartTrack *)tg->extraUiData; enum trackVisibility vis = tg->visibility; if (tg->limitedVisSet) vis = tg->limitedVis; +return vis; +} + +static int chartItemHeightOptionalMax(struct track *tg, void *item, boolean isMax) +{ +struct barChartTrack *extras = tg->extraUiData; +// It seems that this can be called early or late +enum trackVisibility vis = trackVisAfterLimit(tg); int height; if (vis == tvSquish || vis == tvDense) { if (vis == tvSquish) { tg->lineHeight = extras->squishHeight; tg->heightPer = tg->lineHeight; } height = tgFixedItemHeight(tg, item); return height; } if (isMax) { int extra = 0; @@ -652,31 +659,31 @@ * pack or full mode. Just single map for squish/dense modes */ { if (tg->limitedVis == tvDense) { genericMapItem(tg, hvg, item, itemName, itemName, start, end, x, y, width, height); return; } struct barChartTrack *extras = (struct barChartTrack *)tg->extraUiData; struct barChartItem *itemInfo = (struct barChartItem *)item; struct bed *bed = itemInfo->bed; int itemStart = bed->chromStart; int itemEnd = bed->chromEnd; int x1, x2; if (tg->limitedVis == tvSquish) { - int categId = maxCategoryForItem(bed, SPECIFICITY_THRESHOLD); + int categId = maxCategoryForItem(bed); char *maxCateg = ""; if (categId > 1) maxCateg = getCategoryLabel(tg, categId); char buf[128]; safef(buf, sizeof buf, "%s %s", bed->name, maxCateg); getItemX(itemStart, itemEnd, &x1, &x2); int width = max(1, x2-x1); mapBoxHc(hvg, itemStart, itemEnd, x1, y, width, height, tg->track, mapItemName, buf); return; } int topGraphHeight = chartHeight(tg, itemInfo); topGraphHeight = max(topGraphHeight, tl.fontHeight); // label int yZero = topGraphHeight + y - 1; // yZero is bottom of graph @@ -839,30 +846,36 @@ else barThinner = 0.75; } int iStart = baseWidth*barIx/barCount; int iEnd = baseWidth*(barIx+1)/barCount; int iWidth = iEnd - iStart; int start = *pStart = iStart + bed->chromStart; *pEnd = start + iWidth*barThinner; } static void barsToGeneDrawAt(struct track *tg, void *item, struct hvGfx *hvg, int xOff, int y, double scale, MgFont *font, Color color, enum trackVisibility vis) /* Draw bar chart over item in proportional to gene way*/ { +if (vis != tvFull && vis != tvPack) + { + barChartDrawAt(tg, item, hvg, xOff, y, scale, font, color, vis); + return; + } + /* Fetch our item and the bed from it */ struct barChartItem *itemInfo = (struct barChartItem *)item; struct bed *bed = itemInfo->bed; /* Figure out where to draw things in Y dimension */ struct barChartTrack *extras = (struct barChartTrack *)tg->extraUiData; int topGraphHeight = chartHeight(tg, itemInfo); topGraphHeight = max(topGraphHeight, tl.fontHeight); int yZero = topGraphHeight + y - 1; // yZero is bottom of graph int yGene = yZero + extras->margin; /* Figure out width between bars */ int barCount = bed->expCount; // drawScaledBox(hvg, bed->chromStart, bed->chromEnd, scale, xOff, y, topGraphHeight, MG_YELLOW); // ugly debug @@ -881,30 +894,37 @@ drawScaledBox(hvg, cStart, cEnd, scale, xOff, y+topGraphHeight-height, height, color); if (!extras->doLogTransform && expScore > extras->maxViewLimit) drawScaledBox(hvg, cStart, cEnd, scale, xOff, yZero-height+1, 2, clipColor); } // Draw the line our graph sits on top of drawScaledBox(hvg, bed->chromStart, bed->chromEnd, scale, xOff, yGene+1, extras->boxModelHeight, MG_GRAY); } static void barsToGeneMapItem(struct track *tg, struct hvGfx *hvg, void *item, char *itemName, char *mapItemName, int start, int end, int x, int y, int width, int height) /* Create a map box on item and label, and one for each category (bar in the graph) */ { +enum trackVisibility vis = trackVisAfterLimit(tg); +if (vis != tvFull && vis != tvPack) + { + barChartMapItem(tg, hvg, item, itemName, mapItemName, start, end, x, y, width, height); + return; + } + struct barChartTrack *extras = tg->extraUiData; struct barChartItem *itemInfo = item; struct bed *bed = itemInfo->bed; if (width > bed->expCount) // When get down to less than a pixel suppress the bar-by-bar map boxes*/ { int i = 0; struct barChartCategory *categs = getCategories(tg); struct barChartCategory *categ; int topGraphHeight = chartHeight(tg, itemInfo); double scale = scaleForWindow(insideWidth, winStart, winEnd); for (categ = categs; categ != NULL; categ = categ->next, i++) { int cStart, cEnd; findBarPosX(bed, scale, i, bed->expCount, &cStart, &cEnd); int x1,x2;