Skip to content

Instantly share code, notes, and snippets.

@danasilver
Created March 26, 2014 21:28
Show Gist options
  • Save danasilver/9794012 to your computer and use it in GitHub Desktop.
Save danasilver/9794012 to your computer and use it in GitHub Desktop.
Orange Trees

Circumference of orange trees over time.

Data comes from R's "Orange" dataset. Legend created with d3.legend.js (MIT License).

For CS465 at Middlebury College.

// d3.legend.js
// (C) 2012 [email protected]
// MIT licence
(function() {
d3.legend = function(g) {
g.each(function() {
var g = d3.select(this),
items = {},
svg = d3.select(g.property("nearestViewportElement")),
legendPadding = g.attr("data-style-padding") || 5,
lb = g.selectAll(".legend-box").data([true]),
li = g.selectAll(".legend-items").data([true])
lb.enter().append("rect").classed("legend-box",true)
li.enter().append("g").classed("legend-items",true)
svg.selectAll("[data-legend]").each(function() {
var self = d3.select(this)
items[self.attr("data-legend")] = {
pos : self.attr("data-legend-pos") || this.getBBox().y,
color : self.attr("data-legend-color") != undefined ? self.attr("data-legend-color") : self.style("fill") != 'none' ? self.style("fill") : self.style("stroke")
}
})
items = d3.entries(items).sort(function(a,b) { return a.value.pos-b.value.pos})
li.selectAll("text")
.data(items,function(d) { return d.key})
.call(function(d) { d.enter().append("text")})
.call(function(d) { d.exit().remove()})
.attr("y",function(d,i) { return i+"em"})
.attr("x","1em")
.text(function(d) { ;return d.key})
li.selectAll("circle")
.data(items,function(d) { return d.key})
.call(function(d) { d.enter().append("circle")})
.call(function(d) { d.exit().remove()})
.attr("cy",function(d,i) { return i-0.25+"em"})
.attr("cx",0)
.attr("r","0.4em")
.style("fill",function(d) { return d.value.color})
// Reposition and resize the box
var lbbox = li[0][0].getBBox()
lb.attr("x",(lbbox.x-legendPadding))
.attr("y",(lbbox.y-legendPadding))
.attr("height",(lbbox.height+2*legendPadding))
.attr("width",(lbbox.width+2*legendPadding))
})
return g
}
})()
<DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font-family: "Helvetica Neue", Helvetica, sans-serif;
}
svg {
font: 10px sans-serif;
}
.line {
fill: none;
stroke-width: 1.5px;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.legend rect {
fill:white;
stroke:black;
opacity:0.8;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<script src="d3.legend.js" charset="utf-8"></script>
<script>
var margin = {top: 20, right: 30, bottom: 30, left: 40},
width = 960 - margin.right - margin.left,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.linear()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var line = d3.svg.line()
.x(function(d) { return x(d.age); })
.y(function(d) { return y(d.circumference); });
var color = d3.scale.category10();
d3.csv("orange.csv", function(error, trees) {
trees.forEach(function(d) {
d.Tree = +d.Tree;
d.age = +d.age;
d.circumference = +d.circumference;
});
nestedTrees = d3.nest()
.key(function(d) { return +d.Tree; })
.entries(trees);
x.domain(d3.extent(trees, function(d) { return d.age; }));
y.domain(d3.extent(trees, function(d) { return d.circumference; }));
color.domain(d3.keys(nestedTrees));
var name = svg.selectAll(".tree")
.data(nestedTrees, function(d) { return d.key; })
.enter().append("g")
.attr("class", "tree");
name.append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.values); })
.attr("data-legend", function(d) { return "Tree " + d.key; })
.attr("data-legend-color", function(d) { return color(d.key)})
.style("stroke", function(d) { return color(d.key); });
var point = svg.selectAll("circle")
.data(trees)
.enter().append("circle")
.attr("r", 3)
.attr("cx", function(d) { return x(d.age); })
.attr("cy", function(d) { return y(d.circumference); })
.attr("fill", function(d) { return color(d.Tree); });
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.append("text")
.attr("x", width)
.attr("dy", "-.71em")
.style("text-anchor", "end")
.text("Age (days)");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Circumference (mm)");
legend = svg.append("g")
.attr("class","legend")
.attr("transform","translate(50,30)")
.style("font-size","12px")
.call(d3.legend);
});
</script>
</body>
Tree age circumference
1 118 30
1 484 58
1 664 87
1 1004 115
1 1231 120
1 1372 142
1 1582 145
2 118 33
2 484 69
2 664 111
2 1004 156
2 1231 172
2 1372 203
2 1582 203
3 118 30
3 484 51
3 664 75
3 1004 108
3 1231 115
3 1372 139
3 1582 140
4 118 32
4 484 62
4 664 112
4 1004 167
4 1231 179
4 1372 209
4 1582 214
5 118 30
5 484 49
5 664 81
5 1004 125
5 1231 142
5 1372 174
5 1582 177
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment