Skip to content

Instantly share code, notes, and snippets.

@billdwhite
Last active November 20, 2020 21:25
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save billdwhite/6243279 to your computer and use it in GitHub Desktop.
Save billdwhite/6243279 to your computer and use it in GitHub Desktop.
treemap with truncating labels
<html>
<head>
<title>Treemap with Wrapping and Truncated Labels</title>
<meta charset="utf-8">
<!-- poor man's browser detection -->
<!--[if IE]><script type="text/javascript">window['isIE'] = true;</script><![endif]-->
<script type="text/javascript" src="./d3/d3.js" charset="utf-8"></script>
<style type="text/css">
html, body {
overflow: hidden;
margin: 0;
font-family: "Helvetica Neue", Helvetica;
}
rect {
fill: none;
stroke: #FFFFFF;
}
.labelbody {
margin: 2px;
}
.foreignObject {
font: 9px sans-serif;
text-overflow: ellipsis;
text-align: left;
word-wrap: break-word;
}
</style>
</head>
<body>
<div id="chart"></div>
<script type="text/javascript">
var w = 550;
var h = 550;
var paddingAllowance = 2;
var color = d3.scale.category20c();
var treemap = d3.layout.treemap()
.size([w, h])
.padding([20, 4, 4, 4])
.value(function(d) {
return d.size;
});
var svg = d3.select("#chart").append("svg")
.style("position", "relative")
.style("width", w + "px")
.style("height", h + "px")
.append("g")
.attr("transform", "translate(-.5,-.5)");
d3.json("../data/flare0.json", function(json) {
var cell = svg.data([json]).selectAll("g")
.data(treemap)
.enter().append("g")
.attr("class", "cell")
.attr("transform", function(d) {
return "translate(" + d.x + "," + d.y + ")";
});
cell.append("rect")
.attr("width", function(d) {
return d.dx;
})
.attr("height", function(d) {
return d.dy;
})
.style("fill", function(d) {
return d.children ? color(d.name) : null;
});
if (window['isIE']) { // IE sucks so you have to manually truncate the labels here
cell.append("text")
.attr("class", "foreignObject")
.attr("transform", "translate(3, 13)")
.text(function(d) {
return (d.dy < 16 ? "" : d.name);
})
.filter(function(d) {
d.tw = this.getComputedTextLength();
return d.dx < d.tw;
})
.each(function(d) { // ridiculous routine where we test to see if label is short enough to fit
var proposedLabel = d.name;
var proposedLabelArray = proposedLabel.split('');
while (d.tw > d.dx && proposedLabelArray.length) {
// pull out 3 chars at a time to speed things up (one at a time is too slow)
proposedLabelArray.pop(); proposedLabelArray.pop(); proposedLabelArray.pop();
if (proposedLabelArray.length===0) {
proposedLabel = "";
} else {
proposedLabel = proposedLabelArray.join('') + "..."; // manually truncate with ellipsis
}
d3.select(this).text(proposedLabel);
d.tw = this.getComputedTextLength();
}
});
} else {
// normal browsers use these labels; using foreignObject inside SVG allows use of wrapping text inside
// divs rather than less-flexible svg-text labels
cell.append("foreignObject")
.attr("class", "foreignObject")
.attr("width", function(d) {
return d.dx - paddingAllowance;
})
.attr("height", function(d) {
return d.dy - paddingAllowance;
})
.append("xhtml:body")
.attr("class", "labelbody")
.append("div")
.attr("class", "label")
.text(function(d) {
return d.name;
})
.attr("text-anchor", "middle")
}
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment