int colWidth = theme.getColumnWidth();
double pad = theme.getVerticalLinePadding();
canvas.setCoordinateSpaceHeight(height);
canvas.setCoordinateSpaceWidth(colWidth * getTotalWidth(theme));
Context2d ctx = canvas.getContext2d();
//ctx.clearRect(0, 0, colWidth * columns_.length, height);
ctx.translate(colWidth / 2.0, 0);
int startPos = -1;
int endPos = -1;
int nexusColumn = -1;
for (int i = 0; i < columns_.length; i++)
{
GraphColumn c = columns_[i];
if (!c.start)
startPos++;
if (!c.end)
endPos++;
ctx.setStrokeStyle(theme.getColorForId(c.id));
ctx.setLineWidth(theme.getStrokeWidth());
ctx.setLineJoin(LineJoin.ROUND);
if (!c.nexus && !c.start && !c.end)
{
// Just draw a line from start to end position
ctx.beginPath();
ctx.moveTo(startPos * colWidth, 0);
ctx.lineTo(startPos * colWidth, pad);
// This next lineTo helps ensure that the shape of the line looks
// congruous to any specials on the same line
ctx.lineTo(Math.min(startPos, endPos) * colWidth, height / 2.0);
ctx.lineTo(endPos * colWidth, height - pad);
ctx.lineTo(endPos * colWidth, height);
ctx.stroke();
}
else
{
// something special
if (c.nexus)
{
nexusColumn = i;
ctx.setFillStyle(theme.getColorForId(c.id));
}
if (!c.start)
{
// draw from i to nexusColumn;
ctx.beginPath();
ctx.moveTo(startPos * colWidth, 0);
ctx.lineTo(startPos * colWidth, pad);
ctx.lineTo(nexusColumn * colWidth, height / 2.0);
ctx.stroke();
}
if (!c.end)
{
// draw from nexusColumn to endPosition
ctx.beginPath();
ctx.moveTo(nexusColumn * colWidth, height / 2.0);
ctx.lineTo(endPos * colWidth, height - pad);
ctx.lineTo(endPos * colWidth, height);
ctx.stroke();
}
}
}
// draw a circle on the nexus
ctx.beginPath();
ctx.arc(nexusColumn * colWidth, height / 2.0,
theme.getCircleRadius() + theme.getStrokeWidth(), 0, Math.PI * 2);
ctx.closePath();
ctx.fill();
ctx.beginPath();
ctx.arc(nexusColumn * colWidth, height / 2.0,
theme.getCircleRadius(), 0, Math.PI * 2);
ctx.closePath();
ctx.setFillStyle("white");
ctx.fill();
}