Skip to content

Instantly share code, notes, and snippets.

@RoxIv
Last active July 30, 2018 21:02
Show Gist options
  • Save RoxIv/849c15c47caf93a8391fda0ae6f9d51c to your computer and use it in GitHub Desktop.
Save RoxIv/849c15c47caf93a8391fda0ae6f9d51c to your computer and use it in GitHub Desktop.
Women's rights score by regions
license: mit

This is a fork of Ziggy Jonsson's Bar Stack (flex lao) to add to this conversation.

The purpose of this gist was to recommend using whitespace to represent the axes of visualizations, as they signify the zero point in the opposite dimensions encoding. Additionally, this enhances the users comprehension because positive and negative areas are able to be assessed independently.

When doing visual encoding, we tend to ignore whitespace and let 0's handle themselves. To learn about other techniques around this concept, refer to: The Design of Nothing: Null, Zero, Blank by Andy Kirk (@visualisingdata).

Proposed Improvements:

  • aesthetics (very little changes from original example were made).
  • transitions that serve a purpose and flow with the expectation of the reader.

forked from milroc's block: axes as whitespace

We can make this file beautiful and searchable if this error is corrected: It looks like row 2 should actually have 3 columns, instead of 11. in line 1.
x,y,z
1,-0.756097561,blabla,-0.731707317,1.634146341,2.414634146,1.487804878,1.097560976,19.41463415,14.19512195,4.390243902
2,1.473684211,0.868421053,-1.368421053,1.157894737,1.631578947,1.368421053,-0.157894737,19.13157895,14.15789474,4.710526316
3,6.135135135,1.594594595,0.864864865,0.405405405,3,3,2.567567568,24.54054054,6.972972973,6.486486486
4,-0.846153846,3.307692308,-0.769230769,1.461538462,3,2.846153846,1.153846154,22.92307692,12.76923077,2.307692308
5,3,3.5,1.5,0,3,3,0.5,22.5,8,7.5
6,-2.4,5.8,1.2,1.6,3,2.6,3.2,26.5,11.5,0
<!DOCTYPE html>
<html>
<head>
<script src="http://mbostock.github.com/d3/d3.v2.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3-legend/1.1.0/d3-legend.js"></script>
<title></title>
<style>
.axis text {
font: 10px sans-serif;
}
.axis path {
fill: none;
stroke: #FFF;
stroke-width:4;
shape-rendering: crispEdges;
}
.axis line {
display: none;
}
.color-legend text {
font-family: 'Open Sans', sans-serif;
font-size: 19pt;
}
</style>
</head>
<body>
<script type="text/javascript" >
function barStack(d) {
var l = d[0].length
while (l--) {
var posBase = 0, negBase = 0;
d.forEach(function(d) {
d=d[l]
d.size = Math.abs(d.y)
if (d.y<0) {
d.y0 = negBase
negBase-=d.size
} else
{
d.y0 = posBase = posBase + d.size
}
})
}
d.extent= d3.extent(d3.merge(d3.merge(d.map(function(e) { return e.map(function(f) { return [f.y0,f.y0-f.size]})}))))
return d
var legend = d.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("text-anchor", "end")
.selectAll("g")
.data(keys.slice().reverse())
.enter().append("g")
.attr("transform", function(d) { return "translate(0," + d.z + ")"; });
legend.append("rect")
.attr("x", width - 19)
.attr("width", 19)
.attr("height", 19)
.attr("fill", z);
legend.append("text")
.attr("x", width - 24)
.attr("y", 9.5)
.attr("dy", "0.505856em")
.text(function(d) { return d; });
}
/* Here is an example */
var data = [[{x:"Africa",y:-0.756097561,z:"Abortion"},
{x:"Asia",y:1.473684211,z:"Abortion"},
{x:"Europe",y:6.135135135,z:"Abortion"},
{x:"North America",y:-0.846153846,z:"Abortion"},
{x:"Oceania",y:3,z:"Abortion"},
{x:"South America",y:-2.4,z:"Abortion"}],
[{x:"Africa",y:0.073170732,z:"Domestic violence"},
{x:"Asia",y:0.868421053,z:"Domestic violence"},
{x:"Europe",y:1.594594595,z:"Domestic violence"},
{x:"North America",y:3.307692308,z:"Domestic violence"},
{x:"Oceania",y:3.5000,z:"Domestic violence"},
{x:"South America",y:5.8,z:"Domestic violence"}],
[{x:"Africa",y:-0.731707317,z:"Harassment"},
{x:"Asia",y:-1.368421053,z:"Harassment"},
{x:"Europe",y:0.864864865,z:"Harassment"},
{x:"North America",y:-0.769230769,z:"Harassment"},
{x:"Oceania",y:1.5,z:"Harassment"},
{x:"South America",y:1.2,z:"Harassment"}],
[{x:"Africa",y:1.634146341,z:"Constitution"},
{x:"Asia",y:1.157894737,z:"Constitution"},
{x:"Europe",y:0.405405405,z:"Constitution"},
{x:"North America",y:1.461538462,z:"Constitution"},
{x:"Oceania",y:0,z:"Constitution"},
{x:"South America",y:1.6,z:"Constitution"}],
[{x:"Africa",y:2.41463414634146,z:"Other"},
{x:"Asia",y:1.3157894736842,z:"Other"},
{x:"Europe",y:3,z:"Other"},
{x:"North America",y:3,z:"Other"},
{x:"Oceania",y:3,z:"Other"},
{x:"South America",y:3,z:"Other"}],
[{x:"Africa",y:1.48780487804878,z:"Property"},
{x:"Asia",y:1.36842105263158,z:"Property"},
{x:"Europe",y:3,z:"Property"},
{x:"North America",y:2.84615384615385,z:"Property"},
{x:"Oceania",y:3,z:"Property"},
{x:"South America",y:2.6,z:"Property"}],
[{x:"Africa",y:1.09756097560976,z:"Work"},
{x:"Asia",y:-0.157894736842105,z:"Work"},
{x:"Europe",y:2.56756756756757,z:"Work"},
{x:"North America",y:1.15384615384615,z:"Work"},
{x:"Oceania",y:0.5,z:"Work"},
{x:"South America",y:3.2,z:"Work"}]
]
//var data = d3.csv("data.csv");
var h=500
,w=500
,margin=10
,color = d3.scale.category10()
,x = d3.scale.ordinal()
.domain(d3.range(1))
.rangeRoundBands([margin,w-margin], .1)
,y = d3.scale.linear()
.range([h-margin,0+margin])
,xAxis = d3.svg.axis().scale(x).orient("bottom")
,yAxis = d3.svg.axis().scale(y).orient("left")
barStack(data)
y.domain(data.extent)
svg = d3.select("body")
.append("svg")
.attr("height",h)
.attr("width",w)
svg.selectAll(".series").data(data)
.enter().append("g").classed("series",true).style("fill", function(d,i) { return color(i)})
.selectAll("rect").data(Object)
.enter().append("rect")
.attr("x",function(d,i) { return x(d.x)})
.attr("y",function(d) { return y(d.y0)})
svg.append("g").attr("class","axis x")
svg.append("g").attr("class","axis y")
/*Legend*/
var foregroundBarLayer = svg.append("g");
var colorLegendG = svg.append("g")
.attr("class", "color-legend")
.attr("transform", "translate(596, 0)");
var nested = d3.nest()
.key(function (d){ return d.z; })
.entries(data)
var stack = d3.layout.stack()
.y(function (d){ return d.y; })
.values(function (d){ return d.values; });
var colorScale = d3.scale.category10();
var layers = stack(nested.reverse()).reverse();
colorScale.domain(layers.map(function (layer){
return layer.key;
}));
var colorLegend = d3.legend.color()
.scale(colorScale)
.shapePadding(6.24)
.shapeWidth(20)
.shapeHeight(20)
.labelOffset(5);
colorLegendG.call(colorLegend);
colorLegendG.selectAll("text").attr("z", 4);
function listenForHover(selection, data){
selection
.on("mouseover", function (d){
hoveredColorValue = d;
render(data);
})
.on("mouseout", function (d){
hoveredColorValue = null;
render(data);
})
.style("cursor", "pointer");
}
listenForHover(colorLegendG.selectAll("rect"), data);
listenForHover(colorLegendG.selectAll("text"), data);
/*Legend.2*/
function render(data){
var nested = d3.nest()
.key(function (d){ return d.z; })
.entries(data);
var stack = d3.layout.stack()
.y(function (d){ return d.y; })
.values(function (d){ return d.values; });
var layers = stack(nested.reverse()).reverse();
colorScale.domain(layers.map(function (layer){
return layer.key;
}));
colorLegendG.call(colorLegend);
// Move the text down a bit.
colorLegendG.selectAll("text").attr("y", 4);
listenForHover(colorLegendG.selectAll("rect"), data);
listenForHover(colorLegendG.selectAll("text"), data);
}
d3.csv("data.csv", render);
/*Legend.2.E*/
var layout = 0,dur=0
redraw()
dur = 1500
function redraw() {
if (layout=!layout) {
/* Readjust the range to witdh and height */
x.rangeRoundBands([margin,w-margin], .1)
y.range([h-margin,0+margin])
/* Reposition and redraw axis */
svg.select(".x.axis")
.transition().duration(dur)
.attr("transform","translate (0 "+y(0)+")")
.call(xAxis.orient("bottom"))
svg.select(".y.axis")
.transition().duration(dur)
.attr("transform","translate ("+x(0)+" 0)")
.call(yAxis.orient("left"))
/* Reposition the elements */
svg.selectAll(".series rect")
.transition().duration(dur)
.attr("x",function(d,i) { return x(d.x)})
.attr("y",function(d) { return y(d.y0)})
.attr("height",function(d) { return y(0)-y(d.size)})
.attr("width",x.rangeBand())
} else {
/* Readjust the range to witdh and height */
x.rangeRoundBands([h-margin,0+margin], .1)
y.range([margin,w-margin])
/* Reposition and redraw axis */
svg.select(".x.axis")
.transition().duration(dur)
.attr("transform","translate ("+y(0)+" 0)")
.call(xAxis.orient("left"))
svg.select(".y.axis")
.transition().duration(dur)
.attr("transform","translate (0 "+x(0)+")")
.call(yAxis.orient("bottom"))
/* Reposition the elements */
svg.selectAll(".series rect")
.transition().duration(dur)
.attr("y",function(d,i) { return x(d.x)})
.attr("x",function(d) { return y(d.y0-d.size)})
.attr("width",function(d) { return y(d.size)-y(0)})
.attr("height",x.rangeBand())
}
d3.select("body").append("button")
.attr("type","button")
.text("Change Layout")
.style("position","absolute")
.style("left","5px")
.style("top","5px")
.on("click",redraw)
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment