Skip to content

Instantly share code, notes, and snippets.

@biovisualize
Created October 14, 2011 07:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save biovisualize/1286477 to your computer and use it in GitHub Desktop.
Save biovisualize/1286477 to your computer and use it in GitHub Desktop.
Line chart with icicle diagram range selector
<html>
<head>
<title></title>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<style type="text/css">
.domain{
display: none;
}
</style>
</head>
<body>
<div id="viz"></div>
<script type="text/javascript">
var data = [],
dimensions = [],
h = 200,
w = 400,
chartH = 150,
chartW = 350,
chartX = 50,
chartY = 50;
/********************************
* Data
*********************************/
data = [10, 40, 35, 50, 75, 80, 70, 75, 90, 60, 70, 100];
dimensions[0] = {"name": "year", "len": 12};
dimensions[1] = {"name": "quarter", "len": 3};
dimensions[2] = {"name": "month", "len": 1};
/********************************
* Icicle selector
*********************************/
var rootSVG = d3.select("#viz")
.append("svg:svg")
.attr("width", w)
.attr("height", h);
rootSVG.selectAll("g.level")
.data(dimensions)
.enter().append("svg:g")
.attr("class", "level")
.each(function(parentD, parentI){
d3.select(this)
.selectAll("rect.member")
.data(function(d, i){return d3.range(data.length/d.len)})
.enter().append("svg:rect")
.attr("class", "member")
.attr("width", function(){return ~~(parentD.len/data.length*chartW)})
.attr("height", function(){return~~(chartH/dimensions.length)})
.attr("x", function(d, i){return ~~(i*parentD.len/data.length*chartW)+chartX})
.attr("y", ~~(parentI*chartH/dimensions.length))
.attr("fill", "white")
.attr("stroke", "#eee")
.on("mouseover", function(d, i){
var thisRect = d3.select(this);
d3.select("svg")
.append("svg:rect")
.attr("class", "zone")
.attr("fill", "dodgerblue")
.attr("x", thisRect.attr("x"))
.attr("y", 0)
.attr("width", thisRect.attr("width"))
.attr("height", chartH)
.attr("opacity", 0.3)
.attr("pointer-events", "none");
})
.on("mouseout", function(d, i){
d3.selectAll("rect.zone")
.remove();
})
.on("mousedown", function(d, i){
rescale(i, i+dimensions[parentI].len);
});
});
/********************************
* Chart
*********************************/
var y = d3.scale.linear().domain([0, d3.max(data)+10]).range([chartH, 0]);
var x = d3.scale.linear().domain([0, data.length]).range([chartX+15, chartW+chartX+15]);
var yAxis = d3.svg.axis().scale(y).ticks(3).orient("left");
var xAxis = d3.svg.axis().scale(x);
var chart = rootSVG.append("svg:g")
.attr("pointer-events", "none")
.attr("clip-path", "url(#clip)");
chart.append("svg:rect")
.attr("width", chartW)
.attr("height", chartH)
.attr("x", chartX)
.attr("stroke", "black")
.attr("stroke-width", "1")
.attr("fill", "none");
chart.selectAll("circle.dot")
.data(data)
.enter().append("svg:circle")
.attr("class", "dot")
.attr("cx", function(d, i){return x(i)})
.attr("cy", y)
.attr("r", 3);
var line = d3.svg.line()
.interpolate("monotone")
.x(function(d, i) { return x(i); })
.y(function(d, i) { return y(d); });
chart.append("svg:path")
.attr("class", "line")
.attr("d", line(data))
.attr("fill", "none")
.attr("stroke", "black");
rootSVG.append("svg:clipPath")
.attr("id", "clip")
.append("svg:rect")
.attr("width", chartW)
.attr("height", chartH)
.attr("x", chartX);
rootSVG.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + chartH + ")")
.call(xAxis);
rootSVG.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(" + chartX + ",0)")
.call(yAxis);
function rescale(start, end) {
x.domain([start, end]);
var t = rootSVG.transition().duration(500);
t.select(".x.axis").call(xAxis);
t.select(".line").attr("d", line(data));
chart.selectAll("circle.dot")
.transition().duration(500)
.attr("cx", function(d, i){return x(i)});
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment