static void wikiTrackMapItem(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 special map box item with different i=hgcClickName and * pop-up statusLine with the item name */ { char *userName; /* already been determined to be enabled by getting here, need to verify * userName vs editors and vs owner */ (void) wikiTrackEnabled(database, &userName); char *hgcClickName = tg->mapItemName(tg, item); char *statusLine = tg->itemName(tg, item); boolean editor = isWikiEditor(userName); struct wikiTrack *wikiItem = NULL; boolean enableHgcClick = FALSE; /* allow hgc click (i.e. delete privs) if the following are true 1. this is the item 0 "add new item" 2. logged into the wiki 3. user is an editor or user is the owner */ if (differentWord("0", hgcClickName)) wikiItem = findWikiItemId(hgcClickName); else enableHgcClick = TRUE; /* item 0 "add new item" must go to hgc */ if (wikiItem) { if (isNotEmpty(userName) && sameWord(userName, wikiItem->owner)) enableHgcClick = TRUE; /* owner has delete privls */ if (editor) enableHgcClick = TRUE; /* editors have delete privls */ } if (enableHgcClick) { mapBoxHgcOrHgGene(hvg, start, end, x, y, width, height, tg->track, hgcClickName, statusLine, NULL, FALSE, NULL ); } else { /* go directly to the wiki description */ char *directUrl = wikiUrl(wikiItem); mapBoxHgcOrHgGene(hvg, start, end, x, y, width, height, tg->track, hgcClickName, statusLine, directUrl, FALSE, NULL); freeMem(directUrl); } }
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); }
void mapBoxForCenterVariant(struct vcfRecord *rec, struct hvGfx *hvg, struct track *tg, int xOff, int yOff, int width) /* Special mouseover for center variant */ { struct dyString *dy = dyStringNew(0); unsigned int chromStartMap = vcfRecordTrimIndelLeftBase(rec); unsigned int chromEndMap = vcfRecordTrimAllelesRight(rec); gtSummaryString(rec, dy); dyStringAppend(dy, " Haplotypes sorted on "); char *centerChrom = cartOptionalStringClosestToHome(cart, tg->tdb, FALSE, "centerVariantChrom"); if (centerChrom == NULL || !sameString(chromName, centerChrom)) dyStringAppend(dy, "middle variant by default. "); else dyStringAppend(dy, "this variant. "); dyStringAppend(dy, "To anchor sorting to a different variant, click on that variant and " "then click on the 'Use this variant' button below the variant name."); const double scale = scaleForPixels(width); int x1 = round((double)(rec->chromStart-winStart)*scale) + xOff; int x2 = round((double)(rec->chromEnd-winStart)*scale) + xOff; int w = x2-x1; if (w <= 1) { x1--; w = 3; } mapBoxHgcOrHgGene(hvg, chromStartMap, chromEndMap, x1, yOff, w, tg->height, tg->track, rec->name, dy->string, NULL, TRUE, NULL); }
static void cgapSageMapItem(struct track *tg, struct hvGfx *hvg, void *item, char *itemName, char *mapItemName, int start, int end, int x, int y, int width, int height) { struct linkedFeatures *lf = item; mapBoxHgcOrHgGene(hvg, start, end, x, y, width, height, tg->track, itemName, NULL, NULL, TRUE, (char *)lf->extra); }
static void drawOneRec(struct vcfRecord *rec, unsigned short *gtHapOrder, unsigned short gtHapCount, struct track *tg, struct hvGfx *hvg, int xOff, int yOff, int width, boolean isClustered, boolean isCenter, enum hapColorMode colorMode) /* Draw a stack of genotype bars for this record */ { unsigned int chromStartMap = vcfRecordTrimIndelLeftBase(rec); unsigned int chromEndMap = vcfRecordTrimAllelesRight(rec); const double scale = scaleForPixels(width); int x1 = round((double)(rec->chromStart-winStart)*scale) + xOff; int x2 = round((double)(rec->chromEnd-winStart)*scale) + xOff; int w = x2-x1; if (w <= 1) { x1--; w = 3; } // When coloring mode is altOnly, we draw one extra pixel row at the top & one at bottom // to show the locations of variants, since the reference alleles are invisible: int extraPixel = 0; int hapHeight = tg->height - CLIP_PAD; if (colorMode == altOnlyMode) { hvGfxLine(hvg, x1, yOff, x2, yOff, (isClustered ? purple : shadesOfGray[5])); extraPixel = 1; hapHeight -= extraPixel*2; } double hapsPerPix = (double)gtHapCount / hapHeight; int pixIx; for (pixIx = 0; pixIx < hapHeight; pixIx++) { int gtHapOrderIxStart = (int)(hapsPerPix * pixIx); int gtHapOrderIxEnd = round(hapsPerPix * (pixIx + 1)); if (gtHapOrderIxEnd == gtHapOrderIxStart) gtHapOrderIxEnd++; int unks = 0, refs = 0, alts = 0; int gtHapOrderIx; for (gtHapOrderIx = gtHapOrderIxStart; gtHapOrderIx < gtHapOrderIxEnd; gtHapOrderIx++) { int gtHapIx = gtHapOrder[gtHapOrderIx]; int hapIx = gtHapIx & 1; int gtIx = gtHapIx >>1; struct vcfGenotype *gt = &(rec->genotypes[gtIx]); if (gt->isPhased || gt->isHaploid || (gt->hapIxA == gt->hapIxB)) { int alIx = hapIx ? gt->hapIxB : gt->hapIxA; if (alIx < 0) unks++; else if (alIx > 0) alts++; else refs++; } else unks++; } int y = yOff + extraPixel + pixIx; Color col; if (colorMode == baseMode) col = colorByBase(refs, alts, unks, rec->alleles[0], rec->alleles[1]); else if (colorMode == refAltMode) col = colorByRefAlt(refs, alts, unks); else col = colorByAltOnly(refs, alts, unks); if (col != MG_WHITE) hvGfxLine(hvg, x1, y, x2, y, col); } int yBot = yOff + tg->height - CLIP_PAD - 1; if (isCenter) { if (colorMode == altOnlyMode) { // Colorful outline to distinguish this variant: hvGfxLine(hvg, x1-1, yOff, x1-1, yBot, purple); hvGfxLine(hvg, x2+1, yOff, x2+1, yBot, purple); hvGfxLine(hvg, x1-1, yOff, x2+1, yOff, purple); hvGfxLine(hvg, x1-1, yBot, x2+1, yBot, purple); } else { // Thick black lines to distinguish this variant: hvGfxBox(hvg, x1-3, yOff, 3, tg->height, MG_BLACK); hvGfxBox(hvg, x2, yOff, 3, tg->height, MG_BLACK); hvGfxLine(hvg, x1-2, yOff, x2+2, yOff, MG_BLACK); hvGfxLine(hvg, x1-2, yBot, x2+2, yBot, MG_BLACK); } // Mouseover was handled already by mapBoxForCenterVariant } else { struct dyString *dy = dyStringNew(0); gtSummaryString(rec, dy); mapBoxHgcOrHgGene(hvg, chromStartMap, chromEndMap, x1, yOff, w, tg->height, tg->track, rec->name, dy->string, NULL, TRUE, NULL); } if (colorMode == altOnlyMode) hvGfxLine(hvg, x1, yBot, x2, yBot, (isClustered ? purple : shadesOfGray[5])); }
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); }
static void longRangeDraw(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) /* Draw a list of longTabix structures. */ { double scale = scaleForWindow(width, seqStart, seqEnd); struct bed *beds = tg->items; unsigned int maxWidth; struct longRange *longRange; char buffer[1024]; char itemBuf[2048]; char statusBuf[2048]; safef(buffer, sizeof buffer, "%s.%s", tg->tdb->track, LONG_MINSCORE); double minScore = sqlDouble(cartUsualString(cart, buffer, LONG_DEFMINSCORE)); struct longRange *longRangeList = parseLongTabix(beds, &maxWidth, minScore); for(longRange=longRangeList; longRange; longRange=longRange->next) { safef(itemBuf, sizeof itemBuf, "%d", longRange->id); safef(statusBuf, sizeof statusBuf, "%g %s:%d %s:%d", longRange->score, longRange->sChrom, longRange->s, longRange->eChrom, longRange->e); boolean sOnScreen = (longRange->s >= seqStart) && (longRange->s < seqEnd); unsigned sx = 0, ex = 0; if (sOnScreen) sx = (longRange->s - seqStart) * scale + xOff; if (differentString(longRange->sChrom, longRange->eChrom)) { if (!sOnScreen) continue; // draw the foot int footWidth = scale * (longRange->sw / 2); hvGfxLine(hvg, sx - footWidth, yOff, sx + footWidth, yOff, MG_BLUE); int height = tg->height/2; if (tg->visibility == tvDense) height = tg->height; unsigned yPos = yOff + height; hvGfxLine(hvg, sx, yOff, sx, yPos, MG_BLUE); if (tg->visibility == tvFull) { mapBoxHgcOrHgGene(hvg, longRange->s, longRange->s, sx - 2, yOff, 4, tg->height/2, tg->track, itemBuf, statusBuf, NULL, TRUE, NULL); safef(buffer, sizeof buffer, "%s:%d", longRange->eChrom, longRange->e); hvGfxTextCentered(hvg, sx, yPos + 2, 4, 4, MG_BLUE, font, buffer); int width = vgGetFontStringWidth(hvg->vg, font, buffer); int height = vgGetFontPixelHeight(hvg->vg, font); mapBoxHgcOrHgGene(hvg, longRange->s, longRange->s, sx - width/2, yPos, width, height, tg->track, itemBuf, statusBuf, NULL, TRUE, NULL); } } else { boolean eOnScreen = (longRange->e >= seqStart) && (longRange->e < seqEnd); if (!(sOnScreen || eOnScreen)) continue; if (eOnScreen) ex = (longRange->e - seqStart) * scale + xOff; double longRangeWidth = longRange->e - longRange->s; int peak = (tg->height - 15) * ((double)longRangeWidth / maxWidth) + yOff + 10; if (tg->visibility == tvDense) peak = yOff + tg->height; if (sOnScreen) { int footWidth = scale * (longRange->sw / 2); hvGfxLine(hvg, sx - footWidth, yOff, sx + footWidth, yOff, color); hvGfxLine(hvg, sx, yOff, sx, peak, color); } if (eOnScreen) { int footWidth = scale * (longRange->ew / 2); hvGfxLine(hvg, ex - footWidth, yOff, ex + footWidth, yOff, color); hvGfxLine(hvg, ex, yOff, ex, peak, color); } if (tg->visibility == tvFull) { unsigned sPeak = sOnScreen ? sx : xOff; unsigned ePeak = eOnScreen ? ex : xOff + width; hvGfxLine(hvg, sPeak, peak, ePeak, peak, color); safef(statusBuf, sizeof statusBuf, "%g %s:%d %s:%d", longRange->score, longRange->sChrom, longRange->s, longRange->eChrom, longRange->e); if (sOnScreen) mapBoxHgcOrHgGene(hvg, longRange->s, longRange->e, sx - 2, yOff, 4, peak - yOff, tg->track, itemBuf, statusBuf, NULL, TRUE, NULL); if (eOnScreen) mapBoxHgcOrHgGene(hvg, longRange->s, longRange->e, ex - 2, yOff, 4, peak - yOff, tg->track, itemBuf, statusBuf, NULL, TRUE, NULL); mapBoxHgcOrHgGene(hvg, longRange->s, longRange->e, sPeak, peak-2, ePeak - sPeak, 4, tg->track, itemBuf, statusBuf, NULL, TRUE, NULL); } } } }