If I have a C3JS grouped bar chart defined like the following, how can I get the segments to stay in the order I've defined them instead of in ascending order by value? By default C3 will order them as 5, 10, 40, but I want it to remain as 10, 40, 5.
c3.generate({
bindto: '.active-loads',
data: {
columns: [
['Picking up future', 10],
['Enroute', 40],
['Delivered', 5]
],
type: 'bar',
groups: [
['Picking up future', 'Enroute', 'Delivered']
],
onclick: function(d) {
console.debug(d);
}
},
axis: {
rotated: true,
x: {
show: false
}
}
});
EDIT
Turns out it's as easy as specifying order: null in the data property.
C3js documentation has page for this : http://c3js.org/samples/data_order.html
You can order your data in following way :
var chart = c3.generate({
data: {
columns: [
['data1', 130, 200, 320, 400, 530, 750],
['data2', -130, 10, 130, 200, 150, 250],
['data3', -130, -50, -10, -200, -250, -150]
],
type: 'bar',
groups: [
['data1', 'data2', 'data3']
],
order: 'desc' // stack order by sum of values descendantly.
// order: 'asc' // stack order by sum of values ascendantly.
// order: null // stack order by data definition.
},
grid: {
y: {
lines: [{value:0}]
}
}
});
Also detailed explanation here too : http://c3js.org/reference.html#data-order
You can specify your function too :)
Related
When hovering over a line in billboardjs you can see a marker which follows the mouse (a tall vertical line). Is there a function for putting a marker on the x-line which can be used without triggering an automatic marker via onmousemove/hovering over data-points?
var chart = bb.generate({
data: {
columns: [
["data1", 30, 200, 100, 400, 150, 250],
["data2", 50, 20, 10, 40, 15, 25]
],
type: "line", // for ESM specify as: line()
},
bindto: "#lineChart"
});
https://naver.github.io/billboard.js/demo/#Chart.LineChart
So to exemplify. I use an onclick (in the data object) in the chart which defocuses the view and I still want the marker to remain.
So the code would look something like:
var chart = bb.generate({
data: {
columns: [
["data1", 30, 200, 100, 400, 150, 250],
["data2", 50, 20, 10, 40, 15, 25]
],
type: "line", // for ESM specify as: line()
onclick: function (d) {
focusElsewhere()
showMarker(d.x)
}
},
bindto: "#lineChart"
});
So the question is if there is a function for this, or an obvious fix?
I have looked through https://naver.github.io/billboard.js/release/latest/doc/Chart.html but I may of course have missed something.
I found that using xgrids did the trick. I don't think that the documentation gives a good example of how to use it. But basically you can use the "value" field to give which point the line should be on and add a class to show different kinds of lines.
var chart = bb.generate({
data: {
columns: [
["data1", 30, 200, 100, 400, 150, 250],
["data2", 50, 20, 10, 40, 15, 25]
],
type: "line", // for ESM specify as: line()
onclick: function (d) {
focusElsewhere()
this.xgrids.add({ value: d.x, class: "hover-line" }); //showMarker(d.x)
}
},
bindto: "#lineChart"
});
To remove the line or reset the billboard for continued use so to say, you can use
xgrids․remove({}) and add an object with some parameters of what kind of lines you want to remove.
this is my first question here in stack overflow.
I'm working with C3 and I'm wondering if is possible to align 2 points from end to end.
for example if in my chart I have 100 and another point -100, but I want to pass through the columns that appears in the image.
let me show you what I want:
I want to join/align the two-point that appears in the circle highlighted:
here is my code:
var chart = c3.generate({
data: {
columns: [
["data1", 30, 200, 100, 400, 150, 250],
["data2", -100],
["data3", null, null, null, null, null, 100],
],
axis: {
y: {
max: 365,
min: 335,
},
},
type: "bar",
types: {
data2: "line",
data3: "line",
},
colors: {
data1: "#f567",
data2: "blue",
},
bar: {
width: {
ratio: 0.5, // this makes bar width 50% of length between ticks
},
},
labels: {
format: function (v, id, i, j) {
return v;
},
},
// or
//width: 100 // this makes bar width 100px
},
});
thank you for your help! :)
I just added this part and it works
line: {
connectNull: true
},
I need to visualize the bar chart with Javascript. So I'm used C3 JS to visualize the chart. Simply I'm using this Bar chart as follows,
<div id="chart"></div>
<script>
var chart = c3.generate({
bindto: '#chart',
data: {
columns: [
['data1', 30, 200, 100, 400, 150, 250],
['data2', 50, 20, 10, 40, 15, 25]
],
axes: {
data2: 'y2'
},
types: {
data2: 'bar'
}
},
axis: {
y: {
label: {
text: 'Y Label',
position: 'outer-middle'
},
tick: {
format: d3.format("$,") // ADD
}
},
y2: {
show: true,
label: {
text: 'Y2 Label',
position: 'outer-middle'
}
}
}
});
</script>
But the problem is when X-axis consists of the large data set Chart getting cramped. I have more than 700 data.
Have any possible way to avoid this? can I add scroll bar between primary and secondary X-axis?
Google, such a wonderfull thing ;)
https://c3js.org/samples/interaction_zoom.html
or this
C3 / D3 bar chart with horizontal scroll
I am trying to set custom colors in a c3.js timeseries chart following this example. The first element of each array is used to identify the dataset, so if I have an array:
var datatest1 = ['data1', 30, 200, 100, 400, 150, 250];
the color property can be accessed like this:
colors: {data1:'#0000'}
or:
colors: {'data1':'#0000'}
However, if I use the first element of the array to access them:
var data1id = datatest1[0];
and then:
colors: {data1id:'#0000'}
It fails. Not sure what I may doing wrong as I get no feedback in the browser...
Here is a working example:
var axis = ['x', '2013-01-01', '2013-01-02', '2013-01-03', '2013-01-04', '2013-01-05', '2013-01-06'];
var datatest2 = ['data2', 130, 340, 200, 500, 250, 350];
var datatest1 = ['data1', 30, 200, 100, 400, 150, 250];
var data1id = datatest1[0];
var data2id = datatest2[0];
var chart = c3.generate({
data: {
x: 'x',
columns: [
axis,
datatest1,
datatest2
],
colors: {
//data1: '#0000',
//data2: '#0000'
datatest1: '#0000',
datatest2: '#0000'
}
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%Y-%m-%d'
}
}
}
});
----- EDIT
I am doing this because the data (including the identifier) is generated dynamically. Thanks
You can dynamically create the colors object like this.
var colors = {};
colors[datatest1[0]] = '#0000';
colors[datatest2[0]] = '#0000';
then set it in the graph like this
var chart = c3.generate({
data: {
x: 'x',
columns: [
axis,
datatest1,
datatest2
],
colors: colors //set colors object created above
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%Y-%m-%d'
}
}
}
});
working code here
Scenario: I need to show a bar chart about payment details, how much the customers paid for a product using Card, Cheque or Cash. And also need to display the total value in a stacked bar chart.
var chart = c3.generate({
data: {
columns: [
['Cash', 30, 200, 100, 400, 150, 250],
['Card', 130, 100, 140, 200, 150, 50],
['Total', 160,300,240,600,300,300]
],
groups:[['Cash','Card']],
type: 'bar'
}
});
Output:
I need to show the Total value but not the bar and the legend. How can do this? Any advice would be helpful. Thank you.
You don't need the total dataset, you can alter the tooltip contents to calculate it on the fly (adapting the technique found in the answer here -> https://stackoverflow.com/a/36789099/368214)
var chart = c3.generate({
data: {
columns: [
['Cash', 30, 200, 100, 400, 150, 250],
['Card', 130, 100, 140, 200, 150, 50],
],
groups:[['Cash','Card']],
type: 'bar'
},
tooltip : {
contents: function (d, defaultTitleFormat, defaultValueFormat, color) {
var total = d.reduce (function(subTotal,b) { return subTotal + b.value; }, 0);
d.push ({value: total, id: "Total", name: "Total", x:d[0].x , index:d[0].index});
return this.getTooltipContent(d, defaultTitleFormat, defaultValueFormat, color);
}
}
});
The total value is calculated using .reduce to sum all the other values at that point. Then make a new data point for the tooltip called 'Total' using that value and pass it to the default renderer for drawing (this.getTooltipContent)
http://jsfiddle.net/vz1rwvwn/