ba5f4c097ecdf323f94adab36f4cf52f7f59e8cf jcasper Mon Mar 3 09:47:13 2025 -0800 Initial commit of heatmap code for bigBeds, still plenty to do, refs #31812 diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c index 663774c43ee..66c014c0027 100644 --- src/hg/hgTracks/simpleTracks.c +++ src/hg/hgTracks/simpleTracks.c @@ -711,30 +711,33 @@ if (decoratorGroupGetExtent(tg, decoratorKey, NULL, &decoratedEnd)) { if (decoratedEnd > end) end = decoratedEnd; } } AllocVar(range); range->start = start + winOffset; range->end = end + winOffset; slAddHead(&rangeList, range); rangeWidth += (range->end - range->start); range->height = 1; + if (tg->itemHeightRowsForPack != NULL) + range->height = tg->itemHeightRowsForPack(tg, item); + if (hasDecorators(tg)) { char itemString[2048]; struct linkedFeatures *lf = (struct linkedFeatures*) item; safef(itemString, sizeof(itemString), "%s:%d-%d:%s", chrom, baseStart, baseEnd, lf->name); range->height += decoratorGroupHeight(tg, itemString); } AllocVar(node); node->val = item; node->parentSs = sin->ss; node->noLabel = noLabel; slAddHead(&nodeList, node); @@ -1695,51 +1698,57 @@ if (charsInBox < strlen(shortLabel)) return; Color labelColor = hvGfxContrastingColor(hvg, color); hvGfxTextCentered(hvg, x1, y, w, height, labelColor, font, shortLabel); } struct xyPair { double x, y; }; struct glyphShape { int nPoints; struct xyPair* points; }; -/* An obtuse representation, but this is a list of the glyphs we know how to draw along with coordinates for - * the sequential points of each glyph on the unit square. Those will then be scaled by whatever the current - * track height is for actual drawing. */ +/* Glyph definitions + * + * An obtuse representation, but this is a list of the glyphs we know how to draw as polygons along with + * coordinates for the sequence of points for each glyph on the unit square. Those will then be scaled + * by whatever the current track height is for actual drawing. + * There's one glyph that's special-cased - GLYPH_CIRCLE is drawn with a separate routine. + * + * Each glyph is expected to be defined on the unit square with 0,0 at the top left and 1,1 at the bottom right. + * Note that triangle and inverse triangle subvert this a little by extending just outside those bounds. + */ static struct glyphShape glyphShapes[] = { [GLYPH_CIRCLE] = (struct glyphShape) {0, NULL}, [GLYPH_TRIANGLE] = (struct glyphShape) {3, (struct xyPair[]) {{0.5,0},{1.07735,1},{-0.07735,1}}}, [GLYPH_INV_TRIANGLE] = (struct glyphShape) {3, (struct xyPair[]) {{0.5,1},{1.07735,0},{-0.07735,0}}}, [GLYPH_SQUARE] = (struct glyphShape) {4, (struct xyPair[]) {{0,0},{1,0},{1,1},{0,1}}}, [GLYPH_DIAMOND] = (struct glyphShape) {4, (struct xyPair[]) {{0.5,0},{1,0.5},{0.5,1},{0,0.5}}}, [GLYPH_PENTAGRAM] = (struct glyphShape) {5, (struct xyPair[]) {{0.5,0.0},{0.824920,1.0},{-0.025731,0.381966}, {1.02573,0.381966},{0.175080,1}}}, [GLYPH_OCTAGON] = (struct glyphShape) {8, (struct xyPair[]) {{0.292893,1},{0.707107,1},{1,0.707107}, {1,0.292893},{0.707107,0},{0.292893,0},{0,0.292893},{0,0.707107}}}, [GLYPH_STAR] = (struct glyphShape) {10, (struct xyPair[]) {{0.500000,0.000000},{0.624108,0.381966},{1.025731,0.381966}, {0.700811,0.618034},{0.824920,1.000000},{0.500000,0.763932},{0.175080,1.000000},{0.299189,0.618034}, {-0.025731,0.381966},{0.375892,0.381966}}} }; - void drawScaledGlyph(struct hvGfx *hvg, int chromStart, int chromEnd, double scale, int xOff, int y, int heightPer, glyphType glyph, boolean filled, Color outlineColor, Color fillColor) /* Draw a glyph as a circle/polygon. If filled, draw as with fillColor, * which may have transparency. */ { int glyphHeight = heightPer-1; int startX, endX; double middleX, middleY = y+heightPer/2.0; // A glyph might be defined on a wide range - find the center and draw specifically there // so we don't have a glyph shifting if only part of that window is in view. int centeredStart, centeredEnd; centeredStart = (chromStart + chromEnd)/2; centeredEnd = (chromStart + chromEnd+1)/2; int ptCount, i, x0, y0; @@ -14720,46 +14729,46 @@ track->isBigBed = TRUE; interactMethods(track); } else if (sameWord(type, "bigNarrowPeak")) { tdb->canPack = TRUE; track->isBigBed = TRUE; encodePeakMethods(track); track->loadItems = bigNarrowPeakLoadItems; } else if (sameWord(type, "bigPsl")) { tdb->canPack = TRUE; wordCount++; words[1] = "12"; - bigBedMethods(track, tdb, wordCount, words); + commonBigBedMethods(track, tdb, wordCount, words); } else if (sameWord(type, "bigChain")) { tdb->canPack = TRUE; wordCount++; words[1] = "11"; track->isBigBed = TRUE; chainMethods(track, tdb, wordCount, words); } else if (sameWord(type, "bigGenePred")) { tdb->canPack = TRUE; wordCount++; words[1] = "12"; - bigBedMethods(track, tdb, wordCount, words); + commonBigBedMethods(track, tdb, wordCount, words); } else if (sameWord(type, "bigDbSnp")) { tdb->canPack = TRUE; track->isBigBed = TRUE; bigDbSnpMethods(track); } else if (sameWord(type, "bedGraph")) { bedGraphMethods(track, tdb, wordCount, words); } else if (sameWord(type, "bigWig")) { bigWigMethods(track, tdb, wordCount, words); }