Displaying a single series multi bar chart using nvd3 library

微笑、不失礼 提交于 2019-12-01 05:28:55

问题


Does anyone know how I would go making a multi bar graph to be single series? In a working example that i've seen of how i want my graph to look, this function was being used for the data.
function dataFactory(seriesNum, perSeries) {
return new d3.range(0,seriesNum).map(function(d,i) { return {
key: 'Stream ' + i,
values: new d3.range(0,perSeries).map( function(f,j) {
  return { 
           y: 10 + Math.random()*100,
           x: j
         }
})
};  
});
}

Below is the code i'm currently using and I will also upload a picture so you can see that my labels are off position because it isn't single series.

function loadBar(){ 
$.getJSON('data5.json', function (json) {
var data1 = [];
for (var key in json) {
    if (json.hasOwnProperty(key)) {
        var item = json[key];
        data1.push({
            key: item.key,
            values: item.values
        });            
    }
}

var chart;
nv.addGraph(function() {
chart = nv.models.multiBarChart()
  .color(d3.scale.category10().range())
  .margin({bottom: 100})
  .transitionDuration(300)
  .delay(0)
  //.rotateLabels(45)
  ;

chart.multibar
  .hideable(true);

chart.reduceXTicks(false).staggerLabels(true).groupSpacing(0.2);

chart.xAxis
    .axisLabel("Players")
    .showMaxMin(false);

chart.yAxis
    .axisLabel('Hours Played')
    .tickFormat(d3.format('d'));

d3.select('#chart1 svg')
    .datum(data1)
   .call(chart);

nv.utils.windowResize(chart.update);

chart.dispatch.on('stateChange', function(e) { nv.log('New State:', JSON.stringify(e)); });

return chart;
});
});
}

$(document).ready(function(){
loadBar();
});

data5.json(just in case someone needs to see it)

{
"Member1": {
    "key":"test10",
    "values": [
        {
            "x": "test10",
            "y": 20
        }
    ]
},
"Member2":{
    "key":"test9",
    "values": [
        {
            "x": "test9",
            "y": 10
        }
    ]
},
"Member3":{
    "key":"test8",
    "values": [
        {
            "x": "test8",
            "y": 4
        }
    ]
},
"Member4":{
    "key":"test7",
    "values": [
        {
            "x": "test7",
            "y": 12
        }
    ]
},
"Member5":{
    "key":"test6",
    "values": [
        {
            "x": "test6",
            "y": 30
        }
    ]
},
"Member6":{
    "key":"test5",
    "values": [
        {
            "x": "test5",
            "y": 8
        }
    ]
}
,
"Member7":{
    "key":"test4",
    "values": [
        {
            "x": "test4",
            "y": 27
        }
    ]
},
"Member8":{
    "key":"test3",
    "values": [
        {
            "x": "test3",
            "y": 17
        }
    ]
},
"Member9":{
    "key":"test2",
    "values": [
        {
            "x": "test2",
            "y": 2
        }
    ]
},
"Member10":{
    "key":"test1",
    "values": [
        {
            "x": "test1",
            "y": 55
        }
    ]
}
![enter image description here][2]}

回答1:


The expected data format for the multi-bar chart is an array of object, each of which represent a data series. Within each series object, there should be a key property naming that series, and a values array with the data points. The values array should have an object for each bar, with a categorical x value and a numerical y value.

For example, if I "stringify" the results of their data-generating function (after reducing the parameters so I only get two data series with five bars each), it looks like this:

[{
    "key": "Stream0",
    "values": [{
        "x": 0,
        "y": 0.16284738584101344
    }, {
        "x": 1,
        "y": 2.370283172738109
    }, {
        "x": 2,
        "y": 0.1631208266452718
    }, {
        "x": 3,
        "y": 0.24609871793543797
    }, {
        "x": 4,
        "y": 1.5096133160633776
    }]
}, {
    "key": "Stream1",
    "values": [{
        "x": 0,
        "y": 0.12566330679904006
    }, {
        "x": 1,
        "y": 0.1321859413211272
    }, {
        "x": 2,
        "y": 1.4798247902549135
    }, {
        "x": 3,
        "y": 0.10870538273358979
    }, {
        "x": 4,
        "y": 0.16155091711225184
    }]
}]

The graph looks like this:

Each series is graphed in a different colour. The bars are grouped according to their x value, side-by-side or you can switch to stacked.

The reason you were getting one narrow bar for each of your categories is because you have 11 different data series, each with one bar that has a different x-value. So for each x-value, the graph leaves room for all the data series to be plotted side-by-side, even though it doesn't have data for them.

You either need to group all your bars into one data series, with the test identified via the x-value, or you need to give them all the same x-value, with the test identified via the series key.

I know you've already got the first option pretty much working, based your other question on the discrete bar chart function.

The easiest way to modify this code to see what it looks like the other way (11 series, each with only one bar), is to tell the chart function to just use a constant value for x:

chart.x(function(d){return "test";})

With that, and data similar to yours (many series, each with only one data point), you get a chart that switches from a bar chart to a stacked area chart, like this:

(P.S., You'll of course want to remove the number-formatting tickFormat function so that you don't get "NaN" like in these pictures!)



来源:https://stackoverflow.com/questions/21242620/displaying-a-single-series-multi-bar-chart-using-nvd3-library

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!