Skip to content

Instantly share code, notes, and snippets.

@gossi
Created December 5, 2010 00:16
Show Gist options
  • Save gossi/728625 to your computer and use it in GitHub Desktop.
Save gossi/728625 to your computer and use it in GitHub Desktop.
Spacetree Label fitInNode
$jit.ST.Label.Native = new Class({
Implements: Graph.Label.Native,
renderLabel: function(canvas, node, controller) {
var ctx = canvas.getCtx(),
coord = node.pos.getc(true),
height = 0, maxHeight, lineHeight, restText, testLastLine, textSplit,
width = node.getData("width"), modifyLastLine = false, lines, i, len, y;
if (!canvas.viz.config.Node.autoWidth && ctx.measureText(node.name).width > width) {
lines = [];
maxHeight = node.getData("height");
restText = node.name;
// TextMetrics returned from measureText() from the Canvas API doesn't have a height
// property. So, this workaround here.
//
// @see http://stackoverflow.com/questions/1134586/how-can-you-find-the-height-of-text-on-an-html-canvas
// @see http://www.w3.org/Bugs/Public/show_bug.cgi?id=11472
lineHeight = ctx.measureText("imi").width;
while (restText !== "" && height + lineHeight <= maxHeight) {
text = restText;
restText = "";
textSplit = text.split(" ");
testLastLine = textSplit[textSplit.length - 1];
// ouh, last line
if (height + lineHeight > maxHeight) {
if (ctx.measureText(restText).width > width) {
modifyLastLine = true;
}
lines[lines.length] = restText;
restText = "";
} else {
while (ctx.measureText(text).width > width && textSplit.length > 1) {
restText = textSplit.pop() + " " + restText;
text = textSplit.join(" ");
}
// Problem here: If there is one word which is bigger than the node, this doesn't
// get wordwrapped anyhow at the moment
lines[lines.length] = text;
if (restText !== "") {
height += lineHeight;
}
}
}
// print lines
len = lines.length;
y = coord.y - (len - 1)/2 * lineHeight;
for (i = 0; i < len; i++) {
if (i === len - 1 && modifyLastLine) {
// last line is going out-of-bounds, do something with it.
// I'd prefer config options
// scale
ctx.fillText(lines[i], coord.x, y + lineHeight*i, width);
// TODO: crop + dots (...)
} else {
ctx.fillText(lines[i], coord.x, y + lineHeight*i);
}
}
} else {
ctx.fillText(node.name, coord.x, coord.y);
}
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment