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 genoLayDrawBandedChroms(struct genoLay *gl, struct hvGfx *hvg, char *db, struct sqlConnection *conn, Color *shadesOfGray, int maxShade, int defaultColor) /* Draw chromosomes with centromere and band glyphs. * Get the band data from the database. If the data isn't * there then draw simple chroms in default color instead */ { char *bandTable = "cytoBandIdeo"; int yOffset = gl->chromOffsetY; genoLayDrawSimpleChroms(gl, hvg, defaultColor); if (sqlTableExists(conn, bandTable) && !gl->allOneLine) { int centromereColor = hCytoBandCentromereColor(hvg); double pixelsPerBase = 1.0/gl->basesPerPixel; int height = gl->chromHeight; int innerHeight = gl->chromHeight-2; struct genoLayChrom *chrom; boolean isDmel = hCytoBandDbIsDmel(db); boolean bColor = hvGfxFindColorIx(hvg, 200, 150, 150); int fontPixelHeight = mgFontPixelHeight(gl->font); for (chrom = gl->chromList; chrom != NULL; chrom = chrom->next) { boolean gotAny = FALSE; struct sqlResult *sr; char **row; char query[256]; int cenX1=BIGNUM, cenX2=0; int y = chrom->y + yOffset; /* Fetch bands from database and draw them. */ safef(query, sizeof(query), "select * from %s where chrom='%s'", bandTable, chrom->fullName); sr = sqlGetResult(conn, query); while ((row = sqlNextRow(sr)) != NULL) { struct cytoBand band; int x1, x2; cytoBandStaticLoad(row, &band); x1 = pixelsPerBase*band.chromStart; x2 = pixelsPerBase*band.chromEnd; if (sameString(band.gieStain, "acen")) { /* Centromere is represented as two adjacent bands. * We'll just record the extents of it here, and draw it * in one piece later. */ if (x1 < cenX1) cenX1 = x1; if (x2 > cenX2) cenX2 = x2; } else { /* Draw band */ hCytoBandDrawAt(&band, hvg, x1+chrom->x, y+1, x2-x1, innerHeight, isDmel, gl->font, fontPixelHeight, MG_BLACK, bColor, shadesOfGray, maxShade); gotAny = TRUE; } } sqlFreeResult(&sr); /* Draw box around chromosome */ hvGfxBox(hvg, chrom->x, y, chrom->width, 1, MG_BLACK); hvGfxBox(hvg, chrom->x, y+height-1, chrom->width, 1, MG_BLACK); hvGfxBox(hvg, chrom->x, y, 1, height, MG_BLACK); hvGfxBox(hvg, chrom->x+chrom->width-1, y, 1, height, MG_BLACK); /* Draw centromere if we found one. */ if (cenX2 > cenX1) { hCytoBandDrawCentromere(hvg, cenX1+chrom->x, y, cenX2-cenX1, height, MG_WHITE, centromereColor); } } } }