NVD3 stacked bar chart option not working - d3.js

I am trying to create bar chart using nvd3 data. Grouped option is working fine but when I select Stacked it gives following error.
Uncaught TypeError: Cannot read property '1' of undefined(…)
JSON format is as below.
var test = [
{
"key":"A",
"values":
[
{"x":"2016-11-24","y":34},
{"x":"2016-11-25","y":10}
]
},
{
"key":"B",
"values":
[
{"x":"2016-11-25","y":15}
]
},
{
"key":"C",
"values":
[
{"x":"2016-11-28","y":11}
]
},
]
javascript code:
var chart;
nv.addGraph(function() {
chart = nv.models.multiBarChart()
.color(d3.scale.category10().range())
.rotateLabels(0) //Angle to rotate x-axis labels.
.transitionDuration(300)
.showControls(true) //Allow user to switch between 'Grouped' and 'Stacked' mode.
.groupSpacing(0.24) //Distance between each group of bars.
;
chart.reduceXTicks(false).staggerLabels(true).groupSpacing(0.3);
chart.x(function(d) { return d.x; });
chart.y(function(d) { return d.y; });
d3.select('#chart1 svg')
.datum(test)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
I have tried it but can't find answer. Any help ?

Answer is in the JSON data. Basically the values array should have the same length across all data series. In your example when nvd3 transforms data into stacked view it expects to have a 2nd element of the values array.
{
"key":"B",
"values":
[
{"x":"2016-11-25","y":15}
]
}

Related

How to filter datatable with value add with jquery

I'm using Datatable and I am trying to filter value on my last td column on text Red or white value..
When I clicked on arrow's filter nothing is happening (no filter action)..
Do you know why?
image exemple
$('#sst-table-all-contracts').DataTable
({
'createdRow': function (row, data) {
$(row).find("td:eq(1)").attr("id", data[6]);
if (data[7] == null )
{
$(row).find('td:last').css("background", "white");
$(row).find('td:last').text("white");
$(row).find('td:last').css("color", "white");
}
else {
$(row).find('td:last').css("background", "red");
$(row).find('td:last').text("red");
$(row).find('td:last').css("color", "red");
}
},
"aaData": contractsList,
"aoColumns": [ {}, {}]
});

How to specify an "id" for a path in Nvd3

suppose this is my data
data = [
{
"key": "Series1",
"values": [ [ 1125409600000 , 0] , [ 1228088000000 , 50]]
},
{
"key": "Series2",
"values": [ [ 1025409600000 , 10] , [ 1028088000000 , 50]]
}
]
I am using Nvd3 to draw a line chart. So based on the data given above I should have two lines.
nv.addGraph(function() {
var chart = nv.models.lineWithFocusChart();
d3.select('#chart svg')
.datum(data)
.transition().duration(500)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
I can easily do this and my code works. After drawing the chart, each line on the chart is path in the DOM. I am trying to assign each KEY value as an id of the corresponding path. For example, after drawing the graph I want to have something like this
<path id="Series1" ..... >
<path id="Series2" ..... >
Does anyone know how to do this?
As #baklazan states in his comment, the group around the path has a class of nv-series-0, nv-series-1, etc... If you can just use that and get the corresponding path like:
var series1Path = d3.select('.nv-series-0>path');
If you really want to id them:
d3.select('.nv-series-0>path')
.attr('id','Series1);

How to create C3 chart from an api link?

I tried to use this example in order to create a C3 chart. But its using all the data in the api. I am using angularjs.
my data looks like this
[
No:1
Name:'abc'
Id:3
Value:34
]
here is my code
d3.json("http://api.mydata", function(data) {
var convertedData = [];
data.forEach(function(item){
convertedData.push([item.Id, item.Value]);
});
var chart = c3.generate({
bindto : '#chartContainer',
data : {
columns : [convertedData]
},
keys: {
x: convertedData.ID,
value: convertedData.Value
}
});
});
thanks
The data field has to be populated with information about the axis as well. Here you have a functional example (sorry for the Spanish variables):
var chart = c3.generate({
bindto: "#chart-" + value.siglas,
data: {
x: 'x',
x_format: '%Y',
columns: [
['x', new Date('2011'), new Date('2012'), new Date('2013'), new Date('2014')],
['Primera matrícula', value.tasas_2011.tasas1, value.tasas_2012.tasas1, value.tasas_2013.tasas1, value.tasas_2014.tasas1],
['Segunda matrícula', value.tasas_2011.tasas2, value.tasas_2012.tasas2, value.tasas_2013.tasas2, value.tasas_2014.tasas2],
['Tercera matrícula', value.tasas_2011.tasas3, value.tasas_2012.tasas3, value.tasas_2013.tasas3, value.tasas_2014.tasas3],
['Cuarta matrícula', value.tasas_2011.tasas4, value.tasas_2012.tasas4, value.tasas_2013.tasas4, value.tasas_2014.tasas4],
['Media nacional' + averageErrorFlag, average['tasas_2011'].toFixed(2), average['tasas_2012'].toFixed(2), average['tasas_2013'].toFixed(2), average['tasas_2014'].toFixed(2)]
]
},
axis: {
x: {
type: 'timeseries',
tick: {
format: "%Y" // https://github.com/mbostock/d3/wiki/Time-Formatting#wiki-format
}
}
}
});
In data, the format of the x axis and the values (in this graphic you have four variables and the x value) are included. You can also format the x axis with the axis key.

How to create a one level nest in D3

I'm learning about nesting and have been looking at phoebe bright's explanations, where she writes:
var nested_data = d3.nest()
.key(function(d) { return d.status; })
.entries(csv_data);
gets this:
[
{
"key": "Complete",
"values": [
{
"id": "T-024",
"name": "Organisation list in directory",
"priority": "MUST",
},
{
When I try to do the same, in my console, if I can recreate it, looks like this:
Object
key: "1847"
values: Array [2]
0: Object
production: "A Mirror for Witches"
1: Object
production: "Sadlers Wells"
When I try to display the "Values" as text, all I get is [Object, object] in my html, where what I want is the production names.
How do I do this? I have tried nesting production as a key also, but this doesn't seem to work, and have also tried returning the index when returning the values, but can't get that to work either.
Any help I will really appreciate, thanks.
Here is my code
data.csv
year,production,company
1847,A Mirror for Witches
1847,Sadlers Wells
d3.csv("data.csv", function(csv_data){
var nested_data = d3.nest()
.key(function(d) { return d.year; })
.entries(csv_data)
console.log(nested_data);
var selection =
d3.select("body").selectAll("div")
.data(nested_data)
.enter()
selection.append("div")
.classed('classed', true)
.text(function(d){
return d.key;
});
d3.selectAll(".classed").append("div")
.text(function(d){
return d.values;
});
});
Here's a working plunk: http://plnkr.co/edit/0QuH8P9ujMdl0vWuQkrQ?p=preview
I added a few more lines of data to show it working properly.
The thing to do here is to add a second selection (I've called it production_selection) and bind data based off the first selection (year_selection): You use nested selections to show nested data.
First selection (show a div for each year, or key, in your nested data):
var year_selection = d3.select("#chart").selectAll("div")
.data(nested_data)
.enter().append("div")
...
Second selection (show all productions, or values, under that key):
var production_selection = year_selection.selectAll(".classed")
.data(function(d) { return d.values; })
.enter().append("div")
...
For the second selection, you just define the accessor function (d.values)

Flatten nested array created with d3.nest() to create stacked bar

I have data returned from a REST API in the following form.
[{
"created": "2014-06-01T11:21:47Z",
"is_good": false,
"amount": 10
},{
"created": "2014-06-01T12:01:00Z",
"is_good": false,
"amount": 12
},{
"created": "2014-06-02T10:00:00Z",
"is_good": true,
"amount": 8
},{
"created": "2014-06-02T08:00:00Z",
"is_good": false,
"amount": 3
},
...
]
In order to make a stacked bar chart, I thought the solution would be to use d3.nest() to rollup the amounts, first by date, then by is_good (the stacking category).
nestedData = d3.nest()
.key(function(d) { return d3.time.day(new Date(d.created)); })
.key(function(d) { return d.is_good; })
.rollup(function(leaves) { return {amount: d3.sum(leaves, function(d) { return d.amount; })}; })
.entries(jsonData);
That would probably be fine when drawing the chart following Mike Bostock's example here, but wouldn't work in a d3.layout.stack() call, because it requires the .values() to be the group iterable from which x and y is then calculated. That lead me to try the keys the other way around, but then drawing the chart itself becomes tricky.
So after all of that, I'm now wondering if there's a neat d3 way of flattening the nested values into something that resembles the datasets in almost all stacked bar chart examples.
Alternatively, perhaps I'm just not seeing how best to use the double nested data to create a stacked bar chart based on the examples.
Any help would be much appreciated.
I eventually decided to tackle this without using d3.layout.stack at all, and attempted to convert the double nested array into something resembling the example given. This is the code that will take that complex array and squash it down into something more manageable when drawing the chart.
data.forEach(function(d) {
var y0 = 0;
d.amounts = color.domain().map(function(is_good) {
return {is_good: is_good, y0: y0, y1: y0 += +d.values.filter(function(d) {
return d.key == is_good;
})[0].values.amount};
});
d.total = d.amounts[d.amounts.length - 1].y1;
});
Here's a working example.
I'm sure this isn't perfect, so if anyone has a better way of achieving the same result, I'd be interested to see it!

Resources