SquirFly
SquirFly

Reputation: 63

Multiple C3.js charts automatically hidden, except the last one

I am trying to generate multiple c3 charts with the following code :

var datas=[[
    ["name", "position", "y", "bigRect", "myBars"],
    ["One 22", 2, 2, 2, 2],
    ["One 33", 3, 3, 2, 2],
    ["One 44", 4, 4, 2, 2]
],[
    ["name", "position", "y", "bigRect", "myBars"],
    ["Two 55", 5, 5, 2, 2],
    ["Two 66", 6, 6, 2, 2],
    ["Two 77", 7, 7, 2, 2]
],[
    ["name", "position", "y", "bigRect", "myBars"],
    ["Three 88", 8, 8, 2, 2],
    ["Three 99", 9, 9, 2, 2],
    ["Three 00", 0, 0, 2, 2]
]];

var iData = 0;
var charts = [];

for(iData in datas){

    var d = datas[iData];
    document.querySelector(".container").innerHTML += "<div id='chart"+iData+"'></div>";
    var chartSelector = "#chart"+iData;

    charts[iData] = c3.generate({
        bindto: d3.select(chartSelector),
        data: {
            rows: d,
            type: "scatter",
            types: {
                bigRect: "area",
                myBars: "bar"
            },
            x: "position",
            y: "y"
        },
        zoom: {
            enabled: true
        }
    });

}

All the charts look empty except the last one that works perfectly. You can see what it looks like on this JSbin link.

On the hidden charts, all the SVGs are generated, but

Do you know why c3 is disabling the first charts and how to enable them ?

My apologies for my poor English and thank you very much for your time.

Upvotes: 1

Views: 609

Answers (2)

mgraham
mgraham

Reputation: 6207

You've got it working now, but I can also get it working by replacing one line like so:

   d3.select(".container").append("div").attr("id", "chart"+iData);
    //document.querySelector(".container").innerHTML += "<div id='chart"+iData+"'></div>";

It appears adding stuff to and then replacing .innerHtml has side effects for the existing contents, in your case the first charts you build

Is it possible to append to innerHTML without destroying descendants' event listeners?

This includes wiping out event handlers and 'unofficial' (for want of a better term) attributes like the __data__ field d3 populates and uses (it's undefined for the first 2 sets of bars as this code will reveal)

  for(iData in datas){
    console.log (d3.select("#chart"+iData+" .c3-bars").node().__data__);
  }

Upvotes: 1

SquirFly
SquirFly

Reputation: 63

I finally solved my problem by creating all the #chartX containers in another loop before that calling c3.

I assume it has something to do with the non-procedural execution order of JS but I'm still looking for a precise explanation of the phenomenon. Here is the link to the corrected JSbin.

Upvotes: 1

Related Questions