I am working with Highcharts and have come across a little problem that I am struggling to overcome.
I have created a jsfiddle so you can see my issue:
http://jsfiddle.net/jo_pappi/0e5h8sts/3/ [A]
As you can see
I can achieve the above format in highcharts, Since this chart is rendering based on dynamic data When a single group values arrives highcharts leaves so much space between the bars. Am attaching image here
And the code
$('#container-one').highcharts({
chart: {
type: 'bar',
events: {
click: function (event) {
console.log(event.pageX + ',' + event.pageY);
}
}
},
credits: {
enabled: false
},
title: {
text: 'Total fruit consumtion, grouped by gender'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas'],
minPadding: 1.1,
maxPadding: 1.1
},
yAxis: {
allowDecimals: false,
min: 0,
title: {
text: 'Number of fruits'
}
},
tooltip: {
enabled: false,
formatter: function () {
return '<b>' + this.x + '</b><br/>' + this.series.name + ': ' + this.y + '<br/>' +
'Total: ' + this.point.stackTotal;
}
},
plotOptions: {
// column: {
// stacking: 'normal'
// }
series: {
pointWidth: 20,
stacking: 'normal',
borderWidth: 0,
events: {
click: function (event) {
//reloadFlash();
//$('#report').html('click on yAxis title');
console.log(event.pageX + ',' + event.pageY);
}
}
}
},
series: [{
name: 'John',
color: 'rgba(89,89,89,1)',
data: [5], // data: [5, 3, 4, 7, 4],
stack: 'male',
pointPadding: -0.0,
pointPlacement: -0.0
}, {
name: 'Joe',
color: 'rgba(255,95,215,1)',
data: [3], // data: [3, 4, 4, 2, 2],
stack: 'male',
pointPadding: -0.0,
pointPlacement: -0.0
}, {
name: 'Jane',
color: 'rgba(217,116,0,1)',
data: [2], // data: [2, 5, 6, 2, 1],
stack: 'female',
pointPadding: -0.0,
pointPlacement: -0.0
}, {
name: 'Janet',
color: 'rgba(155,215,255,1)',
data: [3], // data: [3, 0, 4, 4, 3],
stack: 'female',
pointPadding: -0.0,
pointPlacement: -0.0
}]
});
how can i reduce the spaces between bars?
If changing height of the chart is one solution means how can i achieve this dynamically?
Removing "pointWidth" solved the white space between the bars. But i need the bars should be off same height in all possible cases. I have solved the problem by setting height dynamically based on the categories count. say for example if am having only one category i have set the height for the chart as "210" and for 2 categories "270" like that. and removed pointWidth.
$('#container-one').highcharts({
chart: {
type: 'bar',
height: 210,
...
.
.
plotOptions: {
bar: {
pointPadding: 0,
borderWidth: 0
},
series: {
//pointWidth: 20,
stacking: 'normal',
.
.
});
When i have two categories i have set chart height as 270
$('#container-two').highcharts({
chart: {
type: 'bar',
height: 270,
...
.
.
plotOptions: {
bar: {
pointPadding: 0,
borderWidth: 0
},
series: {
//pointWidth: 20,
stacking: 'normal',
.
.
});
and the Fiddle Link
may be what i did was wrong. But its fixed my problem. correct me if am wrong.
Thanks all
The options you can use are:
plotOptions:{
bar:{
pointPadding: 0,
groupPadding: 0,
}
}
But you also need to not force your bar point width.
Remove:
series: {
pointWidth: 20,
http://jsfiddle.net/d9f8b22x/
The API docs discuss how these options relate to each other:
http://api.highcharts.com/highcharts#plotOptions.column.pointPadding
What are you using 'pointWidth: 20' in series for ?? That is creating the problem.. Also you are giving the categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas'] even if the data comes for only apples.. one solution would be to generate the categories dynamically.. say for example if data comes only for apples push only apples in the categories array. Then after that you can use :
_chart.setSize(width,height)
method to dynamically set the new height and width of the highchart. Also removing pointWidth will solve the problem ...
Related
i have generated something like.
with this code for highchart option:
Highcharts.chart('container', {
chart: {
type: 'bar'
},
colors: [ '#ff058d', '#9696b2'],
title: {
text: null
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas'],
labels: {
align: 'left',
x: 0,
y: -20,
fontsize: '1em',
color: 'black'
}
},
yAxis: {
visible: false,
min: 0,
title: {
text: 'Total fruit consumption'
}
},
legend: {
visible: false,
reversed: true
},
plotOptions: {
series: {
stacking: 'normal'
}
},
series: [{
name: 'Compliant',
data: [5, 3, 4, 7, 2]
}, {
name: 'Non-Compliant',
data: [2, 2, 3, 2, 1]
}]
});
but i want something like below. according to above code, how can i generate below image?
i want the footer and also the title in front of every chart.
You should be able to achieve it by using the stackLabels and dataLabels feature and their formatter callback function to customize them.
Demo: https://jsfiddle.net/BlackLabel/m1skyt9g/
Code to show the percent value (I'm not sure if this is the correct value to show, but you should be able to easily change it to your requirments) next to the bar:
stackLabels: {
enabled: true,
x: 6,
formatter() {
let output = Math.round(this.total / this.points[0][0] * 100) / 100;
return output + '%'
}
}
To show the 'footer' as a dataLabel:
dataLabels: {
enabled: true,
align: 'left',
allowOverlap: true,
y: 23,
formatter() {
let output = Math.round(this.total / this.y * 100) / 100
if (!this.colorIndex) {
return '';
} else {
return 'Previous Non-Compliance of ' + output + '%'
}
}
}
API: https://api.highcharts.com/highcharts/yAxis.stackLabels.format
API: https://api.highcharts.com/highcharts/plotOptions.series.dataLabels
Let me know if it is what you had in mind.
I would like to place 2nd series of data in the middle of the X axis (inverted line chart).
Here is the fiddle and this is the result I would like to get:
https://jsfiddle.net/r03bvcj1/
https://i.imgur.com/Irqt4hi.png
I’ve managed to get it working partially for Y axis.However Impact Tolerance line has disappeared for some reason and I would like to have it against X axis.
https://jsfiddle.net/r03bvcj1/2/
Any help/pointers will be much appraciated.
var chart;
chart= Highcharts.chart('div-impactTolerance', {
chart: {
type: 'line',
inverted: true,
events: {
load: function() {
var check = $('#div-impactTolerance').highcharts();
var min = check.yAxis[0].min;
var max = check.yAxis[0].max;
var pLine = check.yAxis[0].chart.options.yAxis[0].plotLines[0].value;
if (pLine > max) {
check.yAxis[0].setExtremes(null, pLine);
}
if (pLine < min) {
check.yAxis[0].setExtremes(pLine, null);
}
}
}
},
tooltip: {
formatter: function () {
var formatter = this.y >1 ? ' days':' day';
var header ='<span style="font-size: 10px">' + this.key + '</span><br/>';
var point = this.series.name + ': <b>' + this.y + formatter + '</b><br/>';
return header + point;
}
},
credits: {
enabled: false
},
title: {
text: 'Impact Tolerance'
},
xAxis: [{
title: {
text: "Severity"
},
gridLineWidth: 1,
categories: ['Very High','High','Medium','Low']
},
{
visible: true,
title: {
text: "T"
},
gridLineWidth: 1,
categories: [1,2,3,4],
opposite: true
},
],
yAxis: {
tickInterval: 1,
allowDecimals:false,
title: {
text: "Time (days)"
},
min: 0,
gridLineWidth: 0,
minPadding: 0.30,
plotLines: [{
color: '#FF0000',
width: 2,
value: 6,
dashStyle: 'longdashdot',
label: {
text: 'Impact Tolerance ' ,
verticalAlign: 'middle',
textAlign: 'center',
x: -15
},
}]
},
series: [
{
name: 'Scenario Testing',
states: {
hover: {
enabled: false
}
},
data: [5,7,9,11,12,14,17,18],
xAxis: 1,
lineWidth: 0,
showInLegend: true,
marker: {
radius: 10
},
threshold: 6,
negativeColor: 'green',
color: 'red',
tooltip: {
valueDecimals: 2
}
},
{
name: 'Outage Duration',
states: {
hover: {
enabled: false
}
},
data: [1,2,3,4],
xAxis: 0,
lineWidth: 0,
showInLegend: true,
marker: {
radius: 10
},
threshold: 6,
negativeColor: 'green',
color: 'red',
tooltip: {
valueDecimals: 2
}
}
]
});
Currently there are two categories on the right on one category on the left. You should adjust your data in such a way that the x value does not exceed the number of categories:
xAxis: [{
...,
categories: ['Very High', 'High', 'Medium', 'Low']
},
{
...,
categories: [1, 2, 3, 4]
},
],
...,
series: [{
...,
data: [
[0, 5],
[0, 7],
[1, 9],
[1, 11],
[2, 12],
[2, 14],
[3, 17],
[3, 18]
]
},
{
...,
data: [1, 2, 3, 4]
}
]
Live demo: https://jsfiddle.net/BlackLabel/Lhpt2zdb/
Docs: https://www.highcharts.com/docs/chart-concepts/axes
I was unsatisfied with the answer here:
Multiple y-axes for column graph categories in highcharts
I understand that you can create multiple y-axes can select them using yAxis:0,1,2 etc. for each series. Is it possible to do this for groups of bar graphs?
In the following example, I want 3 groups (Count A, Count B, Percent) each with 4 people (John, Joe, Jane, Janet). How do I do that in addition to having the count groups on one axes and the percent group on the other?
$('#container').highcharts({
chart: { type: 'column' },
xAxis: { categories: ['Count A', 'Count B', 'Percent']},
yAxis: [{ title: { text: 'Count' } }, { title: { text: 'Percent' }, opposite: true }],
series: [{
name: 'John',
data: [5, 3, 0.4],
}, {
name: 'Joe',
data: [3, 4, 0.6],
}, {
name: 'Jane',
data: [2, 5, 0.7],
}, {
name: 'Janet',
data: [3, 0, 0.8],
}]
});
So here's my solution to your problem.
I hope this is what you are looking for and I hope you find this helpful.
When you want to put the data into three categories with two different yAxis' you'd have to split it up in series like this. The percent is linked to the series with the values.
If you want it back to a column chart, just change the chart type to column.
http://jsfiddle.net/henrikskar/j1o450z5/
series: [{
name: 'John',
id: 's1',
data: [5, 3],
},{
//Links to id s1
linkedTo: 's1',
name: 'John',
data: [
//Puts 0.4 percent to the third category which is in the second array position
//of the categories
[2, 0.4]
],
//Assigns the percent to the second yAxis
yAxis: 1,
color: Highcharts.getOptions().colors[0]
},
Yes, this is absolutely possible, and you were on the right track with your research of multiple y-axes.
Below is a code snippet based on Highcharts' demo of stacked and grouped columns. I added a second y-axis and copied some of the demo data to assign to that axis.
Per your requirements, you'll find two sets, or stacks, of data assigned to the first/default y-axis, and a third set assigned to the second/opposite y-axis.
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
title: {
text: 'Total fruit consumtion, grouped by gender'
},
xAxis: {
categories: ['Apples', 'Oranges', 'Pears', 'Grapes', 'Bananas']
},
yAxis: [{
allowDecimals: false,
min: 0,
title: {
text: 'Number of fruits'
}
},{
allowDecimals: false,
min: 0, max: 100,
title: {
text: 'Percentage of fruits'
},
opposite: true
}],
tooltip: {
formatter: function () {
return '<b>' + this.x + '</b><br/>' +
this.series.name + ': ' + this.y + '<br/>' +
'Total: ' + this.point.stackTotal;
}
},
plotOptions: {
column: {
stacking: 'normal'
}
},
series: [{
name: 'John',
data: [5, 3, 4, 7, 2],
stack: 'number'
}, {
name: 'Joe',
data: [3, 4, 4, 2, 5],
stack: 'number'
}, {
name: 'Jane',
data: [2, 5, 6, 2, 1],
stack: 'number2'
}, {
name: 'Janet',
data: [3, 0, 4, 4, 3],
stack: 'number2'
},{
name: 'John',
data: [45, 30, 25, 70, 5],
stack: 'percentage',
yAxis: 1
}, {
name: 'Joe',
data: [25, 15, 40, 5, 5],
stack: 'percentage',
yAxis: 1
}, {
name: 'Jane',
data: [10, 50, 30, 5, 10],
stack: 'percentage',
yAxis: 1
}, {
name: 'Janet',
data: [20, 5, 5, 20, 80],
stack: 'percentage',
yAxis: 1
}]
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<div id="container" style="width: 600px; height: 250px; margin: 0 auto"></div>
One piece of advice: as with line charts on different axes, you need to be clear in your documentation, color choices, or chart labels so that users know which values correspond to which axis. This is particularly needed for columns, as users will naturally compare the heights of each column to its neighbor.
I hope this is helpful for you.
I have a Highcharts pie graph that I need to show multiple labels for each slice, such as an indicator (title) label with a connector on the outside of the slice, and a percentage label without connectors inside the slice.
I can set the distance property in order to bring the label (and the connector) to inside part of the slice but then, of course, there is no label outside anymore.
Any help would be greatly appreciated.
Thank you in advance.
There is no direct possibility to create multiple dataLabels. As you can see on this post, a solution would be to create two overlaying charts.
See JSFiddle here :
$(function () {
// Create the chart
$('#container').highcharts({
chart: {
type: 'pie',
backgroundColor: 'rgba(0,0,0,0)',
y:100
},
title: {
text: 'sfs '
},
yAxis: {
title: {
text: ' '
}
},
plotOptions: {
pie: {
// y:1,
shadow: false,
// center: ['50%', '50%'],
borderWidth: 0,
showInLegend: false,
size: '80%',
innerSize: '60%'
,
data: [
['allo', 18],
['asdad', 14],
['asdad', 11],
['asdasd', 10],
['adad', 8],
['asdada', 7],
['adada ada', 7],
['adad', 5],
['asdas',7],
['ada', 3]
]
}
},
tooltip: {
valueSuffix: '%'
},
series: [
{
type: 'pie',
name: 'Browser share',
dataLabels: {
color:'white',
distance: -20,
formatter: function () {
if(this.percentage!=0) return Math.round(this.percentage) + '%';
}
}
},
{
type: 'pie',
name: 'Browser share',
dataLabels: {
connectorColor: 'grey',
color:'black',
// y:-10,
softConnector: false,
connectorWidth:1,
verticalAlign:'top',
distance: 20,
formatter: function () {
if(this.percentage!=0) return this.point.name;
}
}
}
]
});
});
I want to display a small polar chart on my web site.
But there is an anoying behaviour. the container (circle) of the chart do not fit with the chart, it grow step by step. If a value is just too big, the chart will be lost in a huge empty circle.
Please, have a look on this jsfiddle to understand the problem :
http://jsfiddle.net/7zmT9/
Is it possible to force the frame to fit the chart? or to reduce the step value?
Here is my code :
$(function () {
$('#container').highcharts({
chart: {
polar: true,
height: 252,
width: 262
},
pane:{
size: '100%',
},
title: {
text: 'Highcharts Polar Chart'
},
pane: {
startAngle: 0,
endAngle: 360
},
xAxis: {
tickInterval: 45,
min: 0,
max: 360,
labels: {
formatter: function () {
return this.value + '°';
}
}
},
yAxis: {
min: 0
},
plotOptions: {
series: {
pointStart: 0,
pointInterval: 45
},
column: {
pointPadding: 0,
groupPadding: 0
}
},
series: [{
type: 'column',
name: 'Column',
data: [8, 7, 6, 5, 4, 3, 2, 20], // replace 20 by 18 to see the a more fitted chart
pointPlacement: 'between'
}, {
type: 'line',
name: 'Line',
data: [1, 2, 3, 4, 5, 6, 7, 8]
}, {
type: 'area',
name: 'Area',
data: [1, 8, 2, 7, 3, 6, 4, 5]
}]
});
});
Universal solution is to set maxPadding: 0 and sometimes endOnTick: false. See demo: http://jsfiddle.net/7zmT9/4/
yAxis: {
min: 0,
maxPadding: 0
},
You can indeed set the step, but I am not 100% sure if this is what you are looking for.
On your yAxis you can set the tickInterval
yAxis: {
min: 0,
tickInterval: 2 //change this value to suit your needs
},
I have updated your Fiddle. Is that what you are after?