C3.js chart.load not loading for x/y axis graph - javascript

I have set up an xy graph and I'm trying to load in a new dataset but for some reason the data never generates inside the graph:
<div id="graph"></div>
<script>
var chart = c3.generate({
bindto: '#graph',
data: {
xs: {
'data1': 'x1',
'data2': 'x2',
},
columns: [
['x1', 10, 30, 45, 50, 70, 100],
['x2', 30, 50, 75, 100, 120],
['data1', 30, 200, 100, 400, 150, 250],
['data2', 20, 180, 240, 100, 190]
]
}
});
setTimeout(function () {
chart.load({
bindto: '#graph',
data: {
xs: {
'data3': 'x3',
},
columns: [
['x3', 20, 40, 55, 60, 80, 110],
['data3', 30, 150, 260, 120, 90]
]
}
});
}, 2000);
</script>
Anyone have any idea why this might be? I know that chart.unload works fine and I've tried playing with adding and removing the bindto: 'graph', but nothing has worked

According to the docs, the load function does not need the data parameter, so it should look like this:
chart.load({
bindto: '#graph',
xs: {
'data3': 'x3',
},
columns: [
['x3', 20, 40, 55, 60, 80, 110],
['data3', 30, 150, 260, 120, 90]
]
});
Demo snippet:
var chart = c3.generate({
bindto: '#graph',
data: {
xs: {
'data1': 'x1',
'data2': 'x2',
},
columns: [
['x1', 10, 30, 45, 50, 70, 100],
['x2', 30, 50, 75, 100, 120],
['data1', 30, 200, 100, 400, 150, 250],
['data2', 20, 180, 240, 100, 190]
]
}
});
setTimeout(function () {
chart.load({
bindto: '#graph',
xs: {
'data3': 'x3',
},
columns: [
['x3', 20, 40, 55, 60, 80, 110],
['data3', 30, 150, 260, 120, 90]
]
});
}, 2000);
<link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.8/c3.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.8/c3.js"></script>
<div id="graph"></div>

Related

C3.js Multiple Y in a multiple line chart (no static column name)

Normally in C3.js to create multiple Y axes you would doe something like this:
var chart = c3.generate({
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
axes: {
data1: 'y',
data2: 'y2'
}
},
axis: {
y2: {
show: true
}
}
});
However my data is different/dynamic something like this:
['week', 1, 2, 3, 4, 5, 6],
['feed cow 30', 30, 200, 100, 400, 150, 250],
['weight cow 30', 30, 200, 100, 400, 150, 250],
['week', 1, 2, 3, 4, 5, 6],
['feed cow 40', 30, 200, 100, 400, 150, 250],
['weight cow 40', 30, 200, 100, 400, 150, 250],
['week', 1, 2, 3, 4, 5, 6],
['feed cow 60', 30, 200, 100, 400, 150, 250],
['weight cow 60', 30, 200, 100, 400, 150, 250],
So my Column names are dynamic. I create an array for the plotting of the data X axes. So my data is like this:
data: {
xs: xs,
columns: graphdata,
type: "line", .......
Now I want to have 2 Y axes, one for weight and one for feed. How can I achieve that?
Got it:
var axisData = {}; axisData[graphdata[2][0]] = "y"; axisData[graphdata[1][0]] = "y2";
....
data: {
xs: xs,
columns: graphdata,
axes : axisData,
type: "line",
},

How to combine Box plot graph with line graph in nvd3

enter image description here
Hi,
I have got a requirement to combine Boxplot chart with the line charts. I am using nvd3 library. I want to add two line charts in the same graph, one line will tell the avg and other will tell the current status. Can anyone please help me to achieve this functionality?
Thanks in advance!
configureChart = () => {
this.user_story_options = {
chart: {
type: 'boxPlotChart',
height: 450,
margin: {
top: 20,
right: 20,
bottom: 60,
left: 40
},
color: ['darkblue', 'darkorange', 'green', 'darkred', 'darkviolet'],
x: function(d) {
return d.label;
},
// y: function(d){return d.values.Q3;},
maxBoxWidth: 75,
yDomain: [0, 500]
}
};
}
getData = () => {
this.user_story_data = [{
label: 1,
values: {
Q1: 180,
Q2: 200,
Q3: 250,
whisker_low: 115,
whisker_high: 400,
outliers: [50, 100, 425]
}
},
{
label: 2,
values: {
Q1: 300,
Q2: 350,
Q3: 400,
whisker_low: 225,
whisker_high: 425,
outliers: [175, 450, 480]
}
},
{
label: 3,
values: {
Q1: 100,
Q2: 200,
Q3: 300,
whisker_low: 25,
whisker_high: 400,
outliers: [450, 475]
}
},
{
label: 4,
values: {
Q1: 75,
Q2: 100,
Q3: 125,
whisker_low: 50,
whisker_high: 300,
outliers: [450]
}
},
{
label: 5,
values: {
Q1: 325,
Q2: 400,
Q3: 425,
whisker_low: 225,
whisker_high: 475,
outliers: [50, 100, 200]
}
}
];
}
<div class="container-fluid">
<nvd3 #userStoryNvd3 [options]="user_story_options" [data]="user_story_data"></nvd3>
</div>
I've implemented the requirement using d3.
https://github.com/Dhiraj1411/box-plot-combined-with-line-chart

c3js Hide data after legend click and data update

To explain my problem, I use the following code on the c3js website (http://c3js.org/samples/chart_bar.html) :
var chart = c3.generate({
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 130, 100, 140, 200, 150, 50]
],
type: 'bar'
},
bar: {
width: {
ratio: 0.5 // this makes bar width 50% of length between ticks
}
// or
//width: 100 // this makes bar width 100px
}
});
setTimeout(function () {
chart.load({
unload : true,
columns: [
['data3', 130, -150, 200, 300, -200, 100]
]
});
}, 3000);
setTimeout(function () {
chart.load({
unload : true,
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 130, 100, 140, 200, 150, 50]
],
});
}, 4000);
I click on data1 to hide one of the data before it is updated, I have the following, which is normal:
But after the final update, I got a weird behavior where data1 is "half displayed":
Is there any way to solve this issue?
Thank you
The issue seems to be the drawing logic of c3. But there is a workaround for this issue. Check the following code:
setTimeout(function () {
chart.load({
unload : true,
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 130, 100, 140, 200, 150, 50]
],
done : function() {
// After chart is drawn, shown all the hidden legend.
chart.show();
}
});
}, 4000);

