0301e7107474990ca5b3328ad5f622b018fb481c kate Thu Jul 6 13:14:00 2017 -0700 Split label into left (gene) and right (tissues). refs #15646 diff --git src/hg/hgTracks/gtexEqtlClusterTrack.c src/hg/hgTracks/gtexEqtlClusterTrack.c index 3d8b872..a2b800b 100644 --- src/hg/hgTracks/gtexEqtlClusterTrack.c +++ src/hg/hgTracks/gtexEqtlClusterTrack.c @@ -117,102 +117,132 @@ bedLoadItemWhere(track, track->table, where, (ItemLoader)loadOne); safef(cartVar, sizeof cartVar, "%s.%s", track->track, GTEX_EQTL_EFFECT); extras->minEffect = fabs(cartUsualDouble(cart, cartVar, GTEX_EFFECT_MIN_DEFAULT)); safef(cartVar, sizeof cartVar, "%s.%s", track->track, GTEX_EQTL_PROBABILITY); extras->minProb = cartUsualDouble(cart, cartVar, 0.0); boolean hasTissueFilter = filterTissues(track, extras); if (!hasTissueFilter && extras->minEffect == 0.0 && extras->minProb == 0.0) return; // more filtering filterItems(track, eqtlIncludeFilter, "include"); } static char *gtexEqtlClusterItemName(struct track *track, void *item) -/* Load all items (and motifs if table is present) in window */ +/* Left label is gene name */ { struct gtexEqtlCluster *eqtl = (struct gtexEqtlCluster *)item; -struct dyString *ds = dyStringNew(0); -if (eqtl->expCount == 1) - { - dyStringPrintf(ds, "%s in %s", eqtl->target, eqtl->expNames[0]); +return eqtl->target; } -else + +static char *gtexEqtlClusterSourcesLabel(struct track *track, void *item) +/* Right label is tissue (or number of tissues if >1) */ { +struct gtexEqtlCluster *eqtl = (struct gtexEqtlCluster *)item; int i, included; for (i=0, included=0; iexpCount; i++) if (!isExcludedTissue(eqtl, i)) included++; - dyStringPrintf(ds, "%s in %d tissues", eqtl->target, included); - } +if (included == 1) + return eqtl->expNames[i-1]; +struct dyString *ds = dyStringNew(0); +dyStringPrintf(ds, "%d tissues", included); return dyStringCannibalize(&ds); } +static int gtexEqtlClusterItemRightPixels(struct track *track, void *item) +/* Return number of pixels we need to the right of an item (for sources label). */ +{ +return mgFontStringWidth(tl.font, gtexEqtlClusterSourcesLabel(track, item)); +} + static Color gtexEqtlClusterItemColor(struct track *track, void *item, struct hvGfx *hvg) /* Color by highest effect in list (blue -, red +), with brighter for higher effect (teal, fuschia) */ { struct gtexEqtlCluster *eqtl = (struct gtexEqtlCluster *)item; double maxEffect = 0.0; int i; for (i=0; iexpCount; i++) { if (isExcludedTissue(eqtl, i)) continue; double effect = eqtl->expScores[i]; if (fabs(effect) > fabs(maxEffect)) maxEffect = effect; } double cutoff = 2.0; if (maxEffect < 0.0) { /* down-regulation displayed as blue */ if (maxEffect < 0.0 - cutoff) return MG_CYAN; return MG_BLUE; } /* up-regulation displayed as red */ if (maxEffect > cutoff) return MG_MAGENTA; return MG_RED; } -static void gtexEqtlClusterMapItem(struct track *track, struct hvGfx *hvg, void *item, char *itemName, - char *mapItemName, int start, int end, int x, int y, int width, int height) +static void gtexEqtlClusterDrawItemAt(struct track *track, void *item, + struct hvGfx *hvg, int xOff, int y, + double scale, MgFont *font, Color color, enum trackVisibility vis) +/* Draw GTEx eQTL cluster with right label indicating source(s) */ +{ +bedPlusLabelDrawAt(track, item, hvg, xOff, y, scale, font, color, vis); +if (vis != tvFull && vis != tvPack) + return; + +/* Draw text to the right */ +struct gtexEqtlCluster *eqtl = (struct gtexEqtlCluster *)item; +int x2 = round((double)((int)eqtl->chromEnd-winStart)*scale) + xOff; +int x = x2 + tl.mWidth/2; +char *label = gtexEqtlClusterSourcesLabel(track, item); +int w = mgFontStringWidth(font, label); +hvGfxTextCentered(hvg, x, y, w, track->heightPer, MG_BLACK, font, label); +} + +static void gtexEqtlClusterMapItem(struct track *track, 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 with list of tissues with colors and effect size */ { char *title = itemName; if (track->limitedVis != tvDense) { struct gtexEqtlCluster *eqtl = (struct gtexEqtlCluster *)item; // Experiment: construct list of tissues with colors and effect sizes for mouseover //struct gtexEqtlClusterTrack *extras = (struct gtexEqtlClusterTrack *)track->extraUiData; //struct hash *tissueHash = extras->tissueHash; struct dyString *ds = dyStringNew(0); dyStringPrintf(ds, "%s/%s: ", eqtl->name, eqtl->target); int i; for (i=0; iexpCount; i++) { if (isExcludedTissue(eqtl, i)) continue; double effect= eqtl->expScores[i]; dyStringPrintf(ds, "%s(%s%0.2f)%s", eqtl->expNames[i], effect < 0 ? "" : "+", effect, i < eqtl->expCount - 1 ? ", " : ""); //struct gtexTissue *tis = (struct gtexTissue *)hashFindVal(tissueHash, eqtl->expNames[i]); //unsigned color = tis ? tis->color : 0; // BLACK //char *name = tis ? tis->name : "unknown"; //#dyStringPrintf(ds,"*%s%s%0.2f\n", //color, name, effect < 0 ? "" : "+", effect); } title = dyStringCannibalize(&ds); } -genericMapItem(track, hvg, item, title, itemName, start, end, x, y, width, height); +int w = width + gtexEqtlClusterItemRightPixels(track, item); +genericMapItem(track, hvg, item, title, itemName, start, end, x, y, w, height); } void gtexEqtlClusterMethods(struct track *track) /* BED5+5 with target, expNames,expScores, expProbs */ { track->loadItems = gtexEqtlClusterLoadItems; track->itemName = gtexEqtlClusterItemName; track->itemColor = gtexEqtlClusterItemColor; +track->itemRightPixels = gtexEqtlClusterItemRightPixels; +track->drawItemAt = gtexEqtlClusterDrawItemAt; track->mapItem = gtexEqtlClusterMapItem; }