Trying to create the above using c3.js.
We are using the same charting library across the application so would like to keep it consistent. Didn't find a way in c3.js to either customize donut or pie chart to get this. i need it to be hour, instead of percentage . and also the target value should be 12 instead of 100%. Any help or pointers are greatly appreciated.
normal jsfiddle link to customise.
var chart = c3.generate({
bindto: '#pie-chart',
data: {
columns: [
['data1', 30],
['data2', 120],
],
type : 'donut',
onclick: function (d, i) { console.log("onclick", d, i); },
onmouseover: function (d, i) { console.log("onmouseover", d, i); },
onmouseout: function (d, i) { console.log("onmouseout", d, i); }
},
donut: {
title: "Iris Petal Width"
}
});
setTimeout(function () {
chart.load({
columns: [
["setosa", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],
["versicolor", 1.4, 1.5, 1.5, 1.3, 1.5, 1.3, 1.6, 1.0, 1.3, 1.4, 1.0, 1.5, 1.0, 1.4, 1.3, 1.4, 1.5, 1.0, 1.5, 1.1, 1.8, 1.3, 1.5, 1.2, 1.3, 1.4, 1.4, 1.7, 1.5, 1.0, 1.1, 1.0, 1.2, 1.6, 1.5, 1.6, 1.5, 1.3, 1.3, 1.3, 1.2, 1.4, 1.2, 1.0, 1.3, 1.2, 1.3, 1.3, 1.1, 1.3],
]
});
}, 1500);
setTimeout(function () {
chart.unload({
ids: 'data1'
});
chart.unload({
ids: 'data2'
});
}, 2500);
I think I'm pretty close to what you were wanting. The onrendered callback code is to append a circle in the middle of that; you may want to handle that another way, my implementation is pretty basic.
The key things to pay attention to are the config options under gauge:
gauge: {
fullCircle: true, // This makes it go all the way around
max: 12, // This is your max unit -- 12h
min: 0, // Min. is 0
startingAngle: 90, // This sets the opening to the other side
width: 25, // This is how thick the outer arc is.
label: {
format: function(value, ratio) {
return value + 'HR';
}
}
var chart = c3.generate({
data: {
columns: [
['data1', 10],
],
type: 'gauge',
colors: {
data1: '#9873FF'
}
},
gauge: {
fullCircle: true, // This makes it go all the way around
max: 12, // This is your max unit -- 12h
min: 0, // Min. is 0
startingAngle: 90, // This sets the opening to the other side
width: 25, // This is how thick the outer arc is
label: {
format: function(value, ratio) {
return value + 'HR';
}
}
},
onrendered: function() {
setTimeout(function(){ // timeout is needed for initial render.
var centerBBox = d3.select('.c3-arc-data1').node().getBBox();
d3.select('.c3-arcs-data1')
.insert('circle', '.c3-arc-data1')
.classed('c3-arc-data1-background', true)
.attr('cx', centerBBox.x + centerBBox.width/2)
.attr('cy', centerBBox.y + centerBBox.height/2)
.attr('fill', '#6C40E8')
.attr('r', (centerBBox.height / 2 - 25)) // "25" is an arbitrary number
}, 0);
}
});
.c3-chart-arcs-gauge-max,
.c3-chart-arcs-gauge-min,
.c3-chart-arcs-background{
display: none;
}
.c3-gauge-value {
fill: white !important;
font-family: "Lucida Console", Helvetica, sans-serif;
font-size: 40px !important;
transform: translateY(10px);
}
.c3-arc-data1 {
stroke: transparent !important;
}
<link href="https://cdn.rawgit.com/c3js/c3/0.4.11/c3.css" rel="stylesheet"/>
<script src="https://cdn.rawgit.com/c3js/c3/0.4.11/c3.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="chart"></div>
Please guide me what i am doing wrong.I am using c3.js for showing chart in my webpage.Now i have requirement where i need to show spline and scatter chart together.I have searched in c3.js and came across combinational chart (http://c3js.org/samples/chart_combination.html). But when i used it for scatter and spline chart is not coming at all
Below is my code
<!-- Load c3.css -->
<link href="c3.css" rel="stylesheet" type="text/css">
<!-- Load d3.js and c3.js -->
<script src="d3.js" charset="utf-8"></script>
<script src="c3.js"></script>
<div class="chart" id="chart" ></div>
<script>
var chart = c3.generate({
data: {
xs: {
setosa: 'setosa_x',
},
// iris data from R
columns: [
["setosa", 3.0, 3.0, 3.2, 3.1, 3.6, 3.9, 3.4, 3.4, 2.9, 3.1, 3.7, 3.4, 3.0, 3.0, 4.0, 4.4, 3.9, 3.5, 3.8, 3.8, 3.4, 3.7, 3.6, 3.3, 3.4, 3.0, 3.4, 3.5, 3.4, 3.2, 3.1, 3.4, 4.1, 4.2, 3.1, 3.2, 3.5, 3.6, 3.0, 3.4, 3.5, 2.3, 3.2, 3.5, 3.8, 3.0, 3.8, 3.2, 3.7, 3.3],
["setosa_x", 3.2, 3.2, 3.1, 2.3, 2.8, 2.8, 3.3, 2.4, 2.9, 2.7, 2.0, 3.0, 2.2, 2.9, 2.9, 3.1, 3.0, 2.7, 2.2, 2.5, 3.2, 2.8, 2.5, 2.8, 2.9, 3.0, 2.8, 3.0, 2.9, 2.6, 2.4, 2.4, 2.7, 2.7, 3.0, 3.4, 3.1, 2.3, 3.0, 2.5, 2.6, 3.0, 2.6, 2.3, 2.7, 3.0, 2.9, 2.9, 2.5, 2.8],
['data3', 300, 200, 160, 400, 250, 250],
],
type: 'scatter',
types: {
data3: 'spline',
},
},
axis: {
x: {
label: 'Sepal.Width',
tick: {
fit: false
}
},
y: {
label: 'Petal.Width'
}
}
});
</script>
Thanks
I have also wondered.
To plot the line chart on the same x axis as the scatter chart, you will need an x axis and set it to the same axis as scatter chart. The setosa_x data does not have to be in order, but it should be so you can make a useful line chart on the shared x axis. This affects how setosa can be defined also.
Because the x axis will have several numbers the same, you will need to giver your line data some nulls.
You need to give the scatter and line charts different axes{} to work from (y and y2). Also need to set limits with min and max for each.
You can cut and paste the data in the arrays into M Excel and order the chronoligically
var chart = c3.generate({
data: {
x:'setosa_x',
xs: {
setosa: 'setosa_x',
},
// iris data from R
columns: [
//['x',2.3,2.9,3.0,3.0,3.0,3.0,3.0,3.0,3.1,3.1,3.1,3.1,3.2,3.2,3.2,3.2,3.2,3.3,3.3,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.5,3.5,3.5,3.5,3.5,3.6,3.6,3.6,3.7,3.7,3.7,3.8,3.8,3.8,3.8,3.9,3.9,4.0,4.1,4.2,4.4],
['data3', 100, 200, 300, null, null, 200, null, 160, 400, 250, 250,100, 200, 300, 200, 160, 400, 250, 250,100, 200, 300, 200 ],
["setosa_x",2.3,2.9,3.0,3.0,3.0,3.0,3.0,3.0,3.1,3.1,3.1,3.1,3.2,3.2,3.2,3.2,3.2,3.3,3.3,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.5,3.5,3.5,3.5,3.5,3.6,3.6,3.6,3.7,3.7,3.7,3.8,3.8,3.8,3.8,3.9,3.9,4.0,4.1,4.2,4.4],
["setosa", 0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2],
],
axes: {
// setosa_x: 'x',
setosa: 'y2',
data3: 'y'
},
type: 'scatter',
types: {
data3 : 'spline'
}
},
axis: {
y: {
min: 35,
show: true
},
y2: {
max: 0.5,
show: true
}
}
});
The above answer was a useful start for me but it's ultimately off point. The C3 system allows one to specify multiple chart types, without having to resort to creating multiple y axes, which should almost always be avoided because it's too easy to manipulate inferences in this manner (think of truncating one axis to increase the appearance of variability or vise versa).
Simply add in the x and y values respectively for each series you'd like to plot and refer to the type of chart that needs to be plotted in the types argument in the data object. See below:
var setosa_x = [2.3,2.9,3.0,3.0,3.0,3.0,3.0,3.0,3.1,3.1,3.1,3.1,3.2,3.2,3.2,3.2,3.2,3.3,3.3,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.4,3.5,3.5,3.5,3.5,3.5,3.6,3.6,3.6,3.7,3.7,3.7,3.8,3.8,3.8,3.8,3.9,3.9,4.0,4.1,4.2,4.4];
var setosa = [0.2, 0.2, 0.2, 0.2, 0.2, 0.4, 0.3, 0.2, 0.2, 0.1, 0.2, 0.2, 0.1, 0.1, 0.2, 0.4, 0.4, 0.3, 0.3, 0.3, 0.2, 0.4, 0.2, 0.5, 0.2, 0.2, 0.4, 0.2, 0.2, 0.2, 0.2, 0.4, 0.1, 0.2, 0.2, 0.2, 0.2, 0.1, 0.2, 0.2, 0.3, 0.3, 0.2, 0.6, 0.4, 0.3, 0.2, 0.2, 0.2, 0.2];
var new_setosa = setosa.map(function(x){
return 0.75 * x + .25;
});
var new_setosa_x = setosa_x.map(function(x){
return x + .10;
})
var other_chart = c3.generate({
bindto: '#other_chart',
data: {
xs: {
setosa: 'setosa_x',
other: 'other_x'
},
// iris data from R
columns: [
["setosa_x"].concat(setosa_x),
["setosa"].concat(setosa),
["other_x"].concat(new_setosa_x),
["other"].concat(new_setosa)
],
types: {
setosa: 'scatter',
other : 'spline'
}
}
});
I do not understand why the following two shaders produce different results when I render a vertex buffer with x coordinates equal to zero:
First:
attribute vec3 position;
void main() {
gl_Position = vec4(position.x, position.y, 0.0, 1.0);
}
Second:
attribute vec3 position;
void main() {
gl_Position = vec4(0.0, position.y, 0.0, 1.0);
}
The result of the first is a line of nine dots. The result of the second is a single dot.
I'm drawing the following vertex array as GL_POINTS:
0.0, -1.00, 0.0,
0.0, -0.75, 0.0,
0.0, -0.50, 0.0,
0.0, -0.25, 0.0,
0.0, 0.00, 0.0,
0.0, 0.25, 0.0,
0.0, 0.50, 0.0,
0.0, 0.75, 0.0,
0.0, 1.00, 0.0
Here's the VBO preparation calls:
var a = new Float32Array([
0.0, -1.00, 0.0,
0.0, -0.75, 0.0,
0.0, -0.50, 0.0,
0.0, -0.25, 0.0,
0.0, 0.00, 0.0,
0.0, 0.25, 0.0,
0.0, 0.50, 0.0,
0.0, 0.75, 0.0,
0.0, 1.00, 0.0
]);
gl.bindBuffer(gl.ARRAY_BUFFER, b);
gl.bufferData(gl.ARRAY_BUFFER, a.byteLength, gl.STATIC_DRAW);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, a);
Here's the draw calls:
gl.bindBuffer(gl.ARRAY_BUFFER, b);
gl.vertexAttribPointer(p.position, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(p.position);
gl.drawArrays(gl.POINTS, 0, 9);
That is a known problem (sorry, no link for now).
Basically, GLSL compiler thinks that attribute 'position' is not used, because the first component of it is not used. To check this try the following test:
gl_Position = vec4(0.0, position.y, 0.0, 1.0) + position.x*0.001;
Once you confirm the bug, you can either update you video driver or use an obvious workaround.