static struct memGfx *altColorLabels(char **labels, int labelCount, int width) /* Return a memory image with alternating colors. */ { struct memGfx *mg = NULL; Color c1,c2; MgFont *font = mgMediumFont(); int lineHeight = mgFontLineHeight(font)-1; int height = lineHeight * labelCount, i; int y = 0; /* Allocate picture and set up colors. */ mg = mgNew(width, height); c1 = mgFindColor(mg, 0xE0, 0xE0, 0xFF); c2 = mgFindColor(mg, 0xFF, 0xC8, 0xC8); /* Draw text. */ for (i=labelCount-1; i >= 0; --i) { Color c = ((i&1) ? c2 : c1); mgDrawBox(mg, 0, y, width, lineHeight, c); mgTextRight(mg, 0+1, y+1, width-1, lineHeight, MG_BLACK, font, labels[i]); y += lineHeight; } return mg; }
static void doMapBoxPerRow(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, MgFont *font, Color color, enum trackVisibility vis) { int fontHeight = mgFontLineHeight(font); int numRows = tg->height / fontHeight; struct customTrack *ct = tg->customPt; char itemBuffer[1024]; if (ct) // this should have the trash file name instead of spacer // but the click handler doesn't use it anyway safef(itemBuffer, sizeof itemBuffer, "%s %s","spacer","zoom in"); else safef(itemBuffer, sizeof itemBuffer, "zoom in"); while(numRows--) { char buffer[1024]; safef(buffer, sizeof buffer, "Too many items in display. Zoom in to click on items. (%d)",numRows); mapBoxHc(hvg, seqStart, seqEnd, xOff, yOff, width, fontHeight, tg->track, itemBuffer, buffer); yOff += fontHeight; } // just do this once tg->customInt = 0; }
static void maybeDrawLeftLabels(struct track *tg, int seqStart, int seqEnd, struct hvGfx *hvg, int xOff, int yOff, int width, int height, boolean withCenterLabels, MgFont *font, Color color, enum trackVisibility vis) /* If this is invoked, we are hiding item labels. In full mode, that means no left labels. * In dense mode, we do need the left label to show shortLabel. */ { if (tg->limitedVis == tvDense) { int fontHeight = mgFontLineHeight(font); if (isCenterLabelIncluded(tg)) yOff += fontHeight; hvGfxTextRight(hvg, xOff, yOff, width, tg->lineHeight, color, font, tg->shortLabel); } return; }
void hCytoBandDrawAt(struct cytoBand *band, struct hvGfx *hvg, int x, int y, int width, int height, boolean isDmel, MgFont *font, int fontPixelHeight, Color aColor, Color bColor, Color *shades, int maxShade) /* Draw a single band in appropriate color at given position. If there's * room put in band label. */ { Color col = hCytoBandColor(band, hvg, isDmel, aColor, bColor, shades, maxShade); hvGfxBox(hvg, x, y, width, height, col); if (height >= mgFontLineHeight(font)) { char *s = abbreviatedBandName(band, font, width, isDmel); if (s != NULL) { Color textCol = hvGfxContrastingColor(hvg, col); hvGfxTextCentered(hvg, x, y, width, height, textCol, font, s); } } }
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); }
struct genoLay *genoLayNew(struct genoLayChrom *chromList, MgFont *font, int picWidth, int betweenChromHeight, int minLeftLabelWidth, int minRightLabelWidth, char *how) /* Figure out layout. For human and most mammals this will be * two columns with sex chromosomes on bottom. This is complicated * by the platypus having a bunch of sex chromosomes. */ { int margin = 3; struct slRef *refList = NULL, *ref, *left, *right; struct genoLayChrom *chrom; struct genoLay *gl; int autoCount, halfCount, bases, chromInLine; int leftLabelWidth=0, rightLabelWidth=0, labelWidth; int spaceWidth = mgFontCharWidth(font, ' '); int extraLabelPadding = 0; int autosomeOtherPixels=0, sexOtherPixels=0; int autosomeBasesInLine=0; /* Maximum bases in a line for autosome. */ int sexBasesInLine=0; /* Bases in line for sex chromsome. */ double sexBasesPerPixel, autosomeBasesPerPixel, basesPerPixel; int pos = margin; int y = 0; int fontHeight = mgFontLineHeight(font); int chromHeight = fontHeight; int lineHeight = chromHeight + betweenChromHeight; boolean allOneLine = FALSE; refList = refListFromSlList(chromList); /* Allocate genoLay object and fill in simple fields. */ AllocVar(gl); gl->chromList = chromList; gl->chromHash = hashNew(0); gl->font = font; gl->picWidth = picWidth; gl->margin = margin; gl->spaceWidth = spaceWidth; gl->lineHeight = lineHeight; gl->betweenChromHeight = betweenChromHeight; gl->betweenChromOffsetY = 0; gl->chromHeight = chromHeight; gl->chromOffsetY = lineHeight - chromHeight; /* Save chromosomes in hash too, for easy access */ for (chrom = chromList; chrom != NULL; chrom = chrom->next) hashAdd(gl->chromHash, chrom->fullName, chrom); if (sameString(how, genoLayOnePerLine)) { gl->leftList = refList; } else if (sameString(how, genoLayAllOneLine)) { gl->bottomList = refList; allOneLine = TRUE; } else { /* Put sex chromosomes on bottom, and rest on left. */ separateSexChroms(refList, &refList, &gl->bottomList); autoCount = slCount(refList); gl->leftList = refList; /* If there are a lot of chromosomes, then move later * (and smaller) chromosomes to a new right column */ if (autoCount > 12) { halfCount = (autoCount+1)/2; ref = slElementFromIx(refList, halfCount-1); gl->rightList = ref->next; ref->next = NULL; slReverse(&gl->rightList); } } if (allOneLine) { unsigned long totalBases = 0, bStart=0, bEnd; int chromCount = 0, chromIx=0; for (ref = gl->bottomList; ref != NULL; ref = ref->next) { chrom = ref->val; totalBases += chrom->size; chromCount += 1; } int availablePixels = picWidth - minLeftLabelWidth - minRightLabelWidth - 2*margin - (chromCount-1); double basesPerPixel = (double)totalBases/availablePixels; gl->picHeight = 2*margin + lineHeight + fontHeight; for (ref = gl->bottomList; ref != NULL; ref = ref->next) { chrom = ref->val; bEnd = bStart + chrom->size; int pixStart = round(bStart / basesPerPixel); int pixEnd = round(bEnd / basesPerPixel); chrom->width = pixEnd - pixStart; chrom->height = lineHeight; chrom->x = pixStart + margin + chromIx + minLeftLabelWidth; chrom->y = 0; chromIx += 1; bStart = bEnd; } gl->lineCount = 1; gl->picHeight = 2*margin + lineHeight + fontHeight + 1; gl->allOneLine = TRUE; gl->leftLabelWidth = minLeftLabelWidth; gl->rightLabelWidth = minRightLabelWidth; gl->basesPerPixel = basesPerPixel; gl->pixelsPerBase = 1.0/basesPerPixel; } else { /* Figure out space needed for autosomes. */ left = gl->leftList; right = gl->rightList; while (left || right) { bases = 0; chromInLine = 0; if (left) { chrom = left->val; labelWidth = mgFontStringWidth(font, chrom->shortName) + spaceWidth; if (leftLabelWidth < labelWidth) leftLabelWidth = labelWidth; bases = chrom->size; left = left->next; } if (right) { chrom = right->val; labelWidth = mgFontStringWidth(font, chrom->shortName) + spaceWidth; if (rightLabelWidth < labelWidth) rightLabelWidth = labelWidth; bases += chrom->size; right = right->next; } if (autosomeBasesInLine < bases) autosomeBasesInLine = bases; gl->lineCount += 1; } /* Figure out space needed for bottom chromosomes. */ if (gl->bottomList) { gl->lineCount += 1; sexOtherPixels = spaceWidth + 2*margin; for (ref = gl->bottomList; ref != NULL; ref = ref->next) { chrom = ref->val; sexBasesInLine += chrom->size; labelWidth = mgFontStringWidth(font, chrom->shortName) + spaceWidth; if (ref == gl->bottomList ) { if (leftLabelWidth < labelWidth) leftLabelWidth = labelWidth; sexOtherPixels = leftLabelWidth; } else if (ref->next == NULL) { if (rightLabelWidth < labelWidth) rightLabelWidth = labelWidth; sexOtherPixels += rightLabelWidth + spaceWidth; } else { sexOtherPixels += labelWidth + spaceWidth; } } } /* Do some adjustments if side labels are bigger than needed for * chromosome names. */ if (leftLabelWidth < minLeftLabelWidth) { extraLabelPadding += (minLeftLabelWidth - leftLabelWidth); leftLabelWidth = minLeftLabelWidth; } if (rightLabelWidth < minRightLabelWidth) { extraLabelPadding += (minRightLabelWidth - rightLabelWidth); rightLabelWidth = minRightLabelWidth; } sexOtherPixels += extraLabelPadding; /* Figure out the number of bases needed per pixel. */ autosomeOtherPixels = 2*margin + spaceWidth + leftLabelWidth + rightLabelWidth; basesPerPixel = autosomeBasesPerPixel = autosomeBasesInLine/(picWidth-autosomeOtherPixels); if (gl->bottomList) { sexBasesPerPixel = sexBasesInLine/(picWidth-sexOtherPixels); if (sexBasesPerPixel > basesPerPixel) basesPerPixel = sexBasesPerPixel; } /* Save positions and sizes of some things in layout structure. */ gl->leftLabelWidth = leftLabelWidth; gl->rightLabelWidth = rightLabelWidth; gl->basesPerPixel = basesPerPixel; gl->pixelsPerBase = 1.0/basesPerPixel; /* Set pixel positions for left autosomes */ for (ref = gl->leftList; ref != NULL; ref = ref->next) { chrom = ref->val; chrom->x = leftLabelWidth + margin; chrom->y = y; chrom->width = round(chrom->size/basesPerPixel); chrom->height = lineHeight; y += lineHeight; } /* Set pixel positions for right autosomes */ y = 0; for (ref = gl->rightList; ref != NULL; ref = ref->next) { chrom = ref->val; chrom->width = round(chrom->size/basesPerPixel); chrom->height = lineHeight; chrom->x = picWidth - margin - rightLabelWidth - chrom->width; chrom->y = y; y += lineHeight; } gl->picHeight = 2*margin + lineHeight * gl->lineCount; y = gl->picHeight - margin - lineHeight; /* Set pixel positions for sex chromosomes */ for (ref = gl->bottomList; ref != NULL; ref = ref->next) { chrom = ref->val; chrom->y = y; chrom->width = round(chrom->size/basesPerPixel); chrom->height = lineHeight; if (ref == gl->bottomList) chrom->x = leftLabelWidth + margin; else if (ref->next == NULL) chrom->x = picWidth - margin - rightLabelWidth - chrom->width; else chrom->x = 2*spaceWidth+mgFontStringWidth(font,chrom->shortName) + pos; pos = chrom->x + chrom->width; } } return gl; }