Switch between stacked and grouped layouts using sequenced transitions! Animations preserve object constancy and allow the user to follow the data across views. Animation design by Heer and Robertson. Colors and data generation inspired by Byron and Wattenberg.
forked from mbostock's block: Stacked-to-Grouped Bars
forked from scresawn's block: bar chart 5
forked from lesevimx's block: bar chart 5
xxxxxxxxxx
<meta charset="utf-8">
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: auto;
position: relative;
width: 960px;
}
.title {
font: 20px sans-serif;
fill: black;
}
.bar {
stroke: black;
}
.bar:hover {
fill: green;
}
.axis {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
/*display: none;*/
}
form {
position: absolute;
right: 10px;
top: 10px;
}
.d3-tip {
line-height: 1;
font-weight: bold;
padding: 12px;
background: rgba(0, 0, 0, 0.9);
color: #fff;
border-radius: 2px;
}
/* Creates a small triangle extender for the tooltip */
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 10px;
width: 100%;
line-height: 1;
color: rgba(0, 0, 0, 0.8);
content: "\25BC";
position: absolute;
text-align: center;
}
/* Style northward tooltips differently */
.d3-tip.n:after {
margin: -1px 0 0 0;
top: 100%;
left: 0;
}
</style>
<form>
<label><input type="radio" name="mode" value="grouped"> Grouped</label>
<label><input type="radio" name="mode" value="stacked" checked> Stacked</label>
</form>
<script src="//d3js.org/d3.v3.min.js"></script>
<script src="https://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js"></script>
<script>
function type(d) {
d["Expression (5 min)"] = +d["Expression (5 min)"];
d["Expression (30 min)"] = +d["Expression (30 min)"];
d["Expression (60 min)"] = +d["Expression (60 min)"];
return d;
}
d3.csv("dataConsolidated.csv", type, function(error, data) {
if (error) throw error;
/*var dataByTimePoint = d3.nest()
.key(function(d) { return d.TimePoint; })
.entries(data);
//console.log(dataByTimepoint);*/
dataLayer = function(g) {
return data.map(function(d, i) {
//console.log(d, i,g);
return {x: d.GeneNumber, y: d[g], Function: d.Function};
});
};
var n = 3, // number of layers
m = 88, // number of samples per layer
stack = d3.layout.stack();
layers = stack(['Expression (5 min)', 'Expression (30 min)', 'Expression (60 min)'].map(function(a) { return dataLayer(a);}));
yGroupMax = d3.max(layers, function(layer) { return d3.max(layer, function(d) { return d.y; }); }),
yStackMax = d3.max(layers, function(layer) { return d3.max(layer, function(d) { return d.y0 + d.y; }); });
var margin = {top: 40, right: 10, bottom: 80, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var x = d3.scale.ordinal()
.domain(d3.range(1,m+1))
.rangeRoundBands([0, width], .08);
var y = d3.scale.linear()
.domain([0, yStackMax])
.range([height, 0]);
/*var color = d3.scale.linear()
.domain([0, n - 1])
.range(["#b5c062", "#834ed4"]);*/
var color = d3.scale.ordinal()
.range(['gold', 'gray', 'purple']);
var xAxis = d3.svg.axis()
.scale(x)
.tickSize(0)
.tickPadding(6)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left");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 layer = svg.selectAll(".layer")
.data(layers)
.enter().append("g")
.attr("class", "layer")
.style("fill", function(d, i) { return color(i); });
var rect = layer.selectAll("rect")
.data(function(d) { return d; })
.enter().append("rect")
.attr("x", function(d) { return x(d.x); })
.attr("y", height)
.attr("width", x.rangeBand())
.attr("height", 0);
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
console.log(d);
return "<strong>Function:</strong> <span style='color:yellow'>" + d.Function + "</span>";
});
rect
.on('mouseover', tip.show)
.on('mouseout', tip.hide);;
svg.call(tip);
rect.transition()
.delay(function(d, i) { return i * 10; })
.attr("y", function(d) { return y(d.y0 + d.y); })
.attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); });
x_group = svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
x_group
.selectAll("text")
.attr("transform", function (d) {return "rotate(-60," + 0 + "," + 14 + ")"});
svg.append("g")
.attr("class", "axis")
.append("text")
.attr("font-size", 16)
.attr("text-anchor", "end")
.attr("x", width)
.attr("y", height + margin.bottom/2)
.attr("shape-rendering", "crispEdges")
.text("Kampy Gene Number");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("font-size", 16)
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Expression (RPKM)");
var legend = svg.selectAll(".legend")
.data(d3.keys(data[0]).slice(5))
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; })
.style("font", "10px sans-serif");
legend.append("rect")
.attr("x", width - 18)
.attr("width", 18)
.attr("height", 18)
.attr("fill", function(d,i) { return color(i);});
legend.append("text")
.attr("x", width - 24)
.attr("y", 9)
.attr("dy", ".35em")
.attr("text-anchor", "end")
.text(function(d) { return d; });
d3.selectAll("input").on("change", change);
var timeout = setTimeout(function() {
d3.select("input[value=\"grouped\"]").property("checked", true).each(change);
}, 2000);
function change() {
clearTimeout(timeout);
if (this.value === "grouped") transitionGrouped();
else transitionStacked();
}
function transitionGrouped() {
y.domain([0, yGroupMax]);
rect.transition()
.duration(500)
.delay(function(d, i) { return i * 10; })
.attr("x", function(d, i, j) { return x(d.x) + x.rangeBand() / n * j; })
.attr("width", x.rangeBand() / n)
.transition()
.attr("y", function(d) { return y(d.y); })
.attr("height", function(d) { return height - y(d.y); });
}
function transitionStacked() {
y.domain([0, yStackMax]);
rect.transition()
.duration(500)
.delay(function(d, i) { return i * 10; })
.attr("y", function(d) { return y(d.y0 + d.y); })
.attr("height", function(d) { return y(d.y0) - y(d.y0 + d.y); })
.transition()
.attr("x", function(d) { return x(d.x); })
.attr("width", x.rangeBand());
}
});
</script>
Modified http://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js to a secure url
https://d3js.org/d3.v3.min.js
https://labratrevenge.com/d3-tip/javascripts/d3.tip.v0.6.3.js