The goal of this chart is to create two overlaying bar charts, with tooltip, and proper labeling of the scales. The chart is constructed from CSV data.
The data consists of the names of the countries participating in the UEFA European Championship, count of participations and wins from 1960 to 2016.
More details to come
xxxxxxxxxx
<meta charset="utf-8">
<head>
<title>Overlaying Bar Charts</title>
<style> /* CSS styling */
body {
font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
font-size: 14px;
}
.bar1 {
border: 1px solid #0b3536;
border-radius: 6px;
fill: #0098d8;
}
.bar2 {
fill: #f54123;
}
.axisY text, .axisX text, .headerText text, .footerText text {
fill: #0b3536;
}
#viz svg {
background-color: #f5faf8;
}
div.tooltip{
position: absolute;
border: 1px solid #0b3536;
border-radius: 6px;
text-align: center;
padding: 0 5px;
background: white;
}
</style>
</head>
<body>
<div class="container">
<div id="viz"></div>
</div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
// Setting the margin and dimensions of the work area
var margin = {top: 60, right: 20, bottom: 110, left: 30},
width = 760- margin.left - margin.right,
height = 380 - margin.top - margin.bottom;
// Creating the scale variables and setting the ranges
var xScale = d3.scaleBand().rangeRound([0, width]).padding(0.1),
yScale = d3.scaleLinear().rangeRound([height, 0]);
// Appending the svg object to the div on the page
var svg = d3.select('#viz').append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom);
// Appending the 'group' element to the svg
// Moving the 'group' element to the top left margin
var g = svg.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// Appending the tooltip to the div on the page
var tooltip = d3.select('#viz').append('div')
.attr('class', 'tooltip').style('opacity', 0);
// Adding header to the chart
g.attr('class', 'headerText')
.append('text')
.attr('transform', 'translate(' + (width / 2) + ',' + (-margin.top / 2) + ')')
.attr('text-anchor', 'middle')
.attr('font-weight', 600)
.text('Participants and Winners of the UEFA European Championship')
// Adding footer to the chart
g.append('g')
.attr('class', 'footerText')
.attr('transform', 'translate(' + width / 2 + ',' + (height + margin.bottom - 10) + ')')
.attr('text-anchor', 'middle')
.style('font-size', '0.5rem')
.attr('font-weight', 600)
.append('text')
.attr("dy", "0em")
.text('1 - Five appearances as Yugoslavia |' +
' 2 - Three appearances as Czechoslovakia |' +
' 3 - Five appearances as West Germany | ' +
' 4 - Five appearances as the USSR and one as the CIS');
var legend = g.append("g")
.attr("font-family", "sans-serif")
.attr("font-size", 10)
.attr("text-anchor", "end");
legend.append("rect")
.attr("x", width - margin.right / 2)
.attr('y', -4)
.attr("width", 8)
.attr("height", 8)
.style('fill', '#0098d8');
legend.append("rect")
.attr("x", width - margin.right / 2)
.attr('y', 12)
.attr("width", 8)
.attr("height", 8)
.style('fill', '#f54123');
legend.append('text')
.attr("x", width - 12)
.attr("dy", "0.32em")
.text("Participated");
legend.append('text')
.attr("x", width - 12)
.attr('y', 16)
.attr("dy", "0.32em")
.text("Won");
// Reading from csv file, and converting the needed data
d3.csv('uefa_part_win.csv', function(d) {
d.part = +d.part;
d.win = +d.win;
return d;
}, function(error, data) {
if (error) throw error;
xScale.domain(data.map(function(d) { return d.country; }));
yScale.domain([0, d3.max(data, function(d) { return d.part; })]);
// Appending X axis and formatting the text
g.append('g')
.attr('class', 'axisX')
.attr('transform', 'translate(0,' + height + ')')
.call(d3.axisBottom(xScale))
.selectAll('text')
.attr('text-anchor', 'end')
.attr('dx', '-.8em')
.attr('dy', '.15em')
.style('font-size', '0.6rem')
.attr('font-weight', 600)
.attr('text-anchor', 'end')
.attr('transform', 'rotate(-60)');
// Appending Y axis and adding
g.append('g')
.attr('class', 'axisY')
.call(d3.axisLeft(yScale).ticks(10))
.append('text')
.attr('x', 0)
.attr('y', yScale(yScale.ticks().pop()) + 0.5)
.attr('dy', '1em')
.attr('fill', '#000')
.attr('font-weight', 'bold')
.attr('text-anchor', 'end')
.attr('transform', 'rotate(-90)')
.text('Count');
var chart = g.selectAll('bars')
.data(data)
.enter().append('g');
chart.append('rect')
.attr('class', 'bar1')
.attr('x', function(d) { return xScale(d.country); })
.attr('y', height)
.attr('width', xScale.bandwidth())
.attr('height', 0)
.transition()
.attr('height', function(d) { return height - yScale(d.part); })
.attr('y', function(d) { return yScale(d.part); })
.delay(function(d, i){
return i * 8;
})
.duration(1000);
chart.append('rect')
.attr('class', 'bar2')
.attr('x', function(d) { return xScale(d.country); })
.attr('y', height)
.attr('width', xScale.bandwidth())
.attr('height', 0)
.transition()
.attr('height', function(d) { return height - yScale(d.win); })
.attr('y', function(d) { return yScale(d.win); })
.delay(function(d, i){
return i * 8;
})
.duration(1000);
chart.on('mouseover', function(d){
d3.select(this).attr('opacity', 0.7);
tooltip.transition().duration(100).style('opacity', 0.95);
tooltip.html(
'<div style="font-size: 0.6rem; color: #0b3536; font-weight: bold">' +
d.country + '<br/>part: ' + d.part + ' | won: ' + d.win + '</div>')
.style('left', (d3.event.pageX - 35) + 'px')
.style('top', (d3.event.pageY - 30) + 'px');
})
.on('mouseout', function(d){
d3.select(this)
.attr('opacity', 1);
tooltip.transition().style('opacity', 0); });
});
</script>
</body>
https://d3js.org/d3.v4.min.js