I am trying to use Highcharts to generate our website's availability information.
The Y axis is availability in percentage, the expected labels are:
[100, 99.9, 99, 90, 0]
code:
http://jsfiddle.net/2E9vF/1/
$(function () {
$('#container').highcharts({
chart: {
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: {
title: {
text: "AVAILABILITY %"
},
labels: {
formatter: function() {
return 100-this.value;
}
},
type: 'logarithmic',
reversed:true,
min:0.01,
plotLines: [{
color: '#CCCCCC',
width: 2,
value: 0.1,
dashStyle: 'ShortDot'
},{
color: 'red',
width: 2,
value: 1,
dashStyle: 'ShortDot'
},{
color: '#CCCCCCC',
width: 2,
value: 10,
dashStyle: 'ShortDot'
}],
},
tooltip: {
formatter: function() {
return 'x:'+ this.x +'<br>'+
'y:'+ (100-this.y);
}
},
series: [{
// real data:
// [90, 98, 99.7, 100, 100, 99.9, 99.7, 90, 91, 98, 96, 97.3]
data: [10, 2, 0.3, 0, 0, 0.1, 0.3, 10, 9, 2, 4, 2.7]
}]
});
});
However, I have two issues that I need help with:
I cannot draw 100 in the y axis
Orginal data with value 100 cannot be shown in the chart
Here is the expected chart:
http://www.shareimage.ro/images/0j1o0bnccavkqds8icuy.jpg
In general negative numbers and zero-based are not supported, but you can workaround this: http://jsfiddle.net/2E9vF/2/
In steps:
Assume that value 0 will be represented as other one, for example 0.001 (or lower)
Set min for yAxis to that value
Update formatters for tooltip and yAxis.labels accordingly:
tooltip: {
formatter: function() {
if(this.y === 0.001) {
return 'x:'+ this.x +'<br>'+ 'y:100';
} else {
return 'x:'+ this.x +'<br>'+ 'y:'+ (100-this.y);
}
}
},
And:
yAxis: {
labels: {
formatter: function() {
if(this.isFirst) {
return 100;
}
return 100-this.value;
}
}
}
Related
A smoother line is needed (the line should rise smoothly and evenly), but the values should not change. Is it possible to build a more straight line without changing the values?
Screen with explanations: http://prntscr.com/qudf96
And my code:
<script>
function reDrawCalc(gdata, gcurr, nums = 2) {
Highcharts.chart('container', {
chart: {
height: 400,
type: 'area',
margin: [20, 0, 20, 0]
},
title: {
text: null
},
subtitle: {
text: null
},
exporting: {
enabled: false
},
xAxis: {
gridLineWidth: 1,
categories: ['One', 'Two', 'Three', 'Four', 'Five']
},
yAxis: {
gridLineWidth: 0,
},
tooltip: {
enabled: false,
crosshairs: true
},
plotOptions: {
series: {
dataLabels: {
enabled: true,
useHTML: true,
inside: false,
style: {
fontFamily: 'Rubik, sans-serif',
textTransform: 'uppercase',
fontSize: 'none',
fontWeight: 'normal',
textShadow: 'none'
},
formatter: function() {
return '<div class="chitem-time">'+ this.x+'</div>'
+'<div class="chitem-val">'+ Highcharts.numberFormat(this.y,nums)+'<sup>'+gcurr+'</sup></div>';
}
}
}
},
series: [{
type: 'areaspline',
data: gdata,
lineWidth: 5,
color: '#f0c997',
fillColor:'transparent'
}],
responsive: {
rules: [{
condition: {
maxWidth: 500
},
chartOptions: {
chart: {
height: 350,
type: 'area',
margin: [20, 0, 20, 0]
},
series: [{
type: 'areaspline',
data: gdata,
lineWidth: 3,
color: '#f0c997',
fillColor:'transparent'
}],
}
}]
}
});
}
</script>
Is it possible to do it? And how to modify my code for it?
Thank you very much in advance!
As I mentioned in the comment current line shape is at it is because of the points positions on the chart. If you don't need to keep points actual positions the solution which you can use is to use the dummy data for the points and use the correct one in the dataLabels. See:
Demo: https://jsfiddle.net/BlackLabel/fshx3n50/
data: [{
y: 5,
z: 0.20
}, {
y: 10,
z: 1.40
}, {
y: 18,
z: 6.20
}, {
y: 30,
z: 18.00
}, {
y: 50,
z: 73.00
}],
I also changed the formatter function to display the z value in dataLabel:
formatter: function() {
return '<div class="chitem-time">' + this.x + '</div>' +
'<div class="chitem-val">' + Highcharts.numberFormat(this.point.z) + '<sup>REM</sup></div>';
}
I have one last issue to solve with my chart. I have a variable number of colums for each month of the year. What I am trying to do is to assign each column with a set colour. I have read and tried so many ways without success.
My code.
$(function () {
var colors = ['#999999', '#009900', '#FF6600', '#CC0000', '#FF0000'],
colorIterator = 0;
var chart;
$(document).ready(function() {
$.getJSON("../charts/1-2-4-overall_year_chart.php", function(json) {
chart = new Highcharts.Chart({
chart: {
renderTo: 'container1',
type: 'column',
marginRight: 130,
marginBottom: 25,
events:{
load:function() {
var chart = this,
series = chart.series,
each = Highcharts.each;
each(series, function(serie, i) {
each(serie.data, function(data, j) {
data.update({
color: colors[colorIterator]
},false);
colorIterator++;
});
});
chart.redraw();
}
}
},
title: {
text: 'Monthly trend',
x: -20 //center
},
subtitle: {
text: '',
x: -20
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: {
endOnTick: false,
max:11,
showFirstLabel: false,
lineColor:'#999',
lineWidth:1,
tickColor:'#666',
tickWidth:1,
tickLength:2,
tickInterval: 10,
gridLineColor:'#ddd',
title: {
text: 'Count',
style: {
fontFamily: 'Tahoma',
color: '#000000',
fontWeight: 'bold',
fontSize: '8px'
}
},
zIndex: 10,
label: {
text: 'Maximum %',
align: 'center',
x: -10,
y: -10,
style: {
color: '#FF0000'
}
}
},
credits: {
enabled: false
},
tooltip: {
formatter: function() {
return '<b>'+ this.series.name +'</b><br/>'+
this.x +': '+ this.y;
}
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'top',
x: -10,
y: 100,
borderWidth: 1
},
plotOptions: {
column: {
colorByPoint: true
},
series: {
cursor: 'pointer',
pointWidth: 6,
point: {
events: {
//click: function() {
//location.href = "feedback-items_detractors_iframe.php?FromDate1=<?php echo $StartDate;?>&ToDate1=<?php echo $EndDate;?> target='iframe2'";
//}
}
},
legendIndex:0,
dataLabels: {
enabled: true,
color: '#000000',
align: 'center',
cursor: 'pointer',
borderRadius: 5,
backgroundColor: 'rgba(252, 255, 255, 255)',
borderWidth: 1,
borderColor: '#AAA',
y: -6,
format: '{y:.1f}', // one decimal
y: -20, // 10 pixels down from the top
style: {
textShadow: false,
fontSize: '8px',
fontFamily: 'Verdana, sans-serif'
}
}
}
},
series: json,
});
});
});
$('#resizer').resizable({
// On resize, set the chart size to that of the
// resizer minus padding. If your chart has a lot of data or other
// content, the redrawing might be slow. In that case, we recommend
// that you use the 'stop' event instead of 'resize'.
resize: function () {
chart.setSize(
this.offsetWidth - 20,
this.offsetHeight - 20,
false
);
}
});
});
This is what I am trying to do
If anyone has any idea how this is done it would be very helpful.
Thank you in advance for your time.
Configure colorByPoint option true and set the color sequence that you want.
options = {
chart: {...},
plotOptions: {
column: {
colorByPoint: true
}
},
colors: [
// set colors
]
}
Example fiddle: http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/plotoptions/column-colorbypoint-true/
just solved the issue by using colors: [ '#333333','#009900','#FF6600','#CC0000','#FF0000' ], plotOptions: { column: { colorByPoint: false },
I am trying to plot multiple column graphs on the same chart, stacked on each other. This is an example of desired output.
Each colored column segment represents percent of team to have reached a given level by the end of the given month. So it's like 4 separate column charts stacked. I think this is different than grouped and stacked, but may be mistaken.
Thanks for any feedback.
This can be done with a combination of stacked and column range. There are a few caveats with this in that you have to have a category for your yAxis which causes some funkiness with how you set your series' data values. I opted for one method and I am sure there are others. What I did was first set the chart type to 'columnrange':
chart: {
type: 'columnrange'
},
Then I set up the yAxis properties to use categories:
yAxis: {
categories: ['Level 0', 'Level 1', 'Level 2', 'Level 3'],
Since the offset of the category is in-between the tick marks of the axis I removed them and set the start position to not be on the tick:
startOnTick: false,
min: .5,
gridLineWidth: 0,
Up next I have to set the format of the labels (essentially just hiding the first label):
labels: {
formatter: function() {
var label = this.axis.defaultLabelFormatter.call(this);
if (!this.isFirst) {
return label;
}
}
},
Now I create plotLines to mimic the gridlines with the last one a different color to denote the "Target":
plotLines: [{
color: '#e6e6e6',
width: 1,
value: 1
}, {
color: '#e6e6e6',
width: 1,
value: 2
}, {
color: 'red',
width: 2,
value: 3,
label: {
text: 'Target'
}
}]
Now I setup the plotOptions for this chart. Note that the stacking parameter is not listed in the API as being part of the columnrange type but it still functions (as of this answer using v5.0):
plotOptions: {
columnrange: {
stacking: true
}
},
Okay, almost there. I then set up the series data:
series: [{
name: 's1',
data: [
[0, .64],
[0, .9],
[0, 1]
]
}, {
name: 's2',
data: [
[null, null],
[1, 1.1],
[1.0, 1.5]
]
}, {
name: 's3',
data: [
[null, null],
[null, null],
[2.0, 2.5]
]
}]
The important part of the data values is that each "level" is a whole integer such that Level 1 is from 0 to 1 and Level 2 is from 1 to 2 and Level 3 is from 2 to 3. This works out good as you try to determine your percentage in each level for each month as they are still in uniform increments.
I did not modify the tooltip as you gave no specs on that.
Sample jsFiddle and full code:
$(function() {
Highcharts.chart('container', {
chart: {
type: 'columnrange'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: {
categories: ['Level 0', 'Level 1', 'Level 2', 'Level 3'],
startOnTick: false,
min: .5,
gridLineWidth: 0,
title: {
text: null
},
labels: {
formatter: function() {
var label = this.axis.defaultLabelFormatter.call(this);
if (!this.isFirst) {
return label;
}
}
},
plotLines: [{
color: '#e6e6e6',
width: 1,
value: 1
}, {
color: '#e6e6e6',
width: 1,
value: 2
}, {
color: 'red',
width: 2,
value: 3,
label: {
text: 'Target'
}
}]
},
plotOptions: {
columnrange: {
stacking: true
}
},
legend: {
enabled: true
},
series: [{
name: 's1',
data: [
[0, .64],
[0, .9],
[0, 1]
]
}, {
name: 's2',
data: [
[null, null],
[1, 1.1],
[1.0, 1.5]
]
}, {
name: 's3',
data: [
[null, null],
[null, null],
[2.0, 2.5]
]
}]
});
});
I have a graph with a labelled Y-Axis with points 1 through 100. In addition to the regularly spaced labels (0, 10, 20, etc), I want to add a label for an arbitrary point, say 47. Is this possible with highcharts?
You can add a specific line to the yAxis with the plotLines option.
yAxis: {
plotLines: [{
value: 47,
color: 'rgb(216, 216, 216)',
width: 1,
}]
},
http://jsfiddle.net/nicholasduffy/wa6ukyyp/1/
EDIT:
This seems a bit of a hack, but you could fake the label.
yAxis: {
plotLines: [{
value: 47,
color: 'rgb(216, 216, 216)',
width: 1,
label : {
text: '47',
x: -30,
y: 2
}
}]
},
http://jsfiddle.net/nicholasduffy/wa6ukyyp/2/
Based on your comment, you can add a custom tick with tickPositioner function, with a code like this
$(function () {
$('#container').highcharts({
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: {
tickInterval: 20, //sets the interval ticks
tickPositioner: function(){
var ticks = this.tickPositions; // gets the tick positions
ticks.push(47); // adds the custom tick
ticks.sort(function(a, b) {
return a - b; // sorts numerically the ticks
});
return ticks; // returns the new ticks
}
},
series: [{
data: [29.9, 71.5, 86.4, 29.2, 44.0, 76.0, 93.5, 98.5, 16.4, 94.1, 95.6, 54.4]
}]
});
});
JSFiddle demo
I think the solution I found that comes closest is to create a line of zero thickness and label the line:
plotLines: [{
value: cutoff,
color: 'rgb(216, 216, 216)',
width: 0,
label: {
text: 'label_name',
style: {
color: 'grey',
fontweight: 'bold'
}
}
}],
The label_name goes pretty close to the Y-Axis, and it gets the point across without putting a tooltip onto the graph
For this.x, I am getting the index location when I push the data in via code. If I populate the data separately, like the following code, then this.x returns the right item. How can I fix this issue?
Works
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 54.4]
}]
Index location is getting pushed out for this.x here
var points = [{
Name: 'good',
Y: '15000'
}, {
Name: 'baad',
Y: '3000'
}, {
Name: 'wow',
Y: '2000'
}];
var chartData = {
GetChartSeries: function (points, name) {
var seriesData = [];
if (points != null && points != 'undefined') {
for (i=0; i<points.length; i++) {
seriesData.push({
name: ""+points[i].Name,
y: parseFloat(points[i].Y)
//,color: ''
});
}
}
return seriesData;
}
};
$(function () {
$('#container').highcharts({
chart: {
type: 'column',
margin: [ 50, 50, 100, 80],
borderColor: '#A4A4A4',
borderRadius: 5,
borderWidth: 2
},
legend: {
enabled: false
},
title: {
text: 'Graduation Year Breakdown'
},
colors: ['#790000'],
legend: {
enabled: false
},
plotOptions: {
series: {
/*
dataLabels: {
enabled: true,
color: 'red'
},
*/
borderRadius: 3,
colorByPoint: true
}
},
tooltip: {
formatter: function() {
return '<b>'+ Highcharts.numberFormat(this.y, 0) +'</b><br/>'+
'in year: '+ this.x;
}
},
xAxis: {
categories: [],
labels: {
rotation: -45,
align: 'right',
style: {
fontSize: '13px',
fontFamily: 'Verdana, sans-serif'
}
}
},
yAxis: {
min: 0,
title: {
text: 'Number of Students'
}
},
series: [{
//name: 'Population',
data: chartData.GetChartSeries(points, ""),//[4000, 3400, 2000, 34000, 120000],
dataLabels: {
enabled: true,
//rotation: -90,
color: '#4F4F4F',
align: 'center',//'right',
//x: 4,
//y: 10,
style: {
fontSize: '12px',
//fontWeight: 'bold',
fontFamily: 'Verdana, sans-serif'
}
}
}]
});
});
While I am uncertain as to why your solution doesn't work, I can propose an alternative solution.
The tooltip formatter function has access to a number of different parameters. Instead of this.x, you could use this.point.name.
For example:
formatter: function() {
// If you want to see what is available in the formatter, you can
// examine the `this` variable.
// console.log(this);
return '<b>'+ Highcharts.numberFormat(this.y, 0) +'</b><br/>'+
'in year: '+ this.point.name;
}