75b9f337975beb5a9eaec5ff00e48cb878591fd2 braney Fri Aug 7 12:07:35 2026 -0700 bigLolly: reserve top margin from the largest lolly actually drawn, refs #38031 A track that sets lollySizeField scales each radius by the track height, so a lolly can end up bigger than lollyMaxSize. The margins were reserved from lollyMaxSize alone, so once the drawn radius passed it the top row of circles ran off the top of the row and came out flat. Take the larger of the two, which leaves every current picture unchanged since today's radii are all below lollyMaxSize. The same margin positions the y-axis gridlines and the upper and lower value labels, so all three move together and the axis still lines up with the circles. diff --git src/hg/hgTracks/lollyTrack.c src/hg/hgTracks/lollyTrack.c index a29c88174ba..acdf893df89 100644 --- src/hg/hgTracks/lollyTrack.c +++ src/hg/hgTracks/lollyTrack.c @@ -1,552 +1,571 @@ /* lollyTrack -- load and draw lollys */ /* Copyright (C) 2019 The Regents of the University of California * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */ #include "common.h" #include "obscure.h" #include "hgTracks.h" #include "bedCart.h" #include "bigWarn.h" #include "lolly.h" #include "limits.h" #include "float.h" #include "bigBedFilter.h" #include "asParse.h" #include "quickLift.h" -#define LOLLY_DIAMETER 2 * (lollyCart->radius + 2) +#define LOLLY_DIAMETER 2 * (lollyMaxRadius(tg) + 2) struct lolly { struct lolly *next; char *name; /* the mouseover name */ double val; /* value in the data file */ unsigned start; /* genomic start address */ unsigned end; /* genomic end address */ unsigned radius; /* radius of the top of the lolly */ unsigned height; /* height of the lolly */ Color color; /* color of the lolly */ char *mouseOver; }; +static unsigned lollyMaxRadius(struct track *tg) +/* Return the radius of the largest lolly that will be drawn. A track that sets + * lollySizeField scales each radius by the track height at load time, so a lolly + * can be bigger than lollyMaxSize. Reserving margins from lollyMaxSize alone + * clips the top row once that happens. */ +{ +unsigned maxRadius = tg->lollyCart->radius; +struct lolly *pop; + +for(pop = tg->items; pop; pop = pop->next) + { + // a radius of -1 means the lolly takes the default, which is the floor above + if ((pop->radius != -1) && (pop->radius > maxRadius)) + maxRadius = pop->radius; + } + +return maxRadius; +} + static unsigned getLollyColor( struct hvGfx *hvg, unsigned color) /* Get the device color from our internal definition. */ { struct rgbColor itemRgb; itemRgb.r = (color & 0xff0000) >> 16; itemRgb.g = (color & 0xff00) >> 8; itemRgb.b = color & 0xff; return hvGfxFindColorIx(hvg, itemRgb.r, itemRgb.g, itemRgb.b); } // structure to capture yLabels struct yLabel { struct yLabel *next; unsigned y; char *label; unsigned long color; boolean on; }; int cmpY(const void *va, const void *vb) // sort the lines by y value { const struct yLabel *a = *((struct yLabel **)va); const struct yLabel *b = *((struct yLabel **)vb); return a->y - b->y; } // font heights available to the user unsigned fontHeights[] = { 6,8,10,12,14,18,24 ,34 }; unsigned findBiggest(unsigned num) /* find biggest font not bigger than num */ { int ii; unsigned prev = 6; for (ii=0; ii < ArraySize(fontHeights); prev = fontHeights[ii], ii++) if (fontHeights[ii] > num) return prev; return 34; } void doYLabels(struct track *tg, struct hvGfx *hvg, int width, int height, struct lollyCartOptions *lollyCart, int xOff, int yOff, Color color, MgFont *font, boolean doLabels ) /* parse lines like yAxisLabel