An example using my d3 icon array plugin illustrating when you may want to to use widthFirst(true)
vs widthFirst(false)
xxxxxxxxxx
<html>
<head>
<title>Simple icon array example</title>
<script src="//d3js.org/d3.v4.0.0-alpha.18.min.js" charset="utf-8"></script>
<script type="text/javascript" src="d3-iconarray.js"></script>
<style type="text/css">
*{
font-family: sans-serif;
}
p.bar-label{
margin:0px;
}
.Conservative{
fill:#00F;
}
.Labour{
fill:#F00;
}
.Liberal{
fill:#EA0;
}
.SNP{
fill:#DD0;
}
.DUP, .Other{
fill:#AAA;
}
p{
max-width: 600px;
}
</style>
</head>
<body>
<p>By default the icon array is built width first. Whilst this has some nice properties like using the full width available, leading to a percieved compactness, it doesn't allow easy comparison between arrays. In this case the Conservative and Labour arrays look about the same ... </p>
<div id="width-first">
</div>
<p>A height first construction allows a better approximation of a bar chart (comparisons of length are much easier than comparisons of area so we want to emphasise those differences) and the difference between the front runners becomes more apparent.</p>
<div id="height-first">
</div>
<p>Note the smaller values become a little tricker to compare but that the ease of countability (is that a word?) which a icon array provides can help here providing more legible information than an equivalent bar chart would at a similar scale.
</body>
<script type="text/javascript">
var results = [
{party:'Conservative', seats:331 },
{party:'Labour', seats:232},
{party:'SNP', seats:56},
{party:'Liberal Democats', seats:8},
{party:'DUP', seats:8},
{party:'Other', seats:15}
];
var gridWidth = 80;
var gridHeight = 5;
var layout = d3_iconarray.layout()
.width(gridWidth)
.height(gridHeight);
var width = 600;
var height = 40;
var radius = 2.5;
var margin = { top:radius*2, left:radius*2, bottom:radius*2, right:radius*2 }
var scale = d3.scaleLinear()
.range([0, (width-(margin.left + margin.right))])
.domain([0, gridWidth]);
console.log(scale.range())
d3.select('#width-first')
.selectAll('div.result')
.data(results)
.enter()
.append('div').attr('class','result')
.call(arrayBars, true);
d3.select('#height-first')
.selectAll('div.result')
.data(results)
.enter()
.append('div').attr('class','result')
.call(arrayBars, false);
function arrayBars(parent, widthFirst){
layout.widthFirst(widthFirst);
parent.append('p')
.attr('class','bar-label')
.html(function(d){
return d.party;
});
parent.append('svg')
.attr('width', width).attr('height', height)
.append('g')
.attr('transform','translate('+margin.left+','+margin.top+')')
.attr('class',function(d){return d.party})
.selectAll('circle')
.data(function(d){ return layout( d3.range(0, d.seats, 1) ); })
.enter()
.append('circle')
.attr('cx',function(d){ return scale(d.position.x); })
.attr('cy',function(d){ return scale(d.position.y); })
.attr('r', radius)
}
</script>
</html>
https://d3js.org/d3.v4.0.0-alpha.18.min.js