Skip to content

Instantly share code, notes, and snippets.

@jensgrubert
Forked from billdwhite/demo_treemap_04_wrappinglabels.html
Last active December 31, 2015 05:49
Show Gist options
  • Save jensgrubert/7943555 to your computer and use it in GitHub Desktop.
Save jensgrubert/7943555 to your computer and use it in GitHub Desktop.
Treemap with labels

Treemap with internal labels.

{
"name": "Adaptive to what",
"children": [
{
"name": "Human Factors",
"children": [
{
"name": "Preferences",
"children": [
{"name": "Sinclair2001", "size": 1},
{"name": "Choonsung2008", "size": 1},
{"name": "Vemezia2011", "size": 1}
]
},
{
"name": "Capabilities",
"children": [
{"name": "Sinclair2001", "size": 1},
{"name": "Stricker2012", "size": 1},
{"name": "Doswell2006", "size": 1},
{
"name": "Motion/Gestures",
"children": [
{"name": "Stricker2012", "size": 1},
{"name": "Dünser2011", "size": 1}
]
}
]
},
{
"name": "State",
"children": [
{
"name": "Physiological State",
"children": [
{"name": "Xu2012", "size": 1},
{"name": "Dünser2011", "size": 1},
{"name": "Lewandowski2011", "size": 1}
]
},
{
"name": "Attention",
"children": [
{"name": " Xu2012", "size": 1}
]
}
]
}
]
},
{
"name": "User Tasks",
"children": [
{"name": "Stricker2012", "size": 1},
{
"name": "User Goals",
"children": [
{"name": "Beadle1997", "size": 1}
]
},
{
"name": "Information",
"children": [
{
"name": "Quantity",
"children": [
{"name": "Julier2002", "size": 1}
]
},
{
"name": "Readabillity",
"children": [
{"name": "Gabbard2005", "size": 1}
]
},
{
"name": "Distance",
"children": [
{"name": "Uratani2005", "size": 1}
]
}
]
}
]
},
{
"name": "Activity/Environmental Factors",
"children": [
{
"name": "Place",
"children": [
{"name": "Bordes2011", "size": 1},
{"name": "Hervas2011", "size": 1},
{"name": "Henderson2008", "size": 1}
]
},
{
"name": "Social Networks",
"children": [
{"name": " Hervas2011", "size": 1}
]
}
]
},
{
"name": "Technical Factors",
"children": [
{
"name": "Interactive System",
"children": [
{
"name": "System State/Setup",
"children": [
{"name": "Bühling2012", "size": 1},
{"name": "MacWilliams2005", "size": 1},
{"name": "Verbelen2011", "size": 1}
]
},
{
"name": "Input",
"children": [
{
"name": "Environment Sensors",
"children": [
{
"name": "Location",
"children": [
{
"name": "Spatial Uncertainties",
"children": [
{"name": "Hallaway2004", "size": 1},
{"name": "MacIntyre2007", "size": 1},
{"name": "MacIntyre2002", "size": 1},
{"name": "Coelho2004", "size": 1}
]
}
]
},
{
"name": "Noise",
"children": [
{"name": "Xu2012", "size": 1},
{"name": "Shin2010", "size": 1}
]
},
{
"name": "Illumination",
"children": [
{"name": "Shin2010", "size": 1},
{"name": "Barakonyi2004", "size": 1}
]
},
{
"name": "Temperatur",
"children": [
{"name": "Barakonyi2004", "size": 1}
]
}
]
},
{
"name": "User Input",
"children": [
{"name": "Mendez2007", "size": 1}
]
}
]
},
{
"name": "Output",
"children": [
{
"name": "Visual Displays ",
"children": [
{
"name": "Spatial Arrangement",
"children": [
{"name": "Rosten2005", "size": 1},
{"name": "Grasset2012", "size": 1},
{"name": "Bell2002", "size": 1}
]
},
{
"name": "Composition",
"children": [
{"name": "Kalkofen2009", "size": 1},
{"name": "Kalkofen2013", "size": 1}
]
}
]
}
]
}
]
}
]
}
]
}
{
"name": "Adapting What?",
"children": [
{
"name": "System Configuration/Setup",
"children": [
{"name": "MacWilliams2005", "size": 1},
{"name": "Verbelen2011", "size": 1}
]
},
{
"name": "System Input",
"children": [
{
"name": "Interface",
"children": [
{"name": "Hallaway2004", "size": 1},
{"name": "Stricker2012", "size": 1},
{"name": "Xu2012", "size": 1},
{"name": "Hervas2011", "size": 1},
{"name": "Henderson2008", "size": 1},
{"name": "Lewandowski2011", "size": 1}
]
},
{
"name": "Interaction Modalities",
"children": [
{"name": "ArtSense", "size": 1}
]
}
]
},
{
"name": "System Output",
"children": [
{
"name": "Content",
"children": [
{"name": "Beadle1997", "size": 1},
{"name": "Bühling2012", "size": 1},
{"name": "Dünser2011", "size": 1},
{"name": "Choonsung2008", "size": 1} ,
{"name": "Doswell2006", "size": 1},
{"name": "Lewandowski2011", "size": 1},
{"name": "Shin2010", "size": 1},
{"name": "Vemezia2011", "size": 1}
]
},
{
"name": "Information Presentation",
"children": [
{
"name": "Spatial Arrangement",
"children": [
{"name": "Rosten2005", "size": 1},
{"name": "Grasset2012", "size": 1},
{"name": "Bordes2011", "size": 1}
]
},
{
"name": "Appearance Adaptation",
"children": [
{"name": "Kalkofen2013", "size": 1},
{"name": "Sinclair2001", "size": 1},
{"name": "MacIntyre2007", "size": 1},
{"name": "Bordes2011", "size": 1},
{"name": "Uratani2005", "size": 1},
{"name": "Beadle1997", "size": 1},
{"name": "Bühling2012", "size": 1},
{"name": "Kalkofen2009", "size": 1},
{"name": "Hallaway2004", "size": 1},
{"name": "MacIntyre2002", "size": 1},
{"name": "Dünser2011", "size": 1},
{"name": "Coelho2004", "size": 1},
{"name": "Bell2002", "size": 1}
]
},
{
"name": "Amount of Data",
"children": [
{"name": "Julier2002", "size": 1},
{"name": "Vemezia2011", "size": 1}
]
}
]
}
]
}
]
}
<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 src="http://d3js.org/d3.v3.min.js"></script>
<script src="d3.v3.min.js"></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>
<p>
<button onclick="switchData('data-to-what.json')">Show: "Adaptive to What?"</button>
<button onclick="switchData('data-what.json')">Show: "Adapting What?"</button>
</p>
<script type="text/javascript">
var w = 700;
var h = 700;
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)");
function switchData(dataFn) {
d3.select("svg").remove();
treemap = d3.layout.treemap()
.size([w, h])
.padding([20, 4, 4, 4])
.value(function(d) {
return d.size;
});
svg = d3.select("#chart").append("svg")
.style("position", "relative")
.style("width", w + "px")
.style("height", h + "px")
.append("g")
.attr("transform", "translate(-.5,-.5)");
drawTreemap(dataFn);
}
function drawTreemap(datFn01) {
d3.json(datFn01, 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>
<script type="text/javascript">
drawTreemap('data-to-what.json');
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment