c3 (v4) scatter plot with two sets of data - javascript

I have the following csv file to plot two different sets of data: normal and global with its respective regression.
Access grade global,Grade_global,Regression_global,Access grade,Grade,Regression
11.48,6.0,5.66,11.48,6.0,5.74
11.43,5.6,5.63,11.43,5.6,5.69
12.13,5.9,6.16,12.13,5.9,6.55
10.48,5.0,4.91,10.48,5.0,4.52
10.54,4.7,4.96,10.54,4.7,4.6
10.23,5.1,4.73,10.23,5.1,4.22
12.27,5.5,6.26,12.27,5.5,6.71
11.13,4.2,5.4,11.13,4.2,5.32
13.7,10.0,7.34,13.7,10.0,8.46
I want to create a scatter plot with all the dots, each group in a different color and with its respective linear regressions (dots of the regression already calculated). I am trying to assign "Access grade global" and "Access grade" as x values to both the "Grade"/"Grade_global" and "Regression"/"Regression_global"
How can I do it? My actual code is:
var chart = c3.generate({
bindto: '#chart0',
data: {
url: '../static/CSV/Chart_data/grades_access_hs.csv?rnd='+(new Date).getTime(),
xs: {
Grade_global: 'Access grade global',
Grade: 'Access grade'
},
type: 'scatter',
types: {
Regression_global: "line",
Regression: 'line'
},
},
axis: {
y: {
label: {
text: "Average grade",
position: "outer-middle"
},
min: 1,
max: 9
},
x: {
label: {
text: "Access grade PAU",
position: "outer-center"
},
min: 9,
max: 14
}
},
size: {
height: 400,
width: 800
},
zoom: {
enabled: true
},
legend: {
show: true,
position: 'inset',
inset: {
anchor: 'top-right',
x: 20,
y: 300,
step: 1
}
},
})
I get the error: Uncaught Error: x is not defined for for id = "Regression_global".
Thanks!

You are defining your x in the wrong way. Referring to this example, the chart constructor uses xs.
In your chart, defining the xs like this:
....
data: {
url: '../static/CSV/Chart_data/grades_access_hs.csv?rnd='+(new Date).getTime(),
xs: {
'Access grade global': 'Access grade',
'Calculus I global': 'Calculus I',
},
type: 'scatter'
},
....
should work.
Plunker

Related

ChartJS options.scales is being completely ignored

