How can I create a bar chart that has multiple yAxes scales? - bar-chart

I have the following code:
data = {
labels: ["CategoryA", "CategoryB"],
datasets: [
{
label: "Group A",
data: [95, 1]
},
{
label: "Group B",
data: [80, 3]
}
]
};
new Chart(ctx, {
type: 'bar',
data: data,
options: option
});
My goal is to directly compare the numbers in Group A and Group B per category. However, the bars for CategoryA take up the entire vertical space while CategoryB is barely visible.
How can I make CategoryA display on a scale from 0 to 100 and CategoryB on a scale from 0 to 5?
EDIT:
Here was the problem I had. Was unable to make a solution with only one graph, ended up just using two separate ones. If anyone knows how to do it in one graph, please let me know!

Unfortunately, there is no built-in method in ChartJS to achieve this at the moment.
Though, one way I can think of achieving this, is to create two different charts and place them on top of each other, as such ...
// CHART 1
var data = {
labels: ["Category A", "Category B", "Category C"],
datasets: [{
label: "Group A",
data: [95, 0, 0],
backgroundColor: 'blue'
}, {
label: "Group B",
data: [60, 0, 0],
backgroundColor: 'red'
}]
};
var option = {
scales: {
yAxes: [{
ticks: {
min: 0,
max: 100
}
}]
}
}
new Chart(ctx, {
type: 'bar',
data: data,
options: option
});
// CHART 2
var data2 = {
labels: ["Category A", "Category B", "Category C"],
datasets: [{
label: "Group A",
data: [0, 1, 2],
backgroundColor: 'blue'
}, {
label: "Group B",
data: [0, 3, 4],
backgroundColor: 'red'
}]
};
var option2 = {
scales: {
yAxes: [{
position: 'right',
ticks: {
min: 0,
max: 5
}
}]
}
}
new Chart(ctx2, {
type: 'bar',
data: data2,
options: option2
});
#chart-wrapper {
display: flex;
}
#ctx2 {
position: absolute;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.min.js"></script>
<div id="chart-wrapper">
<canvas id="ctx"></canvas>
<canvas id="ctx2"></canvas>
</div>

Related

Barchart reducing space between bars

