static void multiWigDraw(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Draw items in multiWig container. */ { struct track *subtrack; char *aggregate = cartOrTdbString(cart, tg->tdb, "aggregate", NULL); boolean overlay = isOverlayTypeAggregate(aggregate); int y = yOff; for (subtrack = tg->subtracks; subtrack != NULL; subtrack = subtrack->next) { if (isSubtrackVisible(subtrack)) { int height = subtrack->totalHeight(subtrack, vis); hvGfxSetClip(hvg, xOff, y, width, height); if (sameString(WIG_AGGREGATE_TRANSPARENT, aggregate)) hvGfxSetWriteMode(hvg, MG_WRITE_MODE_MULTIPLY); if (overlay) subtrack->lineHeight = tg->lineHeight; subtrack->drawItems(subtrack, seqStart, seqEnd, hvg, xOff, y, width, font, color, vis); if (!overlay) y += height + 1; hvGfxSetWriteMode(hvg, MG_WRITE_MODE_NORMAL); hvGfxUnclip(hvg); } } char *url = trackUrl(tg->track, chromName); //fprintf(stderr, "mapBoxHgcOrHgGene(id: %s;) in multiWigDraw\n", // tg->track); mapBoxHgcOrHgGene(hvg, seqStart, seqEnd, xOff, y, width, tg->height, tg->track, tg->track, NULL, url, TRUE, NULL); }
static void drawTreeInLabelArea(struct hacTree *ht, struct hvGfx *hvg, int yOff, int clipHeight, struct yFromNodeHelper *yHelper, struct titleHelper *titleHelper, boolean drawRectangle) /* Draw the haplotype clustering in the left label area (as much as fits there). */ { // Figure out which hvg to use, save current clipping, and clip to left label coords: struct hvGfx *hvgLL = (hvgSide != NULL) ? hvgSide : hvg; int clipXBak, clipYBak, clipWidthBak, clipHeightBak; hvGfxGetClip(hvgLL, &clipXBak, &clipYBak, &clipWidthBak, &clipHeightBak); hvGfxUnclip(hvgLL); hvGfxSetClip(hvgLL, leftLabelX, yOff, leftLabelWidth, clipHeight); // Draw the tree: int x = leftLabelX; (void)rDrawTreeInLabelArea(ht, hvgLL, yrtMidPoint, x, yFromHapNode, yHelper, titleHelper, drawRectangle); // Restore the prior clipping: hvGfxUnclip(hvgLL); hvGfxSetClip(hvgLL, clipXBak, clipYBak, clipWidthBak, clipHeightBak); }
static void altGraphXDrawPackTrack(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Draws the blocks for an alt-spliced gene and the connections */ { int heightPer = tg->heightPer; int lineHeight = tg->lineHeight; double scale = scaleForPixels(width); if(vis == tvFull) { hvGfxSetClip(hvg, insideX, yOff, insideWidth, tg->height); altGraphXDrawPack(tg->items, tg->ss, hvg, xOff, yOff, width, heightPer, lineHeight, winStart, winEnd, scale, font, color, shadesOfGray, tg->track, altGraphXMap); hvGfxUnclip(hvg); } }
struct hvGfx *oneTrackMakeTrackHvg(char *trackName, char *gifName) /* Set up a single track, load it, draw it and return the graphics object: */ { char *visStr = cloneString( cartUsualString(cart, trackName, hTrackOpenVis(trackName)) ); cartSetString(cart, trackName, visStr); struct trackDb *tdb = hTrackDbForTrack(trackName); tdbSortPrioritiesFromCart(cart, &tdb); if(tdb->subtracks) tdbSortPrioritiesFromCart(cart, &(tdb->subtracks)); struct track *tg = trackFromTrackDb(tdb); tg->visibility = hTvFromString(visStr); trackList = tg; tg->loadItems(tg); limitVisibility(tg); int height = tg->totalHeight(tg, tg->limitedVis); struct hvGfx *hvg = hvGfxOpenGif(insideWidth, height, gifName, TRUE); initColors(hvg); findTrackColors(hvg, tg); /* This is the only image we'll draw, so offset=(0,0). */ int xOff = 0, yOff = 0; MgFont *font = tl.font; hvGfxSetClip(hvg, xOff, yOff, insideWidth, tg->height); tg->drawItems(tg, winStart, winEnd, hvg, xOff, yOff, insideWidth, font, hvGfxFindRgb(hvg, &tg->color), tg->limitedVis); /* MEMORY LEAK -- Freeing items slows hgTracks down unacceptably so we * don't do it, and it has become vestigial. For example, wigFreeItems * is a no-op because the author noted that it is never invoked. */ #ifdef SLOW tg->freeItems(tg); #endif /* SLOW */ return hvg; }
char *altGraphXMakeImage(struct altGraphX *ag) /* create a drawing of splicing pattern */ { MgFont *font = mgSmallFont(); int fontHeight = mgFontLineHeight(font); struct spaceSaver *ssList = NULL; struct hash *heightHash = NULL; int rowCount = 0; struct tempName gifTn; int pixWidth = atoi(cartUsualString(cart, "pix", DEFAULT_PIX_WIDTH )); int pixHeight = 0; struct hvGfx *hvg; int lineHeight = 0; double scale = 0; Color shadesOfGray[9]; int maxShade = ArraySize(shadesOfGray)-1; scale = (double)pixWidth/(ag->tEnd - ag->tStart); lineHeight = 2 * fontHeight +1; altGraphXLayout(ag, ag->tStart, ag->tEnd, scale, 100, &ssList, &heightHash, &rowCount); hashFree(&heightHash); pixHeight = rowCount * lineHeight; makeTempName(&gifTn, "hgc", ".png"); hvg = hvGfxOpenPng(pixWidth, pixHeight, gifTn.forCgi, FALSE); makeGrayShades(hvg, maxShade, shadesOfGray); hvGfxSetClip(hvg, 0, 0, pixWidth, pixHeight); altGraphXDrawPack(ag, ssList, hvg, 0, 0, pixWidth, lineHeight, lineHeight-1, ag->tStart, ag->tEnd, scale, font, MG_BLACK, shadesOfGray, "Dummy", NULL); hvGfxUnclip(hvg); hvGfxClose(&hvg); printf( "<IMG SRC = \"%s\" BORDER=1 WIDTH=%d HEIGHT=%d><BR>\n", gifTn.forHtml, pixWidth, pixHeight); return cloneString(gifTn.forHtml); }
void cytoBandIdeoDraw(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Draw the entire chromosome with a little red box around our current position. */ { double scale = 0; int xBorder = 4; int x1, x2; int yBorder = 0; int chromSize = hChromSize(database, chromName); struct cytoBand *cbList = NULL, *cb = NULL; scale = (double) (width - (2 * xBorder)) / chromSize; /* Subtrack 10 for the 5 pixels buffer on either side. */ tg->heightPer -= 11; tg->lineHeight -= 11; /* Time to draw the bands. */ hvGfxSetClip(hvg, xOff, yOff, width, tg->height); genericDrawItems(tg, 0, chromSize, hvg, xOff+xBorder, yOff+5, width-(2*xBorder), font, color, tvDense); x1 = round((winStart)*scale) + xOff + xBorder -1; x2 = round((winEnd)*scale) + xOff + xBorder -1; if(x1 >= x2) x2 = x1+1; yBorder = tg->heightPer + 7 + 1; /* Draw an outline around chromosome for visualization purposes. Helps to make the chromosome look better. */ hvGfxLine(hvg, xOff+xBorder, yOff+4, xOff+width-xBorder, yOff+4, MG_BLACK); hvGfxLine(hvg, xOff+xBorder, yOff+yBorder-3, xOff+width-xBorder, yOff+yBorder-3, MG_BLACK); hvGfxLine(hvg, xOff+xBorder, yOff+4, xOff+xBorder, yOff+yBorder-3, MG_BLACK); hvGfxLine(hvg, xOff+width-xBorder, yOff+4, xOff+width-xBorder, yOff+yBorder-3, MG_BLACK); /* Find and draw the centromere which is defined as the two bands with gieStain "acen" */ cbList = tg->items; for(cb = cbList; cb != NULL; cb = cb->next) { /* If centromere do some drawing. */ if(sameString(cb->gieStain, "acen")) { int cenLeft, cenRight, cenTop, cenBottom; /* Get the coordinates of the edges of the centromere. */ cenLeft = round((cb->chromStart)*scale) + xOff + xBorder; cenRight = round((cb->next->chromEnd)*scale) + xOff + xBorder; cenTop = yOff+4; cenBottom = yOff + yBorder - 3; /* Draw centromere itself. */ hCytoBandDrawCentromere(hvg, cenLeft, cenTop, cenRight - cenLeft, cenBottom-cenTop+1, MG_WHITE, hCytoBandCentromereColor(hvg)); break; } } /* Draw a red box around all positions in windows for this chromName. * Double thick so two pixels thick each. */ struct window *window; for (window=windows; window; window=window->next) { if (!sameString(chromName, window->chromName)) continue; x1 = round((window->winStart)*scale) + xOff + xBorder -1; x2 = round((window->winEnd)*scale) + xOff + xBorder -1; hvGfxBox(hvg, x1, yOff+1, x2-x1, 2, MG_RED); hvGfxBox(hvg, x1, yOff + yBorder - 1, x2-x1, 2, MG_RED); hvGfxBox(hvg, x1, yOff+1, 2, yBorder, MG_RED); hvGfxBox(hvg, x2, yOff+1, 2, yBorder, MG_RED); } hvGfxUnclip(hvg); /* Put back the lineHeight for the track now that we are done spoofing tgDrawItems(). */ tg->heightPer += 11; tg->lineHeight += 11; }
void bigDrawWarning(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Draw the network error message, for the first window only. * Use the entire screen space across all windows. */ { if (currentWindow != windows) return; int clipXBak, clipYBak, clipWidthBak, clipHeightBak; hvGfxGetClip(hvg, &clipXBak, &clipYBak, &clipWidthBak, &clipHeightBak); hvGfxUnclip(hvg); hvGfxSetClip(hvg, fullInsideX, yOff, fullInsideWidth, tg->height); xOff = fullInsideX; width = fullInsideWidth; char message[1024]; Color yellow = hvGfxFindRgb(hvg, &undefinedYellowColor); char *errMsg = bigWarnReformat(tg->networkErrMsg); char *nl = errMsg; int sl = strlen(errMsg); // in some cases, cannot use tg-> values, so recalc local equivalents. int heightPer = tl.fontHeight; /* Height per item line minus border. */ int lineHeight = heightPer+4; /* Height per item line including border. */ if (lineHeight > tg->height) lineHeight = tg->height; int n = bigWarnNumLines(errMsg); /* Lines of warning text */ int m = tg->height / lineHeight; /* Lines of text space available */ if (m < 1) m = 1; // make yellow background to draw user's attention to the err msg if (!sameOk(parentContainerType(tg), "multiWig")) // multiWig knows full parent height hvGfxBox(hvg, xOff, yOff, width, tg->height, yellow); // leading blank lines if any int bl = (m-n)/2; int i; for(i=0;i<bl;++i) yOff += lineHeight; int l = 0; while (TRUE) { char *msg = nl; nl = strchr(nl,'\n'); if (nl) nl[0] = 0; if (nl || ((sl > 0) && (errMsg[sl-1]!='\n'))) { safef(message, sizeof(message), "%s", msg); hvGfxTextCentered(hvg, xOff, yOff, width, lineHeight, MG_BLACK, font, message); yOff += lineHeight; ++l; if (l > n) break; if (l > m) break; } if (!nl) break; ++nl; } freeMem(errMsg); hvGfxUnclip(hvg); hvGfxSetClip(hvg, clipXBak, clipYBak, clipWidthBak, clipHeightBak); }
static void multiWigDraw(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Draw items in multiWig container. */ { struct track *subtrack; boolean errMsgShown = FALSE; int y = yOff; boolean errMsgFound = FALSE; int numTracks = 0; // determine if any subtracks had errors and count them up for (subtrack = tg->subtracks; subtrack != NULL; subtrack = subtrack->next) { if (isSubtrackVisible(subtrack) ) { numTracks++; if (subtrack->networkErrMsg) errMsgFound = TRUE; } } if (errMsgFound) { Color yellow = hvGfxFindRgb(hvg, &undefinedYellowColor); hvGfxBox(hvg, xOff, yOff, width, tg->height, yellow); } struct wigCartOptions *wigCart = tg->wigCartData; struct wigGraphOutput *wgo = setUpWgo(xOff, yOff, width, tg->height, numTracks, wigCart, hvg); // we want to the order to be the same in all the modes if (wigCart->aggregateFunction == wiggleAggregateStacked) slReverse(&tg->subtracks); /* Cope with autoScale and stacked bars - we do it here rather than in the child tracks, so that * all children can be on same scale. */ double minVal, maxVal; /* Force load of all predraw arrays so can do calcs. Build up list, and then * figure out max/min. No worries about multiple loading, the loaders protect * themselves. */ struct slRef *refList = NULL; for (subtrack = tg->subtracks; subtrack != NULL; subtrack = subtrack->next) { if (isSubtrackVisible(subtrack)) { struct preDrawContainer *pre = subtrack->loadPreDraw(subtrack, seqStart, seqEnd, width); if (pre != NULL) // pre maybe null if the load fails { preDrawWindowFunction(pre->preDraw, pre->preDrawSize, wigCart->windowingFunction, wigCart->transformFunc, wigCart->doNegative); preDrawSmoothing(pre->preDraw, pre->preDrawSize, wigCart->smoothingWindow); pre->smoothingDone = TRUE; refAdd(&refList, pre); } } } slReverse(&refList); minMaxVals(refList, &minVal, &maxVal, wigCart->windowingFunction, wigCart->alwaysZero, wgo->yOffsets); slFreeList(&refList); if (!wigCart->autoScale) { minVal = wigCart->minY; maxVal = wigCart->maxY; } /* Loop through again setting up the wigCarts of the children to have minY/maxY for * our limits and autoScale off. */ for (subtrack = tg->subtracks; subtrack != NULL; subtrack = subtrack->next) { if (!isSubtrackVisible(subtrack)) continue; struct wigCartOptions *wigCart = subtrack->wigCartData; wigCart->minY = minVal; wigCart->maxY = maxVal; wigCart->autoScale = wiggleScaleManual; struct preDrawContainer *pre = subtrack->preDrawContainer; if (pre != NULL) // pre maybe null if the load fails { pre->graphUpperLimit = maxVal; pre->graphLowerLimit = minVal; } } int numTrack = 0; for (subtrack = tg->subtracks; subtrack != NULL; subtrack = subtrack->next) { if (isSubtrackVisible(subtrack)) { if (!subtrack->networkErrMsg || !errMsgShown) { if (subtrack->networkErrMsg) errMsgShown = TRUE; wgo->numTrack = numTrack++; subtrack->wigGraphOutput = wgo; int height = subtrack->totalHeight(subtrack, vis); hvGfxSetClip(hvg, xOff, y, width, height); if (wigCart->aggregateFunction != wiggleAggregateNone) subtrack->lineHeight = tg->lineHeight; subtrack->drawItems(subtrack, seqStart, seqEnd, hvg, xOff, y, width, font, color, vis); if (wigCart->aggregateFunction == wiggleAggregateNone) { y += height + 1; wgo->yOff = y; } hvGfxUnclip(hvg); } } } if (wigCart->aggregateFunction == wiggleAggregateTransparent) { floatPicIntoHvg(wgo->image, xOff, yOff, hvg); floatPicFree((struct floatPic **)&wgo->image); } char *url = trackUrl(tg->track, chromName); mapBoxHgcOrHgGene(hvg, seqStart, seqEnd, xOff, yOff, width, tg->height, tg->track, tg->track, NULL, url, TRUE, NULL); }