sean.boyer
sean.boyer

Reputation: 1237

NVD3 MultiBarChart Stacked Display with Non-Normalized Data

I have multiple datasets that I am passing to an NVD3 multiBarChart. The problem is, the chart doesn't seem to display correctly in stacked mode if some properties are missing from one set vs the other.

Let's say I have a list of User's weekly drink preferences:

[
    {
        userName: "Todd",
        values: [
            { 
                x: "Coffee",
                y: 32
            },
            {
                x: "Tea",
                y: 13
            },
            {
                x: "Beer",
                y: 2
            }
        ]
    },
    {
        userName: "Allison",
        values: [
            { 
                x: "Coffee",
                y: 4
            },
            {
                x: "Milk",
                y: 2
            },
            {
                x: "Sprite",
                y: 14
            }
        ]
    },
    {
        userName: "Vern",
        values: [
            { 
                x: "Water",
                y: 112
            },
            {
                x: "Gatorade",
                y: 13
            },
            {
                x: "Beer",
                y: 0
            }
        ]
    }
]

Since not all "users" have the same drinks, the graph won't display correctly in stack mode.

If I normalize the data so that each user will have ALL the same drinks, with the previously missing values getting a 0 value, the stacked mode will display correctly.

I'm looking for a way to programmatically normalize the data so that all "users" arrays will have the same object count.

This is similar to the post here: in nvd3 multibarchart, some stacks lose their colors or otherwise become invisible, however, I am looking for a way to programmatically normalize the data.

Upvotes: 0

Views: 595

Answers (1)

Lars Kotthoff
Lars Kotthoff

Reputation: 109232

This is not the most efficient way to do it, but doesn't use any libraries and should work fine for not too large amounts of data:

var drinks = [];
data.forEach(function(d) {
  d.values.forEach(function(e) {
    if(drinks.indexOf(e.x) == -1) drinks.push(e.x);;
  });
});

data.forEach(function(d) {
  drinks.forEach(function(drink) {
    var have = false;
    d.values.forEach(function(e) {
        if(e.x == drink) have = true;
    });
    if(!have) d.values.push({x: drink, y: 0});
  });
});

Complete demo here.

Upvotes: 1

Related Questions