Specify the order of Plotly.js Sankey nodes - plotly.js

Trying to use plotly.js so show student grade transitions between quizzes. In Plotly.js the node order (i.e. score bands such as 0-40) is changed between the quizzes. Is there a way to keep them in the same order between quizzes (eg 0.40 is always at the bottom).
Thanks
var trace1 = {
type: "sankey",
orientation: "h",
node: {
groups: ["Quiz 1", "Quiz 2", "Quiz 3", "Quiz 4"],
label: ["0-40", "41-60", "61-70", "71-80", "81-100","0-40", "41-60", "61-70", "71-80", "81-100","0-40", "41-60", "61-70", "71-80", "81-100"],
color: ["red", "orange", "blue", "green", "green","red", "orange", "blue", "green", "green","red", "orange", "blue", "green", "green"]
},
link: {
source: [0,1,2,3,4,5,6,7,8,9],
target: [6,6,7,8,8,11,11,12,14,14],
value: [3,1,1,2,1,3,1,1,2,4,5]
}
};
var data = [ trace1 ];
var layout = {
title: {
text:'SANKEY Title',
font: {
family: 'Courier New, monospace',
size: 24
},
},
annotations: [{
text: 'QUIZ 1',
x: 0.0,
y: 1.1,
showarrow: false,
font: {size: 12}
},
{
text: 'QUIZ 2',
x: 0.5,
y: 1.1,
showarrow: false,
font: {size: 12}
},
{
text: 'QUIZ 3',
x: 1.0,
y: 1.1,
showarrow: false,
font: {size: 12}
},
{
text: 'QUIZ 4',
x: 1.5,
y: 1.1,
showarrow: false,
font: {size: 12}
}],
width: 600,
};
Plotly.newPlot('myDiv', data, layout);
<!-- Plotly.js -->
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="myDiv"></div>

You can define the node position as documented here.
node: {
x: [0.1, 0.1, 0.1, 0.1, 0.1, 0.2, 0.2, 0.2, 0.2, 0.2, 0.3, 0.3, 0.3, 0.3, 0.3],
y: [0.1, 0.2, 0.3, 0.4, 0.5, 0.1, 0.2, 0.3, 0.4, 0.5, 0.1, 0.2, 0.3, 0.4, 0.5],
pad: 50, // 50 Pixels
}
Keep your y values consistent per grade-band and you should be all set. Here's a CodePen example.

Related

canvasjs in decimal format with suffix is not working properly

I use canvasJS to make a line graph report, the issue now is it didn't show properly in tooltip using yValueFormatString.
my goal is to display the value:
{
type:"stepLine",
name: "title",
showInLegend: true,
connectNullData: true,
yValueFormatString: "##.## %",
dataPoints: [
{ x: new Date(2019, 1, 20), y: 12.78 },
{ x: new Date(2019, 1, 19), y: 12.79 },
{ x: new Date(2019, 1, 18), y: 12.80 },
]
}
in tooltip, it shows
1278 %
1279 %
1280 %
I think there's something wrong with it, I wanted to display like:
12.78 %
12.79 %
12.80 %
any idea?
According to documentation, "%" Multiplies a number by 100 i.e. 12.78("##.## %") => 1278%. Instead setting yValueFormatString to "##.#0 '%'" should work fine in this case.
Here is an example:
var chart = new CanvasJS.Chart("chartContainer", {
data: [{
type:"stepLine",
name: "title",
showInLegend: true,
connectNullData: true,
yValueFormatString: "##.#0 '%'",
dataPoints: [
{ x: new Date(2019, 1, 20), y: 12.78 },
{ x: new Date(2019, 1, 19), y: 12.79 },
{ x: new Date(2019, 1, 18), y: 12.80 },
]
}]
});
chart.render();
<script src="https://canvasjs.com/assets/script/canvasjs.min.js"></script>
<div id="chartContainer" style="width: 100%; height: 260px"></div>

AmXYChart - How to add padding to prevent hidden overflows

