2d4c0be4a4a481893ae023a20ad68c753872adbb angie Mon Mar 7 10:58:31 2011 -0800 Enabling next/prev-exon arrows for DECIPHER track at b0b's request.Those arrows are implemented for linkedFeatures, so I convert the bed4 DECIPHER items into linkedFeatures during loading, and use lf->extra to store the phenotypes string used in draw and mapItems. diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c index 0414010..86e309b 100644 --- src/hg/hgTracks/simpleTracks.c +++ src/hg/hgTracks/simpleTracks.c @@ -5128,44 +5128,44 @@ int dir = 0; if (bed->strand[0] == '+') dir = 1; else if(bed->strand[0] == '-') dir = -1; if (dir != 0 && w > 2) { int midY = y + (heightPer>>1); Color textColor = hvGfxContrastingColor(hvg, color); clippedBarbs(hvg, x1, midY, w, tl.barbHeight, tl.barbSpacing, dir, textColor, TRUE); } } } -char *decipherPhenotypeList(struct track *tg, struct bed *item) +char *decipherPhenotypeList(struct track *tg, char *name) /* Return list of diseases associated with a DECIPHER entry */ { struct sqlConnection *conn; char query[256]; struct sqlResult *sr; char **row; char *chp; int i=0; conn = hAllocConn(database); safef(query,sizeof(query), - "select distinct phenotype from decipherRaw where id='%s' order by phenotype", item->name); + "select distinct phenotype from decipherRaw where id='%s' order by phenotype", name); sr = sqlMustGetResult(conn, query); row = sqlNextRow(sr); /* show up to 20 max entries */ chp = decipherBuffer; while ((row != NULL) && i<20) { if (i != 0) { safef(chp, 3, "; "); chp++;chp++; } safef(chp, 100, "%s", row[0]); chp = chp+strlen(row[0]); row = sqlNextRow(sr); @@ -5173,47 +5173,73 @@ } if ((i == 20) && (row != NULL)) { safef(chp, 5, " ..."); chp++;chp++;chp++;chp++; } *chp = '\0'; hFreeConn(&conn); sqlFreeResult(&sr); return(decipherBuffer); } +void decipherLoad(struct track *tg) +/* Convert bed4 to linkedFeatures so we can have next "exon" arrows. */ +{ +struct sqlConnection *conn = hAllocConn(database); +struct linkedFeatures *lfList = NULL; +int rowOffset = 0; +struct sqlResult *sr = hRangeQuery(conn, tg->table, chromName, winStart, winEnd, NULL, &rowOffset); +char **row = NULL; +while ((row = sqlNextRow(sr)) != NULL) + { + struct bed *bed = bedLoad(row+rowOffset); + bed->score = 1000; + bed->strand[0] = '.'; + bed->thickStart = bed->chromStart; + bed->thickEnd = bed->chromEnd; + struct linkedFeatures *lf = bedMungToLinkedFeatures(&bed, tg->tdb, 4, 0, 1000, FALSE); + lf->extra = cloneString(decipherPhenotypeList(tg, lf->name)); + slAddHead(&lfList, lf); + } +sqlFreeResult(&sr); +hFreeConn(&conn); +slReverse(&lfList); +slSort(&lfList, linkedFeaturesCmp); +tg->items = lfList; +} + Color decipherColor(struct track *tg, void *item, struct hvGfx *hvg) /* Return color to draw DECIPHER entry */ { -struct bed *bedItem = item; +struct linkedFeatures *lf = item; int col = tg->ixColor; struct sqlConnection *conn = hAllocConn(database); struct sqlResult *sr; char **row; char query[256]; char cond_str[256]; char *decipherId = NULL; /* color scheme: RED: If the entry is a deletion (mean ratio < 0) BLUE: If the entry is a duplication (mean ratio > 0) */ -safef(cond_str, sizeof(cond_str),"name='%s' ", bedItem->name); +safef(cond_str, sizeof(cond_str),"name='%s' ", lf->name); decipherId = sqlGetField(database, "decipher", "name", cond_str); if (decipherId != NULL) { if (hTableExists(database, "decipherRaw")) { safef(query, sizeof(query), "select mean_ratio > 0 from decipherRaw where id = '%s'", decipherId); sr = sqlGetResult(conn, query); if ((row = sqlNextRow(sr)) != NULL) { if (sameWord(row[0], "1")) { col = MG_BLUE; } else { @@ -5234,85 +5260,88 @@ col = MG_GRAY; } } sqlFreeResult(&sr); } } hFreeConn(&conn); return(col); } static void decipherDrawAt(struct track *tg, void *item, struct hvGfx *hvg, int xOff, int y, double scale, MgFont *font, Color color, enum trackVisibility vis) /* Draw a single superfamily item at position. */ { -struct bed *bed = item; -char *sPhenotypes; +struct linkedFeatures *lf = item; +char *sPhenotypes = lf->extra; int heightPer = tg->heightPer; -int x1 = round((double)((int)bed->chromStart-winStart)*scale) + xOff; -int x2 = round((double)((int)bed->chromEnd-winStart)*scale) + xOff; +int x1 = round((double)((int)lf->start-winStart)*scale) + xOff; +int x2 = round((double)((int)lf->end-winStart)*scale) + xOff; int w; -sPhenotypes = decipherPhenotypeList(tg, item); w = x2-x1; if (w < 1) w = 1; if (color) { hvGfxBox(hvg, x1, y, w, heightPer, decipherColor(tg, item, hvg)); if (vis == tvFull) { hvGfxTextRight(hvg, x1-mgFontStringWidth(font, sPhenotypes)-2, y, mgFontStringWidth(font, sPhenotypes), heightPer, MG_BLACK, font, sPhenotypes); } if (tg->drawName && vis != tvSquish) { /* Clip here so that text will tend to be more visible... */ - char *s = tg->itemName(tg, bed); + char *s = tg->itemName(tg, item); w = x2-x1; if (w > mgFontStringWidth(font, s)) { Color textColor = hvGfxContrastingColor(hvg, color); hvGfxTextCentered(hvg, x1, y, w, heightPer, textColor, font, s); } } - if (vis != tvDense) - mapBoxHc(hvg, bed->chromStart, bed->chromEnd, x1, y, x2 - x1, heightPer, - tg->track, tg->mapItemName(tg, bed), sPhenotypes); } -if (tg->subType == lfWithBarbs) +} + +void decipherMapItem(struct track *tg, struct hvGfx *hvg, void *item, + char *itemName, char *mapItemName, int start, int end, + int x, int y, int width, int height) +/* Special mouseover text from lf->extra (phenotype list). */ { - int dir = 0; - if (bed->strand[0] == '+') - dir = 1; - else if(bed->strand[0] == '-') - dir = -1; - if (dir != 0 && w > 2) +// Don't bother if we are imageV2 and a dense child. +if(!theImgBox || tg->limitedVis != tvDense || !tdbIsCompositeChild(tg->tdb)) { - int midY = y + (heightPer>>1); - Color textColor = hvGfxContrastingColor(hvg, color); - clippedBarbs(hvg, x1, midY, w, tl.barbHeight, tl.barbSpacing, - dir, textColor, TRUE); - } + struct linkedFeatures *lf = item; + char *directUrl = trackDbSetting(tg->tdb, "directUrl"); + boolean withHgsid = (trackDbSetting(tg->tdb, "hgsid") != NULL); + char *phenotypes = lf->extra; + char *mouseOverText = isEmpty(phenotypes) ? lf->name : phenotypes; + mapBoxHgcOrHgGene(hvg, start, end, x, y, width, height, tg->track, + mapItemName, mouseOverText, directUrl, withHgsid, NULL); } } + void decipherMethods(struct track *tg) /* Methods for DECIPHER track. */ { +linkedFeaturesMethods(tg); +tg->loadItems = decipherLoad; +tg->mapItem = decipherMapItem; tg->itemColor = decipherColor; tg->drawItemAt = decipherDrawAt; } char *emptyName(struct track *tg, void *item) /* Return name of item. */ { return(""); } void rdmrMethods(struct track *tg) /* Methods for R-DMR track. */ { tg->itemName = emptyName; }