I am trying to reduce the space between bars, and I am pretty sure it has to be within this piece of code. I removed the code that displays the legend and yAxes assuming I would not need to edit those parts.
barchart = new Chart(myChart, {
type:'bar',
data:{
labels: {{ data.x_vals | tojson }},
datasets:[{
label:'Liquid Level',
data:{{ data.y_vals }},
backgroundColor: gradient,
borderWidth:1, //Effects plotted line on chart
borderColor:'white',
hoverBorderWidth:1,
hoverBorderColor:'#000',
barPercentage: 1.0,
categoryPercentage: 1.0
}]
},
options:{
// legend is here
},
scales: {
// yAxes is here
xAxes: [{
display: true,
ticks: {
autoSkip: true,
padding: 4,
fontSize: 12
}
}]
},
You can set the category and bar percentages to 1:
var options = {
type: 'bar',
data: {
labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
datasets: [{
label: '# of Votes',
data: [12, 19, 3, 5, 2, 3],
backgroundColor: 'blue',
categoryPercentage: 1,
barPercentage: 1
}]
},
options: {
scales: {
yAxes: [{
ticks: {
reverse: false
}
}]
}
}
}
var ctx = document.getElementById('chartJSContainer').getContext('2d');
new Chart(ctx, options);
<body>
<canvas id="chartJSContainer" width="600" height="400"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.js"></script>
</body>
EDIT:
Make sure you have at least chart.js version 2.9 installed since any version below its not implemented yet

One series name in higcharts not getting populated even though json send the correct information

The last series in a bar chart is showing "Series 4" as a name, even though its proper name is coming correcty from json file.
The information from the json file comes from a SQL query that prints the information in a string with the following format:
[
{"name": "Operation","data": [{"y":3000, "second": 1500, "third": 5}]},
{"name": "Mechanical","data": [{"y":2515, "second": 515, "third": 8}]},
{"name": "Electrical","data": [{"y":1800, "second": 475, "third": 10}]},
{"name": "Operation Slag","data": [{"y":1000, "second": 1500, "third": 7}]}
]
Since the colors of the series are set manually, I am using the below to add just data and name to each series:
jspData.forEach(function(jspData, i) {
Delays.series[i].setData(jspData.data);
Delays.series[i].setName(jspData.name);
}];
This is working as expected until the last series which show "Series 4" name and not "Operation Slag".
$(function () {
$(document).ready(function(){
$.getJSON('getData.json', function(jspData) {
var Delays = new Highcharts.chart({
chart: {
renderTo: 'Delays',
type: 'bar'
},
xAxis: {
categories: [''],
lineWidth: 0,
minorTickLength: 0,
tickLength: 0,
gridLineWidth: 0,
minorGridLineWidth: 0,
title: {
text: null
}
},
yAxis: {
gridLineWidth: 0,
minorGridLineWidth: 0,
lineWidth: 0,
tickWidth: 0,
tickLength: 0,
min: 0,
title: null,
labels: {
enabled: false,
}
},
tooltip: {
enabled:true,
style:{fontSize:'10px', fontFamily:"sans-serif"},
formatter: function() {
console.log(this);
return 'Total duration: ' + this.y + 'min<br/>Delay Code: ' + this.point.second + '<br/>Count of Events: ' + this.point.third;
},
},
plotOptions: {
bar: {
borderWidth: 0.5,
dataLabels: {
enabled: true,
format: '{series.name}',
style: {
fontSize: "10px",
fontWeight:'normal',
textOutline: false,
fontFamily: 'sans-serif',
},
}
},
series: {
groupPadding: 0,
pointPadding: 0,
},
},
legend:{
enabled:false,
},
series: [{
color:'#4572A7',
data: []
}, {
color:'#89A54E',
data: []
}, {
color:'#AA4643',
data: []
}, {
color:'#A1745B',
data: []
}],
});
jspData.forEach(function(jspData, i) {
Delays.series[i].setData(jspData.data);
Delays.series[i].setName(jspData.name);
});
});
});
});
Last series name should not be "Series 4" but "Operation Slag". Chart is render porperly all other data is populated correctly.
The setName method is internal and it requires to redraw the chart. In your case it's enough to change the order of calls, because setData causes redraw:
jspData.forEach(function(jspData, i) {
Delays.series[i].setName(jspData.name);
Delays.series[i].setData(jspData.data);
});
Live demo: http://jsfiddle.net/BlackLabel/0qkf26zp/
API: https://api.highcharts.com/class-reference/Highcharts.Series#setData

Multiple labels in chartjs with stacked bars on angular 4

My problem is that I have to display one label for each bar but i can't because when i add labels to the json chartjs add new group of empty bars
as I show in the picture, I'm using stacked bars, how I can do that?.
Here is my Json code.
PredialUrbano = {
type: 'groupableBar',
labels: ['Facturado','cobrado','ejemplo'],
datasets: [
{
label: 'Facturado',
data: [67.8],
backgroundColor: '#3A3032',
stack: 1
}, {
label: 'Exento',
data: [20.7],
backgroundColor: '#902528',
stack: 1
},
{
label: 'Ley de ingresos',
data: [20.7],
backgroundColor: '#902528',
stack: 2
},
{
label: 'Cobrado',
data: [20.7],
backgroundColor: '#3A3032',
stack: 3
}
],
options: {
scales: {
xAxes: [{ stacked: true }],
yAxes: [{ stacked: true }]
}
},
};

Highcharts to present in an HTML Table

I'm currently creating a system that produces different kind of graphs. I want to create a chart and table, that when a chart is DRILLDOWNED, the table will sync as well. Is there a way to output the current data presented by HighCharts to JSON? Then this JSON will be inputted into a datatable? Thanks!
check this JsFiddle Demo
You can obtain the id by e.seriesOptions.id which is the key to your data. Then you can use this id as the key to get appropriate data and update your data table from within the drillUp and drillDown events.
HTML
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/drilldown.js"></script>
<div id="container" style="min-width: 310px; height: 400px; margin: 0 auto"></div>
JS
$(function() {
// Create the chart
$('#container').highcharts({
chart: {
type: 'column',
events: {
drillup: function(e) {
//alert('drill Up');
console.log(this);
console.log(e.seriesOptions.id);
console.log(this.options.series[0].name);
console.log(this.options.series[0].data[0].name);
},
drilldown: function(e) {
//alert('drill Down');
console.log(this);
console.log(e.seriesOptions.id);
console.log(this.options.series[0].name);
console.log(this.options.series[0].data[0].name);
}
}
},
title: {
text: 'DrillUp button styling'
},
xAxis: {
type: 'category'
},
legend: {
enabled: false
},
plotOptions: {
series: {
borderWidth: 0,
dataLabels: {
enabled: true,
}
}
},
series: [{
name: 'Things',
colorByPoint: true,
data: [{
name: 'Dieren',
y: 5,
drilldown: 'animals'
}, {
name: 'Fruit',
y: 2,
drilldown: 'fruits'
}, {
name: "Auto's",
y: 4
}]
}],
drilldown: {
drillUpButton: {
relativeTo: 'spacingBox',
position: {
y: 0,
x: 0
},
theme: {
fill: 'white',
'stroke-width': 1,
stroke: 'silver',
r: 0,
states: {
hover: {
fill: '#bada55'
},
select: {
stroke: '#039',
fill: '#bada55'
}
}
}
},
series: [{
id: 'animals',
data: [
['Katten', 4],
['Honden', 2],
['Koeien', 1],
['Schapen', 2],
['Varkens', 1]
]
}, {
id: 'fruits',
data: [
['Appels', 4],
['Sinaasappels', 2]
]
}]
}
})
});

Highcharts - how change JSON to csv

I have a small problem...
$(function () {
$.get('../../../abc-test.csv', function(data) {
// split the data set into ohlc and volume
var ohlc = [],
volume = [],
dataLength = data.length,
// set the allowed units for data grouping
groupingUnits = [[
'week', // unit name
[1] // allowed multiples
], [
'month',
[1, 2, 3, 4, 6]
]],
i = 0;
for (i; i < dataLength; i += 1) {
ohlc.push([
data[i][0], // the date
data[i][1], // open
data[i][2], // high
data[i][3], // low
data[i][4] // close
]);
volume.push([
data[i][0], // the date
data[i][5] // the volume
]);
}
$('#test').highcharts({
rangeSelector: {
selected: 1
},
title: {
text: 'AAPL Historical'
},
yAxis: [{
labels: {
align: 'right',
x: -3
},
title: {
text: 'OHLC'
},
height: '60%',
lineWidth: 2
}, {
labels: {
align: 'right',
x: -3
},
title: {
text: 'Volume'
},
top: '65%',
height: '35%',
offset: 0,
lineWidth: 2
}],
data: {
csv: data
//csv: document.getElementById('csv').innerHTML
},
series: [{
type: 'candlestick',
name: 'AAPL',
data: ohlc,
dataGrouping: {
units: groupingUnits
}
}, {
type: 'column',
name: 'Volume',
data: volume,
yAxis: 1,
dataGrouping: {
units: groupingUnits
}
}]
});
});
});
abc-test.csv:
Date,Open,High,Low,Close,Volume
2013-12-20,9371.08,9413.09,9352.98,9400.18,161686900
2013-12-19,9279.68,9351.9,9257.24,9335.74,98276500
2013-12-18,9145.35,9190.73,9122.05,9181.75,82342700
2013-12-17,9142.75,9161.8,9085.12,9085.12,72207500
2013-12-16,9004.62,9187.78,8997.75,9163.56,99105600
2013-12-13,9016.78,9046.63,8990.58,9006.46,67761700
2013-12-12,9032.67,9060.54,8984.28,9017,75120200
2013-12-11,9093.26,9153.14,9065.51,9077.11,64845800
2013-12-10,9180.29,9223.73,9091.97,9114.44,74363400
Why this code dont't work ?
Don't work:
- Two panes, candlestick and volume
- OHLC
- 1.7 million points with async loading...
The issue is in the "date" in csv or something else ... ?