Skip to content

Instantly share code, notes, and snippets.

@phuquoc
Last active December 11, 2018 10:36
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 phuquoc/1a1e75e1cc0405784cfb9c787801540c to your computer and use it in GitHub Desktop.
Save phuquoc/1a1e75e1cc0405784cfb9c787801540c to your computer and use it in GitHub Desktop.
TP4_11419813
license: mit
<!DOCTYPE html>
<html lang="en">
<style>
.axis .domain {
display: none;
}
</style>
<body>
<head>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font- awesome/4.4.0/css/font-awesome.min.css">
</head>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var n = 10, // number of samples (columns)
m = 5; // number of series (layers)
var data = d3.range(n).map(function() {
return d3.range(m).map(Math.random);
});
var margin = {top: 20, right: 30, bottom: 30, left: 40},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var layers = d3.stack().keys(d3.range(m))(data);
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 + ")");
// Display stack bar chart first
stackBar()
// Button to switch between modes
//container for all buttons
var allButtons= svg.append("g")
.attr("id","allButtons");
//colors for different button states
var defaultColor= "#7777BB"
var hoverColor= "#0000ff"
var pressedColor= "#000077"
var labels= ["Grouped", "Stacked"];
//groups for each button (which will hold a rect and text)
var buttonGroups= allButtons.selectAll("g.button")
.data(labels)
.enter()
.append("g")
.attr("class","button")
.style("cursor","pointer")
.on("click", buttonClicked)
.on("mouseover", function() {
if (d3.select(this).select("rect").attr("fill") != pressedColor){
d3.select(this)
.select("rect")
.attr("fill",hoverColor);
}
})
.on("mouseout", function() {
if (d3.select(this).select("rect").attr("fill") != pressedColor) {
d3.select(this)
.select("rect")
.attr("fill",defaultColor);
}
})
var bWidth= 80; //button width
var bHeight= 30; //button height
var bSpace= 10; //space between buttons
var x0= 200; //x offset
var y0= 66; //y offset
//adding a rect to each toggle button group
//rx and ry give the rect rounded corner
buttonGroups.append("rect")
.attr("class","buttonRect")
.attr("width",bWidth)
.attr("height",bHeight)
.attr("x",function(d,i) {return x0+(bWidth+bSpace)*i;})
.attr("y",y0)
.attr("rx",5) //rx and ry give the buttons rounded corners
.attr("ry",5)
.attr("fill",defaultColor)
//adding text to each toggle button group, centered
//within the toggle button rect
buttonGroups.append("text")
.attr("class","buttonText")
.attr("font-family","FontAwesome")
.attr("x",function(d,i) {
return x0 + (bWidth+bSpace)*i + bWidth/2;
})
.attr("y",y0+bHeight/2)
.attr("text-anchor","middle")
.attr("dominant-baseline","central")
.attr("fill","white")
.text(function(d) {return d;})
// update button color when clicked
function updateButtonColors(button, parent) {
parent.selectAll("rect")
.attr("fill",defaultColor)
button.select("rect")
.attr("fill",pressedColor)
}
function buttonClicked(type) {
updateButtonColors(d3.select(this), d3.select(this.parentNode))
if (type == "Stacked"){
stackBar()
}
if (type == "Grouped") {
groupBar()
}
}
function stackBar(){
var y = d3.scaleLinear()
.domain([0, m])
.rangeRound([height, 0])
.nice();
var x = d3.scaleBand()
.rangeRound([0, width])
.paddingInner(0.05)
.align(0.1)
.domain(d3.range(n));
var color = d3.scaleOrdinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
if (d3.select("g").selectAll("g.bar").empty() === true) {
d3.select("g").selectAll("g.bar")
.data(layers)
.enter()
.append("g")
.attr("class", "bar")
.each(function(d) {
d3.select(this)
.selectAll("rect")
.data(d)
.enter()
.append("rect")
.attr("x", function(p, i) { return x(i) })
.attr("y", function(p) { return y(p[1]) })
.attr("height", function(p) { return y(p[0]) - y(p[1]) })
.attr("width", x.bandwidth())
.style("fill", color(d.key))
})
} else {
d3.select("g").selectAll("g.bar")
.data(layers)
.attr("transform", function(_, i) { return "translate(0, 0)" })
.style("fill", function(_, i) { return color(i) })
.each(function(d) {
d3.select(this)
.selectAll("rect")
.data(d)
.attr("x", function(p, i) { return x(i) })
.attr("y", function(p) { return y(p[1]) })
.attr("height", function(p) { return y(p[0]) - y(p[1]) })
.attr("width", x.bandwidth())
})
}
}
function groupBar(){
var y = d3.scaleLinear()
.domain([0, m])
.range([height, 0]);
var x0 = d3.scaleBand()
.domain(d3.range(n))
.range([0, width], .2);
var x1 = d3.scaleBand()
.domain(d3.range(m))
.range([0, x0.bandwidth() - 10]);
var color = d3.scaleOrdinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var layersGroup = []
layers.forEach(function(e) {
var tmp = []
e.forEach(function(a, i) {
tmp.push(a[1])
})
layersGroup.push(tmp)
})
d3.selectAll("g.bar")
.data(layersGroup)
.attr("transform", function(_, i) { return "translate(" + x1(i) + ",0)" })
.style("fill", function(_, i) { return color(i) })
.each(function(d) {
d3.select(this)
.selectAll("rect")
.data(d)
.attr("width", x1.bandwidth())
.attr("height", function(p) { return height - y(p) })
.attr("x", function(_, i) { return x0(i) })
.attr("y", function(p) { return y(p) })
})
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment