a693e3b71a0933e2cb6ea62dcb571b8a6a53a17e kent Tue Feb 2 11:23:21 2021 -0800 Quite a bit of refactoring including removing a redundant routine, countFilteredBars. Functionally added two things: a new level of zoom out on the bar chart display (non-fit-to-gene case) and apply filters before doing width calculations so that your bars can get wider when you filter things out. diff --git src/hg/hgTracks/barChartTrack.c src/hg/hgTracks/barChartTrack.c index c9a390b..1dee878 100644 --- src/hg/hgTracks/barChartTrack.c +++ src/hg/hgTracks/barChartTrack.c @@ -28,35 +28,37 @@ char *unit; /* Units for category values (e.g. RPKM) */ struct barChartCategory *categories; /* Category names, colors, etc. */ int categCount; /* Count of categories - derived from above */ char **categNames; /* Category names - derived from above */ char **categLabels; /* Category labels - derived from above */ struct rgbColor *colors; /* Colors for all categories */ struct hash *categoryFilter; /* NULL out excluded factors */ int maxViewLimit; // dimensions for drawing char *maxGraphSize; /* optionally limit graph size (override semantic zoom) small, medium, or large (default) */ int winMaxGraph; /* Draw large graphs if window size smaller than this */ int winMedGraph; /* Draw medium graphs if window size greater than this and smaller than winMaxGraph */ + int winSmallGraph; /* Draw small graphs if windowSize between this and + * win medGraph, draw tiny if smaller */ int squishHeight; /* Height of item in squish mode (larger than typical) */ int boxModelHeight; /* Height of indicator box drawn under graph to show gene extent */ int modelHeight; /* Height of box drawn under graph with padding */ - int barWidth; /* Width of individual bar in pixels */ + double barWidth; /* Width of individual bar in pixels */ int margin; int padding; int maxHeight; }; struct barChartItem /* BED item plus computed values for display */ { struct barChartItem *next; /* Next in singly linked list */ struct bed *bed; /* Item coords, name, exp count and values */ int height; /* Item height in pixels */ }; /***********************************************/ /* Organize category info */ @@ -208,31 +210,31 @@ 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; } double threshold = 5.4 * totalScore / bed->expCount; /* The 54 cats in and 10% of that for backwards - * compatability */ + * compatability with the GTEX 54 element track */ 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); 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); @@ -331,30 +333,45 @@ return itemInfo->height; } int topGraphHeight = chartHeight(tg, itemInfo); topGraphHeight = max(topGraphHeight, tl.fontHeight); int bottomGraphHeight = 0; height = topGraphHeight + bottomGraphHeight + extras->margin + extras->modelHeight; return height; } static int barChartItemHeight(struct track *tg, void *item) { int height = chartItemHeightOptionalMax(tg, item, FALSE); return height; } +static int chartWidth(struct track *tg, struct barChartItem *itemInfo) +{ +struct barChartTrack *extras = (struct barChartTrack *)tg->extraUiData; +if (extras->fitToGene) + { + struct bed *bed = itemInfo->bed; + return scaleForWindow(bed->chromEnd - bed->chromStart, winStart, winEnd); + } +else + { + int count = filteredCategoryCount(extras); + return (extras->barWidth * count) + (extras->padding * (count-1)) + 2; + } +} + static void barChartLoadItems(struct track *tg) /* Load method for track items */ { /* Initialize colors for visibilities that don't display actual barchart */ if (tg->visibility == tvSquish || tg->limitedVis == tvSquish) tg->itemColor = barChartItemColor; tg->colorShades = shadesOfGray; /* Get track UI info */ struct barChartTrack *extras; if (!tg->extraUiData) { AllocVar(extras); tg->extraUiData = extras; } @@ -365,166 +382,168 @@ struct trackDb *tdb = tg->tdb; extras->doLogTransform = barChartIsLogTransformed(cart, tdb->track, tdb); extras->maxMedian = barChartUiMaxMedianScore(tdb); extras->noWhiteout = cartUsualBooleanClosestToHome(cart, tdb, FALSE, BAR_CHART_NO_WHITEOUT, BAR_CHART_NO_WHITEOUT_DEFAULT); extras->fitToGene = trackDbSettingClosestToHomeOn(tdb, BAR_CHART_FIT_TO_GENE); extras->maxViewLimit = barChartCurViewMax(cart, tg->track, tg->tdb); extras->maxGraphSize = trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_MAX_GRAPH_SIZE, BAR_CHART_MAX_GRAPH_SIZE_DEFAULT); extras->unit = trackDbSettingClosestToHomeOrDefault(tdb, BAR_CHART_UNIT, ""); /* Set barchart dimensions to draw. For three window sizes */ #define MAX_BAR_CHART_MODEL_HEIGHT 2 #define MED_BAR_CHART_MODEL_HEIGHT 2 +#define SMALL_BAR_CHART_MODEL_HEIGHT 1 #define MIN_BAR_CHART_MODEL_HEIGHT 1 #define WIN_MAX_GRAPH_DEFAULT 50000 #define MAX_GRAPH_HEIGHT 175 #define MAX_BAR_WIDTH 5 #define MAX_GRAPH_PADDING 2 -#define WIN_MED_GRAPH_DEFAULT 500000 +#define WIN_MED_GRAPH_DEFAULT 300000 #define MED_GRAPH_HEIGHT 100 #define MED_BAR_WIDTH 3 #define MED_GRAPH_PADDING 1 -#define MIN_BAR_WIDTH 1 +#define WIN_SMALL_GRAPH_DEFAULT 2000000 +#define SMALL_GRAPH_HEIGHT 75 +#define SMALL_BAR_WIDTH 1 +#define SMALL_GRAPH_PADDING 0 + +#define MIN_BAR_WIDTH 0.5 #define MIN_GRAPH_PADDING 0 extras->winMaxGraph = WIN_MAX_GRAPH_DEFAULT; extras->winMedGraph = WIN_MED_GRAPH_DEFAULT; +extras->winSmallGraph = WIN_SMALL_GRAPH_DEFAULT; char *setting = trackDbSetting(tdb, BAR_CHART_SIZE_WINDOWS); if (isNotEmpty(setting)) { char *words[2]; int ct = chopLine(setting, words); if (ct == 2) { extras->winMaxGraph = atoi(words[0]); extras->winMedGraph = atoi(words[1]); } } -int barCount = getCategoryCount(tg); + +/* Get bed (names and all-sample category median scores) in range */ +loadSimpleBedWithLoader(tg, (bedItemLoader)barChartSimpleBedLoad); + +/* Create itemInfo items with BED and geneModels */ +struct barChartItem *itemInfo = NULL, *list = NULL; +struct bed *bed = (struct bed *)tg->items; + +/* Test that configuration matches data file */ +if (bed != NULL) + { + int categCount = getCategoryCount(tg); + int expCount = bed->expCount; + if (categCount != expCount) + warn("Bar chart track: category count mismatch between trackDb (%d) and data file (%d)", + categCount, expCount); + } + +filterCategories(tg); + +int barCount = filteredCategoryCount(extras); 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.9; + scale = 0.8; else if (barCount <= 200) - scale = 0.75; + scale = 0.6; else scale = 0.5; 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; + extras->padding = MAX_GRAPH_PADDING * scale; extras->maxHeight = MAX_GRAPH_HEIGHT; } -else if (winSize < extras->winMedGraph && - differentString(extras->maxGraphSize, BAR_CHART_MAX_GRAPH_SIZE_SMALL)) +else if (winSize < extras->winMedGraph) { extras->boxModelHeight = MED_BAR_CHART_MODEL_HEIGHT; extras->barWidth = MED_BAR_WIDTH * scale; - extras->padding = MED_GRAPH_PADDING; + extras->padding = MED_GRAPH_PADDING * scale; extras->maxHeight = MED_GRAPH_HEIGHT; } +else if (winSize < extras->winSmallGraph) + { + extras->boxModelHeight = SMALL_BAR_CHART_MODEL_HEIGHT; + extras->barWidth = SMALL_BAR_WIDTH * scale; + extras->padding = SMALL_GRAPH_PADDING * scale; + extras->maxHeight = SMALL_GRAPH_HEIGHT; + } else { extras->boxModelHeight = MIN_BAR_CHART_MODEL_HEIGHT; extras->barWidth = MIN_BAR_WIDTH * scale; - extras->padding = MIN_GRAPH_PADDING; + extras->padding = MIN_GRAPH_PADDING * scale; extras->maxHeight = tl.fontHeight * 4; } -if (extras->barWidth == 1 && extras->padding == 1) +if (extras->barWidth > 1) + extras->barWidth = floor(extras->barWidth); + +if (extras->barWidth <= 1 && extras->padding == 1) { extras->barWidth = 2; extras->padding = 0; } if (extras->barWidth < 1) - { - extras->barWidth = 1; extras->padding = 0; - } +else + extras->barWidth = round(extras->barWidth); +// uglyAbort("barCount %d, graphSize %s, extras->barWidth = %g, extras->padding = %d, scale = %g", barCount, extras->maxGraphSize, extras->barWidth, extras->padding, scale); extras->modelHeight = extras->boxModelHeight + 3; extras->margin = 1; extras->squishHeight = tl.fontHeight - tl.fontHeight/2; -/* Get bed (names and all-sample category median scores) in range */ -loadSimpleBedWithLoader(tg, (bedItemLoader)barChartSimpleBedLoad); - -/* Create itemInfo items with BED and geneModels */ -struct barChartItem *itemInfo = NULL, *list = NULL; -struct bed *bed = (struct bed *)tg->items; - -/* Test that configuration matches data file */ -if (bed != NULL) - { - int categCount = getCategoryCount(tg); - int expCount = bed->expCount; - if (categCount != expCount) - warn("Bar chart track: category count mismatch between trackDb (%d) and data file (%d)", - categCount, expCount); - } - -filterCategories(tg); - while (bed != NULL) { AllocVar(itemInfo); itemInfo->bed = bed; slAddHead(&list, itemInfo); bed = bed->next; itemInfo->bed->next = NULL; itemInfo->height = barChartItemHeight(tg, itemInfo); } slReverse(&list); tg->items = list; } /***********************************************/ /* Draw */ -static int chartWidth(struct track *tg, struct barChartItem *itemInfo) -{ -struct barChartTrack *extras = (struct barChartTrack *)tg->extraUiData; -if (extras->fitToGene) - { - struct bed *bed = itemInfo->bed; - return scaleForWindow(bed->chromEnd - bed->chromStart, winStart, winEnd); - } -else - { - int count = filteredCategoryCount(extras); - return (extras->barWidth * count) + (extras->padding * (count-1)) + 2; - } -} - static int barChartX(struct bed *bed) /* Locate chart on X, relative to viewport. */ { -int start = max(bed->chromStart, winStart); +int start = max(bed->chromStart, winStart); // Consider making this simply bed->chromStart -jk double scale = scaleForWindow(insideWidth, winStart, winEnd); int x1 = round((start - winStart) * scale); return x1; } static void drawGraphBox(struct track *tg, struct barChartItem *itemInfo, struct hvGfx *hvg, int x, int y) /* Draw white background for graph */ { Color lighterGray = MAKECOLOR_32(0xF3, 0xF3, 0xF3); int width = chartWidth(tg, itemInfo); int height = chartHeight(tg, itemInfo); hvGfxOutlinedBox(hvg, x, y-height, width, height, MG_WHITE, lighterGray); } @@ -578,69 +597,79 @@ { struct barChartItem *itemInfo = (struct barChartItem *)item; int graphWidth = chartWidth(tg, itemInfo); return graphWidth; } static void barChartNonPropDrawAt(struct track *tg, void *item, struct hvGfx *hvg, int xOff, int y, double scale, MgFont *font, Color color, enum trackVisibility vis) { if (vis != tvFull && vis != tvPack) return; struct barChartTrack *extras = (struct barChartTrack *)tg->extraUiData; struct barChartItem *itemInfo = (struct barChartItem *)item; struct bed *bed = itemInfo->bed; int topGraphHeight = chartHeight(tg, itemInfo); +int graphWidth = chartWidth(tg, itemInfo); topGraphHeight = max(topGraphHeight, tl.fontHeight); int yZero = topGraphHeight + y - 1; // yZero is bottom of graph int graphX = barChartX(bed); int x1 = xOff + graphX; // x1 is at left of graph int keepX = x1; drawGraphBase(tg, itemInfo, hvg, keepX, yZero+1); if (!extras->noWhiteout) drawGraphBox(tg, itemInfo, hvg, keepX, 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; +int x0 = x1; for (i=0, categ=extras->categories; inext) { if (!filterCategory(extras, categ->name)) continue; 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); if (extras->padding == 0 || sameString(colorScheme, BAR_CHART_COLORS_USER)) - hvGfxBox(hvg, x1, yZero-height+1, barWidth, height, fillColorIx); + { + int x1 = barsDrawn * graphWidth * invCount; + barsDrawn += 1; + hvGfxBox(hvg, x1 + x0, yZero-height+1, max(1,barWidth), height, fillColorIx); + } else + { hvGfxOutlinedBox(hvg, x1, yZero-height+1, barWidth, height, fillColorIx, lineColorIx); + x1 = x1 + barWidth + extras->padding; + } // mark clipped bar with magenta tip if (!extras->doLogTransform && expScore > extras->maxViewLimit) hvGfxBox(hvg, x1, yZero-height+1, barWidth, 2, clipColor); - x1 = x1 + barWidth + extras->padding; } } static char *chartMapText(struct track *tg, struct barChartCategory *categ, double expScore) /* Construct mouseover text for a chart bar */ { static char buf[128]; 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 */ @@ -661,30 +690,52 @@ } static void getItemX(int start, int end, int *x1, int *x2) /* Return startX, endX based on item coordinates and current window */ // Residual (largely replaced by drawScaledBox -- still used by gene model bmap box { int s = max(start, winStart); int e = min(end, winEnd); double scale = scaleForWindow(insideWidth, winStart, winEnd); assert(x1); *x1 = round((double)((int)s-winStart)*scale + insideX); assert(x2); *x2 = round((double)((int)e-winStart)*scale + insideX); } +static void findBarPosX(int chromStart, int chromEnd, double scale, int barIx, int barCount, int *pStart, int *pEnd) +/* Figure out start/end position of our bar's region */ +{ +int baseWidth = chromEnd - chromStart; +double scaledSize = baseWidth *scale; +double oneWidth = scaledSize/barCount; +double barThinner = 1.0; +if (oneWidth >= 5.0) + { + if (oneWidth > 7.0) + barThinner = 0.8; + else + barThinner = 0.75; + } + +int iStart = baseWidth*barIx/barCount; +int iEnd = baseWidth*(barIx+1)/barCount; +int iWidth = iEnd - iStart; +int start = *pStart = iStart + chromStart; +*pEnd = start + iWidth*barThinner; +} + static void barChartMapItem(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) in * 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; @@ -714,47 +765,52 @@ 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); if (graphX < 0) return; -// x1 is at left of graph -x1 = insideX + graphX; -int i = 0; +int graphWidth = chartWidth(tg, itemInfo); +int x0 = insideX + graphX; +int barCount = filteredCategoryCount(extras); +double invCount = 1.0/barCount; +int i = 0, barsDrawn = 0; 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 = x2-x1; double expScore = bed->expScores[i]; int height = valToClippedHeight(expScore, extras->maxMedian, extras->maxViewLimit, extras->maxHeight, extras->doLogTransform); - mapBoxHc(hvg, itemStart, itemEnd, x1, yZero-height, extras->barWidth + extras->padding, height, + mapBoxHc(hvg, itemStart, itemEnd, x0 + x1, yZero-height, width, height, tg->track, mapItemName, chartMapText(tg, categ, expScore)); x1 = x1 + extras->barWidth + extras->padding; } // map over background of chart -int graphWidth = chartWidth(tg, itemInfo); 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; } /* This is lifted nearly wholesale from gtexGene track. Could be shared */ @@ -840,148 +896,112 @@ struct barChartItem *chartItem = (struct barChartItem *)item; struct bed *bed = chartItem->bed; return bed->name; } static char *barChartItemName(struct track *tg, void *item) /* Return item name for labeling */ { struct barChartItem *chartItem = (struct barChartItem *)item; struct bed *bed = chartItem->bed; if (tg->isBigBed) return bigBedItemName(tg, bed); return bed->name; } -void findBarPosX(struct bed *bed, double scale, int barIx, int barCount, int *pStart, int *pEnd) -/* Figure out start/end position of our bar's region */ -{ -int baseWidth = bed->chromEnd - bed->chromStart; -double scaledSize = baseWidth *scale; -double oneWidth = scaledSize/barCount; -double barThinner = 1.0; -if (oneWidth >= 5.0) - { - if (oneWidth > 7.0) - barThinner = 0.8; - 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 int countFilteredBars(struct track *tg) -/* Count up number of bars that remain after filtering */ -{ -struct barChartTrack *extras = (struct barChartTrack *)tg->extraUiData; -struct barChartCategory *categ; -int count = 0; -for (categ=extras->categories; categ != NULL; categ=categ->next) - { - if (filterCategory(extras, categ->name)) - ++count; - } -return count; -} - 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 = countFilteredBars(tg); +int barCount = filteredCategoryCount(extras); int expCount = bed->expCount; int i; Color clipColor = MG_MAGENTA; int outBarIx = 0; struct barChartCategory *categ; for (i=0, categ=extras->categories; inext) { if (!filterCategory(extras, categ->name)) continue; struct rgbColor rgb = extras->colors[i]; int color = hvGfxFindColorIx(hvg, rgb.r, rgb.g, rgb.b); int cStart, cEnd; - findBarPosX(bed, scale, outBarIx, barCount, &cStart, &cEnd); + findBarPosX(bed->chromStart, bed->chromEnd, scale, outBarIx, barCount, &cStart, &cEnd); double expScore = bed->expScores[i]; int height = valToClippedHeight(expScore, extras->maxMedian, extras->maxViewLimit, extras->maxHeight, extras->doLogTransform); 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); ++outBarIx; } // 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; -int barCount = countFilteredBars(tg); +int barCount = filteredCategoryCount(extras); if (width > barCount) // When get down to less than a pixel suppress the bar-by-bar map boxes*/ { int i = 0; int outBarIx = 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++) { if (!filterCategory(extras, categ->name)) continue; int cStart, cEnd; - findBarPosX(bed, scale, outBarIx, barCount, &cStart, &cEnd); + findBarPosX(bed->chromStart, bed->chromEnd, scale, outBarIx, barCount, &cStart, &cEnd); int x1,x2; if (scaledBoxToPixelCoords(cStart, cEnd, scale, 0, &x1, &x2)) { double expScore = bed->expScores[i]; int height = valToClippedHeight(expScore, extras->maxMedian, extras->maxViewLimit, extras->maxHeight, extras->doLogTransform); mapBoxHc(hvg, bed->chromStart, bed->chromEnd, x1+insideX, y+topGraphHeight-height, x2-x1, height, tg->track, mapItemName, chartMapText(tg, categ, expScore)); } ++outBarIx; } } mapBoxHc(hvg, bed->chromStart, bed->chromEnd, x, y, width, height, tg->track, itemName, NULL); }