I have create a simple XY Chart graph with percent as y axes and customers as x axes, I randomised the data between 0...100% with a set of 184 points. and have a bit of difficulty display the lower/upper region values. I have included an image for the demonstration.
Here my config file, I cant seem to find some sort of offset/padding ?
{
type: 'xy',
addClassNames: true,
autoMargins: false,
marginLeft: 67,
marginBottom: 55,
graphs: [{
balloonFunction,
bullet: 'round',
xField: 'customers',
yField: 'rate',
bulletSize: 16,
lineColorField: 'color',
}],
valueAxes: [
{
title,
borderThickness: 0,
axisThickness: 2,
maximum: 100,
labelFunction: (e,val) => { return val + "%"; },
},
{
title,
position: 'bottom',
axisAlpha: 0,
borderThickness: 0,
axisThickness: 0,
gridThickness: 0,
},
],
dataProvider: data,
};
Thanks.
There isn't a way to pad this without modifying your minimum and maximum to be further outside your 0-100 range to accommodate. Since you're using a labelFunction, you can set it up so that you don't display any labels above and below 0-100% if you want, for example:
labelFunction: (e, val) => { return (val > 100 || val < 0 ? "" : val + "%"); }
Demo below using -10 as a minimum and 110 as a maximum:
var data = [{"rate": 99, "customers": 2421},{"rate": 76,"customers": 100},{"rate": 68,"customers": 1711},{"rate": 38,"customers": 313},{"rate": 94,"customers": 393},{"rate": 57,"customers": 946},{"rate": 99,"customers": 1772},{"rate": 20,"customers": 2168},{"rate": 100,"customers": 754},{"rate": 40,"customers": 121},{"rate": 51,"customers": 2412},{"rate": 15,"customers": 2364},{"rate": 32,"customers": 2161},{"rate": 55,"customers": 1506},{"rate": 29,"customers": 986},{"rate": 0,"customers": 698},{"rate": 4,"customers": 1285},{"rate": 22,"customers": 2108},{"rate": 17,"customers": 2081},{"rate": 79,"customers": 251},{"rate": 48,"customers": 258},{"rate": 41,"customers": 1541},{"rate": 35,"customers": 1132},{"rate": 86,"customers": 1213},{"rate": 1,"customers": 1936},{"rate": 51,"customers": 1737},{"rate": 5,"customers": 2447},{"rate": 60,"customers": 305},{"rate": 37,"customers": 776},{"rate": 64,"customers": 886}];
var chart = AmCharts.makeChart("chartdiv", {
type: 'xy',
addClassNames: true,
autoMargins: false,
marginLeft: 67,
marginBottom: 55,
graphs: [{
//balloonFunction,
bullet: 'round',
xField: 'customers',
yField: 'rate',
bulletSize: 16,
lineAlpha: 0, //for testing only
lineColorField: 'color',
}],
valueAxes: [
{
title: "Rate (%)",
borderThickness: 0,
axisThickness: 2,
maximum: 110,
minimum: -10,
labelFunction: (e,val) => { return (val > 100 || val < 0 ? "" : val + "%"); },
},
{
title: "Customers",
position: 'bottom',
axisAlpha: 0,
borderThickness: 0,
axisThickness: 0,
gridThickness: 0,
},
],
dataProvider: data,
});
<script type="text/javascript" src="//www.amcharts.com/lib/3/amcharts.js"></script>
<script type="text/javascript" src="//www.amcharts.com/lib/3/xy.js"></script>
<div id="chartdiv" style="width: 100%; height: 300px;"></div>
If you want to remove the extra grid lines from the additional points generated by the new minimum and maximum, you'll have to use guides as your grid lines and labels instead of the ones auto-generated by the chart. For example:
valueAxes: [{
guides: [{
"value": 0,
"label": "0%",
"lineAlpha": .2,
"tickLength": 5
},
// repeat for each tick/grid line
],
"gridAlpha": 0,
"tickLength": 0,
"labelsEnabled": false,
// ...
Demo:
var data = [{"rate": 99, "customers": 2421},{"rate": 76,"customers": 100},{"rate": 68,"customers": 1711},{"rate": 38,"customers": 313},{"rate": 94,"customers": 393},{"rate": 57,"customers": 946},{"rate": 99,"customers": 1772},{"rate": 20,"customers": 2168},{"rate": 100,"customers": 754},{"rate": 40,"customers": 121},{"rate": 51,"customers": 2412},{"rate": 15,"customers": 2364},{"rate": 32,"customers": 2161},{"rate": 55,"customers": 1506},{"rate": 29,"customers": 986},{"rate": 0,"customers": 698},{"rate": 4,"customers": 1285},{"rate": 22,"customers": 2108},{"rate": 17,"customers": 2081},{"rate": 79,"customers": 251},{"rate": 48,"customers": 258},{"rate": 41,"customers": 1541},{"rate": 35,"customers": 1132},{"rate": 86,"customers": 1213},{"rate": 1,"customers": 1936},{"rate": 51,"customers": 1737},{"rate": 5,"customers": 2447},{"rate": 60,"customers": 305},{"rate": 37,"customers": 776},{"rate": 64,"customers": 886}];
var chart = AmCharts.makeChart("chartdiv", {
type: 'xy',
addClassNames: true,
autoMargins: false,
marginLeft: 67,
marginBottom: 55,
graphs: [{
//balloonFunction,
bullet: 'round',
xField: 'customers',
yField: 'rate',
bulletSize: 16,
lineAlpha: 0, //for testing only
lineColorField: 'color',
}],
valueAxes: [
{
title: "Rate (%)",
borderThickness: 0,
axisThickness: 2,
maximum: 110,
minimum: -10,
guides: [{
value: 0,
label: "0%",
lineAlpha: .2,
tickLength: 5
},{
value: 20,
label: "20%",
lineAlpha: .2,
tickLength: 5
},{
value: 40,
label: "40%",
lineAlpha: .2,
tickLength: 5
},{
value: 60,
label: "60%",
lineAlpha: .2,
tickLength: 5
},{
value: 80,
label: "80%",
lineAlpha: .2,
tickLength: 5
},{
value: 100,
label: "100%",
lineAlpha: .2,
tickLength: 5
}],
gridAlpha: 0,
tickLength: 0,
labelsEnabled: false
},
{
title: "Customers",
position: 'bottom',
axisAlpha: 0,
borderThickness: 0,
axisThickness: 0,
gridThickness: 0,
},
],
dataProvider: data,
});
<script type="text/javascript" src="//www.amcharts.com/lib/3/amcharts.js"></script>
<script type="text/javascript" src="//www.amcharts.com/lib/3/xy.js"></script>
<div id="chartdiv" style="width: 100%; height: 300px;"></div>

how do i customise the c3.js chart to get like this

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>

With C3.js, how can I maintain bar width ratio when zooming in?

I have a c3.js bar graph with a subgraph and zooming enabled. I would like for the graph to show more x-tick labels and make the bars a little wider when the user selects a smaller area.
Here's what my graph looks like zoomed out (left) and zoomed in (right):
Here's a fiddle.
var chart = c3.generate({
bindto: '#chart',
data: {
x: 'x',
columns: [
['x', '2015-01-01', '2015-02-01', '2015-03-01', '2015-04-01', '2015-05-01', '2015-06-01', '2015-07-01', '2015-08-01', '2015-09-01', '2015-10-01', '2015-11-01', '2015-12-01', '2016-01-01', '2016-02-01', '2016-03-01', '2016-04-01', '2016-05-01', '2016-06-01', '2016-07-01', '2016-08-01'],
['y', 100, 200, 300, 200, 100, 450, 800, 900, 12, 70, 500, 450, 20, 100, 200, 300, 200, 100, 450, 800, 900, 12, 70, 500, 450, 20]
],
type: 'bar',
color: function(color, d) {
var color = d3.rgb("#E47911");
if (d.index % 2 == 0) {
color = color.darker(1.2);
}
return color;
}
},
bar: {
width: { ratio: 1.0 }
},
axis: {
x: {
type: 'timeseries',
tick: {
format: "%b",
fit: true
}
},
},
subchart: {
show: true
},
zoom: {
enabled: true
}
});
I'd like it to look more like this when zoomed in:
.
Is there a way to make this happen using C3?
copy the code to your fiddle js panel. type: 'categories' changes the bar scales.
var chart = c3.generate({
bindto: '#chart',
data: {
x: 'x',
columns: [
['x', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
['y', 100, 200, 300, 200, 100, 450, 800, 900, 12, 70, 500, 450, 20, 100, 200, 300, 200, 100, 450, 800, 900, 12, 70, 500, 450, 20]
],
type: 'bar',
color: function(color, d) {
var color = d3.rgb("#E47911");
if (d.index % 2 == 0) {
color = color.darker(1.2);
}
return color;
}
},
bar: {
width: { ratio: 0.8 }
},
axis: {
x: {
type: 'categories',
tick: {
format: "%b",
fit: true
}
},
},
subchart: {
show: true
},
zoom: {
enabled: true
}
});

Not able to create scatter and line chart together in c3.js

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'
}
}
});

Resources