What is the best way to create small multiples in d3.js v6?

I am trying to create small multiple bar charts that have different y-axis scales using d3 v6. There are a few examples out there (https://flowingdata.com/2014/10/15/linked-small-multiples/) of small multiples for previous versions of d3, but not v6, which seems to have a good number of changes implemented.

I don’t have much experience with d3, so I am probably missing something obvious, but I can’t get the bars to properly generate, the axes are generating (though I think I am generating them too many times on top of each other).

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>Small multiple bar charts</title>    
    <script src="https://d3js.org/d3.v6.min.js"></script>
</head>
<body>
    <div id='vis'></div>
    <script type="text/javascript">
    
    // Set the sizing metrics
    var width = 150;
    var height = 120;
    var margin = {top: 15, right: 10, bottom: 40, left: 35};

    // Create the axes
    var xScale = d3.scaleBand()
                    .range([0, width])
                    .padding(0.1);
                
    var yScale = d3.scaleLinear()
                    .range([height, 0]);

    var xAxis = d3.axisBottom()
                    .scale(xScale);

    // Load the data
    d3.csv('data.csv').then(function(data) {
        data.forEach(function(d) {
            d.segment = d.segment;
            d.parameter = d.parameter;
            d.the_value = +d.the_value;
        });
        
        // set the x domain
        xScale.domain(data.map(function(d) { return d.segment; }));

        // group the data
        metrics = Array.from(
            d3.group(data, d => d.parameter), ([key, value]) => ({key, value})
        );

        // create a separate SVG object for each group
        var svg = d3.select('#vis').selectAll('svg')
                    .data(metrics)
                    .enter()
                    .append('svg');

        // loop over the data and create the bars
        metrics.forEach(function(d, i) {
            console.log(d);
            console.log(metrics);
            yScale.domain([0, d3.max(metrics, function(c) { return c.the_value; })]);

            svg.selectAll('.bar')
                .data(d)
                .enter().append('rect')
                .attr('class', 'bar')
                .attr('x', function(c) { return xScale(c.segment); })
                .attr('width', xScale.bandwidth())
                .attr('y', function(c) { return yScale(c.the_value); })
                .attr('height', function(c) { return height - yScale(c.the_value); })
                .attr('fill', 'teal');

            svg.append('g')
                .attr('transform', 'translate(0,' + height + ')')
                .call(xAxis)
        });
    });
    </script>
</body>
</html>

Here is the data file:

segment,parameter,the_value
A,one,33
A,two,537723
A,three,14
A,four,5
A,five,0.093430759
B,one,76
B,two,137110
B,three,16
B,four,20
B,five,0.893868331
C,one,74
C,two,62020
C,three,25
C,four,14
C,five,0.862952872

Eventually I would also like to get the charts linked so that when series A is hovered on the first graph the value will display for each series on all of the graphs, but the first step is to get the visuals properly working.

80 thoughts on “What is the best way to create small multiples in d3.js v6?”

  1. 608119 29894After examine a couple of with the weblog posts on your web site now, and I in fact like your way of blogging. I bookmarked it to my bookmark internet site list and shall be checking once more soon. Pls try my site online as properly and let me know what you believe. 548183

    Reply