block by armollica 2330ff9849436e6f129be633fe911017

Split bar chart

Full Screen

Clone of example from Datawrapper.

index.html

<html>
<head>
<style>

.graphic {
    font-family: sans-serif;
    color: #333;
    fill: #333;
    margin: 40px auto;
}

.hed {
    font-size: 24px;
    font-weight: bold;
    margin-bottom: 8px;
}

.dek {
    font-size: 16px;
    color: #555;
    margin-bottom: 15px;
}

.footnote {
    font-size: 12px;
    color: #999;
    margin-top: 10px;
}

.footnote a {
    color: #888;
    text-decoration: underline dashed;
}

.axis path,
.axis line {
    display: none;
}

.axis text,
.column .title {
    fill: #4c4c4c;
    font-size: 12px;
}

.bar {
    fill: steelblue;
}

.column .bar--underlying {
    fill: #f3f3f3;
}

.label {
    font-size: 12px;
    fill: #4c4c4c;
}

.label--white {
    fill: #fff;
}

</style>
</head>
<body>

<div class="graphic">
    <div class="hed">Social network usage by high schoolers</div>
    <div class="dek">Social network sites used by U.S. high school graduates, by frequency, 2014</div>
    <svg class="chart"></svg>
    <div class="footnote">Source: <a href="//www.emarketer.com/Article/How-Elusive-Generation-Z-After-All/1011466">eMarketer</a>. Chart cloned from <a href="https://www.datawrapper.de/">Datawrapper</a> example.</div>
</div>

<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<script>

var formatLabel = function(d) { return d3.format('.0f')(d * 100); };

var margin = { top: 30, right: 10, bottom: 10, left: 65 },
    width = 600 - margin.left - margin.right,
    height = 200 - margin.top - margin.bottom;

var graphic = d3.select('.graphic')
    .style('width', width + 'px');

var svg = graphic.select('svg.chart')
        .attr('width', width + margin.left + margin.right)
        .attr('height', height + margin.top + margin.bottom)
    .append('g')
        .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

var x = function(d) { return d.share; },
    xScale = d3.scaleLinear(),
    xValue = function(d) { return xScale(x(d)); };

var y = function(d) { return d.social_network; },
    yScale = d3.scaleBand().range([height, 0]).padding(0.1),
    yValue = function(d) { return yScale(y(d)); },
    yAxis = d3.axisLeft(yScale);

var column = function(d) { return d.usage; },
    columnScale = d3.scaleBand().range([0, width]).paddingInner(0.075),
    columnValue = function(d) { return columnScale(column(d)); };

var color = column,
    colorScale = d3.scaleOrdinal(),
    colorValue = function(d) { return colorScale(color(d)); };

function row(d) {
    return {
        usage: d.usage,
        social_network: d.social_network,
        share: +d.share
    };
}

d3.csv('social-network-usage.csv', row, function(error, dataFlat) {
    if (error) throw error;

    var data = d3.nest()
        .key(function(d) { return d.usage; })
        .entries(dataFlat)
        .map(function(d) { return { usage: d.key, values: d.values }; });
    
    yScale.domain(dataFlat.map(y).reverse());
    columnScale.domain(dataFlat.map(column));
    xScale.range([0, columnScale.bandwidth()]);

    // Excluding the light colors from the color scheme
    var colorRange = d3.schemeBuPu[columnScale.domain().length + 2].reverse();
    colorScale
        .domain(dataFlat.map(color))
        .range(colorRange);

    svg.append('g').attr('class', 'axis axis--y')
        .call(yAxis);

    var gColumn = svg.append('g').attr('class', 'columns')
            .selectAll('.column').data(data)
        .enter().append('g')
            .attr('class', 'column')
            .attr('transform', function(d) { return 'translate(' + columnValue(d) + ',0)'; });

    gColumn.append('text').attr('class', 'title')
        .attr('dy', '-0.34em')
        .text(column);
    
    var bars = gColumn.append('g').attr('class', 'bars');

    bars.selectAll('.bar--underlying').data(function(d) { return d.values; })
        .enter().append('rect')
            .attr('class', 'bar bar--underlying')
            .attr('x', 0)
            .attr('y', function(d) { return yScale(y(d)); })
            .attr('width', xScale.range()[1])
            .attr('height', yScale.bandwidth());

    bars.selectAll('.bar--overlying').data(function(d) { return d.values; })
        .enter().append('rect')
            .attr('class', 'bar bar--overlying')
            .attr('x', 0)
            .attr('y', function(d) { return yScale(y(d)); })
            .attr('width', function(d) { return xScale(x(d)); })
            .attr('height', yScale.bandwidth())
            .style('fill', colorValue);

    function positionLabel(d) {
        var xValue = xScale(x(d));
        var xMax = xScale.range()[1];
        if (xValue < (0.25 * xMax)) {
            d3.select(this)
                .classed('label--white', false)
                .attr('x', xValue)
                .attr('dx', 2);
        } else {
            d3.select(this)
                .classed('label--white', true)
                .attr('x', 0)
                .attr('dx', 4);
        }
        d3.select(this)
            .attr('y', yScale(y(d)) + (yScale.bandwidth() / 2))
            .attr('dy', '0.33em');
    }

    gColumn.append('g').attr('class', 'labels')
            .selectAll('.label').data(function(d) { return d.values; })
        .enter().append('text') 
            .attr('class', 'label')
            .text(function(d) { return formatLabel(x(d)); })
            .each(positionLabel);

});

</script>
</body>
</html>

social-network-usage.csv

usage,social_network,share
A few times a day,Facebook,0.47
Once a day,Facebook,0.14
A few times a week,Facebook,0.12
Occasionally,Facebook,0.14
I don't use it,Facebook,0.13
A few times a day,Instagram,0.43
Once a day,Instagram,0.08
A few times a week,Instagram,0.07
Occasionally,Instagram,0.08
I don't use it,Instagram,0.34
A few times a day,Twitter,0.28
Once a day,Twitter,0.07
A few times a week,Twitter,0.07
Occasionally,Twitter,0.13
I don't use it,Twitter,0.45
A few times a day,Google+,0.16
Once a day,Google+,0.07
A few times a week,Google+,0.08
Occasionally,Google+,0.21
I don't use it,Google+,0.48
A few times a day,Tumblr,0.11
Once a day,Tumblr,0.04
A few times a week,Tumblr,0.06
Occasionally,Tumblr,0.12
I don't use it,Tumblr,0.66
A few times a day,Pinterest,0.1
Once a day,Pinterest,0.06
A few times a week,Pinterest,0.1
Occasionally,Pinterest,0.18
I don't use it,Pinterest,0.56