Large or unknown number of data arrays with Multiple XY Line Chart in c3.js

I've been using c3.js for some time now, but recently I stumbled across a problem. I'm using the Multiple XY Line Chart feature and my data set is huge. Is there a way to do the data-axis binding (the xs part) automatically instead of hard coding it?
var chart = c3.generate({
data: {
xs: {
'data1': 'x1',
'data2': 'x2',
.
.
.
'datan': 'xn',
},
columns: [
['x1', 10, 30, 45, 50, 70, 100],
['x2', 30, 50, 75, 100, 120],
.
.
.
['xn', 45, 60, 80, 120, 130],
['data1', 30, 200, 100, 400, 150, 250],
['data2', 20, 180, 240, 100, 190],
.
.
.
['datan', 10, 150, 220, 160, 300]
]
}
});
You just need to build a function that matches the syntax of your data series titles to the relevant x series
Assuming all the x1 / data1 etc stuff is in an object (allmydata) before you generate the chart you could do:
var allmydata = [
['x1', 10, 30, 45, 50, 70, 100],
['x2', 30, 50, 75, 100, 120],
['xn', 45, 60, 80, 120, 130],
['data1', 30, 200, 100, 400, 150, 250],
['data2', 20, 180, 240, 100, 190],
['datan', 10, 150, 220, 160, 300]
];
var match = function (dataStr) {
return dataStr.startsWith("data") ? dataStr.replace ("data", "x") : undefined;
};
var xs = {};
allmydata.forEach (function (series) {
var seriesName = series[0];
var xsName = match (seriesName);
if (xsName) {
xs[seriesName] = xsName;
}
});
var chart = c3.generate({
data: {
xs: xs,
columns: allmydata
}
});
http://jsfiddle.net/0f38ffsy/1/

Replacing chart datasets with d3.js / c3.js

DEMO HERE
In the demo I am attempting to unload all current datasets and load new ones like this:
Using C3.js
chart.unload();
chart.load({
columns: [
['data1', 130, 120, 150, 140, 160],
['data2', 30, 20, 50, 40, 60, 50],
],
});
This is obviously not the correct way to handle this process as the demo shows, this does not work correctly.
The C3 tutorial states that data sets should be replaced like this:
chart.load({
columns: [
['data1', 130, 120, 150, 140, 160],
['data2', 30, 20, 50, 40, 60, 50],
],
unload: ['data3', 'data4', 'data5'],
});
Again the demo shows this works correctly however...
QUESTION
How can I unload ALL current datasets and replace them with new ones without having to specify their individual data names (data3,data4) etc?
Note: The data sets are variable in name and quanity, hence why I just want to unload ALL.
Fundamentally all I want to do is replace the data sets with new ones on click.
I don't know if it could be usefull for you, in the past I have used this (unload in the same function of load). For your code it should be
chart.load({
columns: [
['data1', 130, 120, 150, 140, 160, 150],
['data4', 30, 20, 50, 40, 60, 50],
],
unload: chart.columns,
});
working fiddle
$('#A').on('click', function () {
chart.load({
columns: [
['data1', 130, 120, 150, 140, 160, 150],
['data4', 30, 20, 50, 40, 60, 50],
],
unload: chart.columns,
});
});
$('#B').on('click', function () {
chart.load({
columns: [
['data1', 130, 120, 150, 140, 160, 150],
['data4', 30, 20, 50, 40, 60, 50],
],
unload: chart.columns,
});
});

Categories