I am trying to make a chart which has years along the x-axis and dollar amounts along the y-axis. I finally got close to what I'm looking for, but I found that because the x coordinates are numbers, ChartJS is putting commas in them which looks really strange for years.
After some digging, I used the callbacks. options.plugin.tooltip.callbacks.label worked to let me remove commas in the tooltips, but when I use options.scales.x[0].ticks.callback to try to fix the labels on the bottom, not only does it not work, but I don't see the console.log statement in their ever being printed so it seems it's not even calling the callback. I've tried several variations of how to do the callback based on what I found online and on Stack Overflow which I think correspond to the different ways ChartJS did this in different versions. (I'm on version 3.5.1.)
Then, I realized that... none of the options under options.scales appear to have any effect. I change the min, the title, the tick settings (color to red, callback, etc.) and it has no effect. (This also explains why I was having trouble when using the line chart and had to switch to scatter; apparently type: 'linear' wasn't being picked up nor did it do anything different when I set it to type: 'date' or whatever the exact working was for that.)
Meanwhile, the other options like options.showLine or options.elements do have an effect and I'm seeing the chart and not getting any errors in the console. So, it is picking up the options, just ignoring everything I have in options.scales.
Here is the relevant code:
// Sample data added to make this example self-contained
// This is my internal data format
let data = {
"Series1": [ {x: 2001, y: 100 }, {x: 2002, y: 110 }, {x: 2003, y: 107 }, ],
"Series2": [ {x: 2001, y: 107 }, {x: 2002, y: 102 }, {x: 2004, y: 95 }, ],
}
// Define data //////////////////////////////////////////////////////
// I convert data to format ChartJS wants and add a few options
let datasets = [];
for(let label in data) {
let c = colorIterator.next().value
datasets.push({
label: label,
data: data[label],
backgroundColor: c,
borderColor: c,
});
}
// Define options //////////////////////////////////////////////////////
let chartConfig = {
type: 'scatter',
data: { datasets: datasets, },
options: {
title: { display: false },
indexAxis: 'x', responsive: true, maintainAspectRatio: false,
showLine: true,
elements: {
line: { display: true, tension: 0, borderWidth: 1, fill: false, },
point: { radius: 3 }
},
interaction: { mode: 'x', },
scales: {
x: [{
type: 'linear',
min: 1995, max: (new Date()).getFullYear()+1, stepSize: 1,
title: { display: true, text: 'Year' },
ticks: {
display: true,
major: { enabled: true },
color: 'red',
callback: function(value, index, ticks) {
console.log(value);
return Chart.Ticks.formatters.numeric.apply(this, [value, index, ticks])
.replace(",","");
}
}
}],
y: [{
title: { display: true, text: '$' },
ticks: {
display: true,
color: 'red',
},
}],
},
plugins: {
tooltip: {
callbacks: {
label: function(context) {
let label = context.dataset.label || '';
if(label) {
let x = context.label.replace(",","");
let y = context.formattedValue;
return 'Year ' + x + ' "' + label + '": $' + y;
} else { return 'x'; }
},
},
},
},
}
};
// MAKE CHART //////////////////////////////////////////////////////
let mainChart = new Chart(document.getElementById(c.id), chartConfig);
As described in the docs the scales are not arrays. All the scales are objects in the scale object.
So you will need to change your code to this:
options: {
scales: {
x: {
// x options
},
y: {
// y options
},
}
}

Highcharts.js question: is it possible to keep some part of chart in visible area always, even if "overscoll" option is set

I need to show some empty space to far right of the chart. To do so I use "overscroll" option (https://api.highcharts.com/highstock/xAxis.overscroll). But if user zoom in chart and pans chart to far right there can be empty space without any part of candlestick chart displayed (https://screencast-o-matic.com/watch/cqnfFq3CII). Please advise is it possible to implement following chart behaviour and how to do so: to keep some part of chart in visible area always, even if "overscoll" option is set and user pans chart to the far right? Thanks!
Here is my code:
var ohlc = JSON.parse(ohlcStringified),
volume = JSON.parse(volumeStringified);
var interval = ohlc[ohlc.length - 1].x - ohlc[ohlc.length - 2].x;
var chart = Highcharts.stockChart('container', {
chart: {
borderWidth: 1,
panning: true,
},
title: {
text: 'Chart'
},
legend: {
enabled: true
},
rangeSelector: {
selected: 1,
enabled: false
},
scrollbar: {
enabled: false
},
xAxis: {
minPadding: 0.2,
overscroll: 50 * interval,
},
yAxis: [{
height: '40%'
}, {
top: '40%',
height: '30%',
offset: 0
}, {
top: '70%',
height: '30%',
offset: 0
}],
series: [{
type: 'candlestick',
id: 'candlestick',
name: 'AAPL',
data: ohlc,
tooltip: {
valueDecimals: 2
},
dataGrouping: {
enabled: false,
}
}, {
type: 'column',
id: 'volume',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
enabled: false,
}
}]
});
Here is live demo: http://jsfiddle.net/ogorobets/bfcs9gx7/2/
It's possible, however, it requires some custom logic. It can be achieved using xAxis.events.afterSetExtremes callback where you can check if the current axis minimum is greater than your limit (a value lower than maximum xData value). When it is true, set new axis extremes with your limit as a minimum value. Check the code and demo posted below.
Code:
xAxis: {
minPadding: 0.2,
overscroll: 50 * interval,
events: {
afterSetExtremes: function() {
var chart = this.chart,
xData = chart.series[0].xData,
maxValue = xData[xData.length - 5],
min = chart.xAxis[0].min,
max = chart.xAxis[0].max
if (min > maxValue) {
chart.xAxis[0].setExtremes(maxValue, max, true, false);
}
}
}
}
Demo:
https://jsfiddle.net/BlackLabel/p6d73nk8/
API reference:
https://api.highcharts.com/highcharts/xAxis.events.afterSetExtremes
https://api.highcharts.com/class-reference/Highcharts.Axis#setExtremes

Add click event on each category name on X axis in c3 js

I'm using c3 js for generating categories bar chart
Here is code
var obj = {
size: {
height: 200,
},
bindto: '#grBarChart',
data: {
columns: data.columns,
type: "bar"
},
color: {
pattern: ['#c90000', '#008cba', '#FAAC3D','#427322', '#9ead9b', '#ffa500']
},
axis: {
x: {
type: 'category',
categories: data.categories,
label: {
text: 'Scanned Groups',
position: 'outer-center'
}
},
y: {
label: {
text: 'Count (Rules)',
position: 'outer-middle'
}
}
},
bar: {
width: {
ratio: 0.5,
}
},
grid: {
y: {
show: true
}
}
};
var chart = c3.generate(obj);
This code is generating the following graph
Now my problem is I'm not able to add click event on X Axis Category Names ( Logging 11, Data Protection 13 ...)
I referred C3 Documentation but not able to solve my problem.
Please give me your thought?

C3 graph overlapping x-axis label

C3 graph overlap x-axis labels which is in date time format. I have googled this query but didn't get any solution for it.Is it possible that c3 only shows couple of date time rather then showing altogether which result in overlap x-axis labels
var data = {
x: 'x',
xFormat:'%Y-%m-%d/%H:%M',
empty: {
label: {
text: "No Data"
}
},
columns: [
['x', '{$dateArray}'],
['Attack', {$data}],
],colors: {
Attack: '#67b7dc',
},
types: {
Attack: 'area'
}};
var chart = c3.generate({bindto: '#chart1',
size: {
height: 630,
},
data: data,
grid: {
x: {
show: true
},
y: {
show: true
}
},
tooltip: {
format: {
value: function (value, ratio, id) {
var format = value+' Gbps [ IP: '+destIp[value]+' ]';
return format;
}
}
},
zoom: {
enabled: true
},
subchart: {
show: true
},axis: {
x: {
type: 'timeseries',
tick: {
format: '%b %d, %H:%M',
rotate: 90,
multiline: false
}
},
y: {
tick: {
format: function (d) {
return d.toFixed(3);
}
},
label: {
text: 'Attack Size ( Gbps )',
position: 'outer-middle'
}
}
}
});
Use c3.js chart config tick.count, set it to desired integer value like 2,3 or 4.
Use c3.js Timeseries Chart exmaple to play with this config.
Problem without tick.count:-
Problem solved with tick.count config:-

Is there a way to change the type of the subcharts in c3.js

I have made a bar char chart and it also has a sub chart. I want to change the type of the subchart to line. As in, the main chart should be a bar chart but the subchart of this should be a line chart.
This is the piece of code I am using to generate the chart. But the type of subchart is not working.
var chart=c3.generate({
bindto:bindTo(),
data:{
x:'x',
/* value:['Percent DEP Enabled'],*/
columns:data(),
type: 'bar'
},
subchart: {
show: true,
size: {
height: 25
},
},
axis: {
x: {
type: 'timeseries',
tick: {
format: '%m-%d-%y',
rotate: -45,
},
height: 75
},/* y: {
tick: {
values: function(){
jQuery.forEach(function(){
})}
count: 8,
format:d3.format(".2s"),
},
},*/
subchart: {
show: true,
type: 'line',
}
}
});
You can't do this because there is no setting like axis.subchart. When you take a look at the reference you'll find everything you need but in your case there is no option.

Categories