static char *abbreviatedBandName(struct cytoBand *band, 
	MgFont *font, int width, boolean isDmel)
/* Return a string abbreviated enough to fit into space. */
{
int textWidth;
static char string[32];

/* If have enough space, return original chromosome/band. */
sprintf(string, "%s%s", (isDmel ? "" : skipChr(band->chrom)), band->name);
textWidth = mgFontStringWidth(font, string);
if (textWidth <= width)
    return string;

/* Try leaving off chromosome  */
sprintf(string, "%s", band->name);
textWidth = mgFontStringWidth(font, string);
if (textWidth <= width)
    return string;

/* Try leaving off initial letter */
sprintf(string, "%s", band->name+1);
textWidth = mgFontStringWidth(font, string);
if (textWidth <= width)
    return string;

return NULL;
}
Esempio n. 2
0
static char *abbreviateContig(char *string, MgFont *font, int width)
/* Return a string abbreviated enough to fit into space. */
{
int textWidth;

/* If have enough space, return original unabbreviated string. */
textWidth = mgFontStringWidth(font, string);
if (textWidth <= width)
    return string;

/* Try skipping over 'ctg' */
string += 3;
textWidth = mgFontStringWidth(font, string);
if (textWidth <= width)
    return string;
return NULL;
}
Esempio n. 3
0
void vgDrawRulerBumpText(struct vGfx *vg, int xOff, int yOff, 
	int height, int width,
        Color color, MgFont *font,
        int startNum, int range, int bumpX, int bumpY)
/* Draw a ruler inside the indicated part of mg with numbers that start at
 * startNum and span range.  Bump text positions slightly. */
{
int tickSpan;
int tickPos;
double scale;
int firstTick;
int remainder;
int end = startNum + range;
int x;
char tbuf[14];
int numWid;
int goodNumTicks;
int niceNumTicks = width/35;

numLabelString(startNum+range, tbuf);
numWid = mgFontStringWidth(font, tbuf)+4+bumpX;
goodNumTicks = width/numWid;
if (goodNumTicks < 1) goodNumTicks = 1;
if (goodNumTicks > niceNumTicks) goodNumTicks = niceNumTicks;

tickSpan = figureTickSpan(range, goodNumTicks);

scale = (double)width / range;

firstTick = startNum + tickSpan;
remainder = firstTick % tickSpan;
firstTick -= remainder;
for (tickPos=firstTick; tickPos<end; tickPos += tickSpan)
    {
    numLabelString(tickPos, tbuf);
    numWid = mgFontStringWidth(font, tbuf)+4;
    x = (int)((tickPos-startNum) * scale) + xOff;
    vgBox(vg, x, yOff, 1, height, color);
    if (x - numWid >= xOff)
        {
        vgTextCentered(vg, x-numWid + bumpX, yOff + bumpY, numWid, 
	    height, color, font, tbuf);
        }
    }
}
static void midLabel(struct hvGfx *hvg, struct genoLay *gl,
	struct genoLayChrom *chrom, int yOffset, int fontHeight, 
	int color)
/* Draw a chromosome with label on left. */
{
MgFont *font = gl->font;
int textWidth = mgFontStringWidth(font, chrom->shortName);
hvGfxTextRight(hvg, chrom->x - textWidth - gl->spaceWidth, 
    chrom->y + yOffset, 
    textWidth, fontHeight, color,
    font, chrom->shortName);
}
int ggLabelWidth(struct genoGraph *gg, MgFont *font)
/* Return width used by graph labels. */
{
struct chromGraphSettings *cgs = gg->settings;
int i;
int minLabelWidth = 0, labelWidth;
char buf[24];
fakeEmptyLabels(cgs);
for (i=0; i<cgs->linesAtCount; ++i)
    {
    safef(buf, sizeof(buf), "%g ", cgs->linesAt[i]);
    labelWidth = mgFontStringWidth(font, buf);
    if (labelWidth > minLabelWidth)
        minLabelWidth = labelWidth;
    }
return minLabelWidth;
}
Esempio n. 6
0
int gifLabelMaxWidth(char **labels, int labelCount)
/* Return maximum pixel width of labels.  It's ok to have
 * NULLs in labels array. */
{
int width = 0, w, i;
MgFont *font = mgMediumFont();
for (i=0; i<labelCount; ++i)
    {
    char *label = labels[i];
    if (label != NULL)
	{
	w = mgFontStringWidth(font, labels[i]);
	if (w > width)
	    width = w;
	}
    }
width += 2;
return width;
}
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;
}
Esempio n. 8
0
static void altGraphXDrawAt(struct track *tg, void *item, struct hvGfx *hvg, 
			    int xOff, int yOff, double scale, 
			    MgFont *font, Color color, enum trackVisibility vis)
/* Draw an altGraphX at the specified location. */
{
int i = 0;
int s =0, e=0;
int heightPer = tg->heightPer;
int start = 0, end = 0;
struct altGraphX *ag = item;
int width = 0;
int x1, x2;

/* Create a link to hgc. */
if(tg->mapsSelf && tg->mapItem)
    {
    char name[256];
    int nameWidth = 0;
    int textX = 0;
    start = max(winStart, ag->tStart);
    end = min(winEnd, ag->tEnd);
    width = (end - start) * scale;
    x1 = round((double)((int) start - winStart)*scale) + xOff;
    textX = x1;
    if(width == 0)
	width = 1;
    /* If there isn't enough room on before the left edge snap the
       label to the left edge. */
    if(withLeftLabels && tg->limitedVis == tvPack)
	{
	safef(name, sizeof(name), "%s", tg->itemName(tg, ag));
	nameWidth = mgFontStringWidth(font, name);
	textX = textX - (nameWidth + tl.nWidth/2);
	if(textX < insideX)
	    textX = insideX - nameWidth;
	width = width + (x1 - textX);
	}
    tg->mapItem(tg, hvg, ag, "notUsed", "notUsed", ag->tStart, ag->tEnd, textX, yOff, width, heightPer);
    }

/* Draw the edges (exons and introns). */
for(i= 0; i <  ag->edgeCount; i++)
    {
    Color color2;
    s = ag->vPositions[ag->edgeStarts[i]];
    e = ag->vPositions[ag->edgeEnds[i]];
    color2 = MG_BLACK;
/*  If you want to shade by number of transcripts uncomment next line. */
/* 	color2 = altGraphXColorForEdge(hvg, ag, i); */
    if(isExon(ag, i))
	{
	if(vis == tvPack)
	    drawScaledBox(hvg, s, e, scale, xOff, yOff+heightPer/2, heightPer/2, color2);
	else
	    drawScaledBox(hvg, s, e, scale, xOff, yOff, heightPer, color2);
	}
    else 
	{
	int midX;   
	s = ag->vPositions[ag->edgeStarts[i]];
	e = ag->vPositions[ag->edgeEnds[i]];
	x1 = round((double)((int) s - winStart)*scale) + xOff;
	x2 = round((double)((int) e - winStart)*scale) + xOff;
	if(vis == tvPack)
	    {
	    midX = (x1+x2)/2;
	    hvGfxLine(hvg, x1, yOff+heightPer/2, midX, yOff, color2);
	    hvGfxLine(hvg, midX, yOff, x2, yOff+heightPer/2, color2);
	    }
	else
	    hvGfxLine(hvg, x1, yOff+heightPer/2, x2, yOff+heightPer/2, color2);
	}
    }
}