Skip to content

Instantly share code, notes, and snippets.

@henripal
Created November 30, 2015 20:30
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save henripal/4f04ff8b981a3168b342 to your computer and use it in GitHub Desktop.
Save henripal/4f04ff8b981a3168b342 to your computer and use it in GitHub Desktop.
body {
font: 10px sans-serif;
}
.label {
font-weight: bold;
}
#ext{
padding-left: 150px;
float: left;
}
.tile, .tile2, .tile3 {
shape-rendering: crispEdges;
stroke-width: 1px;
shadow: null;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
var hist_height = 100;
var heat_height = 400;
var heat_width = 500;
var hist_width = 100;
var schem_width = 200;
var bar_padding = 2;
var margin = {top: 20, right: 90, bottom: 80, left: 60, center: 10, center_right: 10},
width = heat_width + 2*hist_width + margin.center_right + schem_width,
height = heat_height + hist_height + margin.center;
// margin.center is the margin between histogram and heatmap, center_right for the other histogram
// x and y are the scales for the heatmap
// z is the color scale
// z_alt is the color scale for mouseover
// y_hist is the color scale for the right histogram
// y_hist is the color scale for the bottom histogram
var x = d3.scale.linear().range([0, heat_width]),
x_hist = d3.scale.linear().range([0, hist_width]),
y = d3.scale.linear().range([heat_height, 0]),
y_hist = d3.scale.linear().range([0, hist_height]),
z = d3.scale.linear().range(["white", "steelblue"]);
z_alt = d3.scale.linear().range(["white", "red"]);
// The size of the buckets in the CSV data file.
// This could be inferred from the data if it weren't sparse.
var xStep = 1,
yStep = 1;
// creating svg for everything
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
// subgroup for the heatmap
var heatmap =svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + (margin.top+hist_height+margin.center) + ")");
// loading the csv and executing code inside it:
d3.csv("motor_extensions_clean.csv", function(error, buckets) {
if (error) throw error;
// Coerce the CSV data to the appropriate types.
buckets.forEach(function(d) {
d.distance = +d.distance;
d.extension_bin = +d.extension_bin+5-1; //adding the globular tail + 5 and first bucket -1
d.count = +d.Count/84982;
});
// grouping the data for the bottom histogram
var d_hist = d3.nest()
.key(function(d) { return d.distance; })
.rollup(function(d) {
return d3.sum(d, function(g) { return g.count; });
})
.entries(buckets);
// calculating the maximum for the bottom histogram
var d_hist_max = d3.max(d_hist, function (d) { return d.values; });
// grouping the data for the right histogram
var d_hist_right = d3.nest()
.key(function(d) { return d.extension_bin; })
.rollup(function(d) {
return d3.sum(d, function(g) { return g.count; });
})
.entries(buckets);
// calculating the maximum for the bottom histogram
var d_hist_right_max = d3.max(d_hist_right, function (d) { return d.values; });
// Compute the scale domains.
x.domain(d3.extent(buckets, function(d) { return d.extension_bin; }));
y.domain(d3.extent(buckets, function(d) { return d.distance; }));
z.domain([0, d3.max(buckets, function(d) { return d.count; })]);
z_alt.domain([0, d3.max(buckets, function(d) { return d.count; })]);
// domain for the histogram
y_hist.domain([0, d_hist_right_max]);
x_hist.domain([0, d_hist_max]);
// Extend the x- and y-domain to fit the last bucket.
// For example, the y-bucket 3200 corresponds to values [3200, 3300].
x.domain([x.domain()[0], +x.domain()[1] + xStep]);
y.domain([y.domain()[0], y.domain()[1] + yStep]);
// y_hist.domain([y_hist.domain()[0], y_hist.domain()[1] + yStep]);
// Display the tiles for each non-zero bucket.
// See http://bl.ocks.org/3074470 for an alternative implementation.
heatmap
// .attr("transform", "translate(0," + (hist_height + margin.center) + ")")
.selectAll(".tile")
.data(buckets)
.enter().append("rect")
.attr("class", function(d) {
return "tile dist_group_" + d.distance + " ext_group_" + d.extension_bin; //dist_group will be used to mouseover similar elements
})
.attr("x", function(d) { return x(d.extension_bin); })
.attr("y", function(d) { return y(d.distance+yStep); })
.attr("width", x(xStep) - x(0))
.attr("height", y(0) - y(yStep))
.style("fill", function(d) { return z(d.count); })
.on("mouseover", function(d) {
d3.select(this)
.style("fill", function(d) { return z_alt(d.count); })
.style("stroke", "black");
d3.selectAll(".tile3").filter("." + this.classList[1]) //this.classList[1] will return the dist_group!
.style("fill", z_alt(d.count))
.style("stroke", "black");
d3.selectAll(".tile2").filter("." + this.classList[2]) //this.classList[1] will return the dist_group!
.style("fill", z_alt(d.count))
.style("stroke", "black");
})
// reset everything on mouseout
.on("mouseout", function() {
d3.select(this)
.style("fill", function(d) { return z(d.count); })
.style("stroke", null);
d3.selectAll(".tile3").filter("." + this.classList[1])
.style("fill", "steelblue")
.style("stroke", null);
d3.selectAll(".tile2").filter("." + this.classList[2]) //this.classList[1] will return the dist_group!
.style("fill", "steelblue")
.style("stroke", null);
});
// adding the potential histogram
heatmap.append("g")
// starts above the heatmap
.attr("transform", "translate(0," + (-hist_height - margin.center) + ")")
.selectAll(".tile2")
.data(d_hist_right)
.enter().append("rect")
.attr("class", function(d) {
return "tile2 ext_group_" + d.key; // to group it with heatmap data
})
.attr("x", function(d) { return x(d.key) + bar_padding; })
// this will appear later
.attr("y", function(d) { return hist_height; })
.attr("width", x(xStep) - x(0)-2*bar_padding)
// this will also appear later
// .attr("height", function(d) { return y_hist(d.values); })
.attr("height", 0)
.style("fill", "steelblue")
.style("opacity", 0.5);
// adding the potential histogram to the right
heatmap.append("g")
// starts to the right of the heatmap
.attr("transform", "translate(" + (heat_width + margin.center_right) + ",0)")
.selectAll(".tile3")
.data(d_hist)
.enter().append("rect")
.attr("class", function(d) {
return "tile3 dist_group_" + d.key; // to group it with heatmap data
})
.attr("x", function(d) { return 0; })
.attr("y", function(d) { return y(+1*d.key + yStep); })
.attr("width", 0)
.attr("height", -y(yStep) + y(0)-2*bar_padding)
.style("fill", "steelblue")
.style("opacity", 0.5);
// Add a legend for the color values.
var legend = heatmap.selectAll(".legend")
.data(z.ticks(6).slice(1).reverse())
.enter().append("g")
.attr("class", "legend")
.attr("transform", function(d, i) { return "translate(" + (80 + 40*i) + "," + (20) + ")"; });
legend.append("rect")
.attr("width", 40)
.attr("height", 20)
.style("fill", z);
legend.append("text")
.attr("x", 0)
.attr("y", -10)
.attr("dy", ".35em")
.text(String);
heatmap.append("text")
.attr("class", "label")
.attr("x", 80)
.attr("y", 50)
.attr("dy", ".35em")
.text("fraction of bound motors");
// Add an x-axis with label.
heatmap.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (heat_height) + ")")
.call(d3.svg.axis().scale(x).orient("bottom"))
.attr("font-size","1.5em")
.append("text")
.attr("class", "label")
.attr("x", heat_width/2)
.attr("y", 40)
.attr("text-anchor", "middle")
.text("tail extension (nm)");
// Add a y-axis with label.
heatmap.append("g")
.attr("class", "y axis")
.call(d3.svg.axis().scale(y).orient("left"))
.attr("font-size","1.5em")
.append("text")
.attr("class", "label")
.attr("x", -heat_height/2)
.attr("y", -45)
.attr("dy", ".71em")
.attr("text-anchor", "middle")
.attr("transform", "rotate(-90)")
.text("distance from MT axis (nm)");
// updating stuff
d3.select("#ext")
.on("click", function() {
// heatmap.selectAll(".x")
// .transition()
// .duration(200)
// .attr("transform", "translate(0," + (height) + ")")
heatmap.selectAll(".tile2")
.transition()
.duration(1000)
.delay(function(d, i) {
return i * 20;
})
// .duration(500)
.attr("height", function(d) { return y_hist(d.values); })
.attr("y", function(d) { return hist_height-y_hist(d.values); });
}); // end updating stuff
// updating stuff 2
d3.select("#dist")
.on("click", function() {
// heatmap.selectAll(".x")
// .transition()
// .duration(200)
// .attr("transform", "translate(0," + (height) + ")")
heatmap.selectAll(".tile3")
.transition()
.duration(1000)
.delay(function(d, i) {
return i * 20;
})
// .duration(500)
.attr("width", function(d) { return x_hist(d.values); });
}); // end updating stuff
}); //get out of csv
<!DOCTYPE html>
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
<link rel="stylesheet" type="text/css" href="../custom.css">
</head>
<body>
<div id="ext">
<input name="updateButton"
type="button"
value="extension distribution"/>
</div>
<div id="dist">
<input name="updateButton"
type="button"
value="width distribution"/>
</div>
<div id="graph"></div>
<script type="text/javascript" src=./Heatmap.js">
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment