Highcharts put null values at maximum y position? - javascript

Setting a maximum of 100 for the y axis, any data point above 100 renders like the below screen shot. With the point being outside of the chart. Mouse hover still displays a tooltip showing the y position, in this screen shot it is 150 with a max y axis of 100.
I am setting null values for points, and connecting null values. Is it possible to reformat a null value and place it outside the chart or at the very least at the maximum y position? Below the null value would be May, is it possible to put this null value at the very top of the chart at the 100 line while keeping the value null?

You could preprocess the data to set your null values to a high number and then add a tooltip formatter to display null for thoes values:
var data = [29.9, 45, 90.4, 29.2, 80.0, null, 24.6, null, 10, 12, 95.6, 54.4];
data = $.map(data, function (n) {
if (n == null) return 150;
else return n;
});
$('#container').highcharts({
chart: {},
tooltip: {
formatter: function () {
if (this.y >= 100) return this.x + ':';
else return this.x + ':' + this.y;
}
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: {
max: 100
},
series: [{
data: data
}]
});

Related

Set chart options when printing and add a footer

So I'm relatively new to highcharts, but I'd like to be able to take a chart and when we set it to print, which i've made the only available option, have the graphic be resized larger, increase the spacingBottom or maybe change the plot size, essentially i need to make space on the bottom and then add a label in this space.
I've figured out how to do the resize, and add the label with the events beforePrint() and afterPrint(), but the changing of the spacing on the bottom still eludes me. I've searched through the questions here, but all seem to be targeted at exporting, which I also tried, believing they were related, and they might be? I tried using the exporting.chartOptions, but that only seems to affect exporting and does nothing when we choose to print.
Thanks for any direction or help you can give.
$(function () {
$('#container').highcharts({
chart: {
type: 'column',
events: {
beforePrint: function() {
this.resetParms = [this.chartWidth, this.chartHeight, false];
this.setSize(600,400,false);
/*eventually if I ever get this to work this is how I'd add the text.*/
//this.myText = this.renderer.text('this is a test',10,350 ).add();
},
afterPrint: function() {
this.setSize.apply(this,this.resetParms);
/*if(this.myText) {
this.myText.destroy();
}*/
Highcharts.charts.forEach(function (chart) {
if (chart !== undefined) {
chart.reflow();
}
});
}
}
},
title: {
text: 'Hours'
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
yAxis: {
allowDecimals: false,
min: 0,
title: {
text: 'Number of Hours'
}
},
tooltip: {
formatter: function () {
return '<b>' + this.x + '</b><br/>' +
this.series.name + ': ' + this.y + '<br/>' +
'Total: ' + this.point.stackTotal;
}
},
plotOptions: {
column: {
stacking: 'normal'
}
},
exporting:{
buttons: {
contextButton:{
menuItems: null,
onclick: function () {
this.print();
}
}
}
},
series: [{
name: 'PY Admin',
data: [5, 3, 4, 7, 2,3,4,5,6,7,8,12],
color: '#85C1E9',
stack:'lyear'
}]
});
});
http://jsfiddle.net/cajmrn/jkv6jbh0/3/
Have you tried to update bottomSpacing property with the Chart.update() function on the beforePrint event? If yes, and it did not work, use update without redraw (second argument to false) and redraw chart without animation:
this.update({
chart: {
spacingBottom: 200
}
}, false);
this.redraw(false);
You could also, instead of setting spacing, set a new chart height minus the spacing you want to apply.
API Reference:
http://api.highcharts.com/highcharts/Chart.update
http://api.highcharts.com/highcharts/Chart.redraw
http://api.highcharts.com/highcharts/chart.spacingBottom
Examples:
http://jsfiddle.net/20r1z3kg/ - updating spacing
http://jsfiddle.net/xp0m4nbh/ - changing chart height with setSize()

Change Datalabel Color, Rotation and Align values based on Column value in highcharts

Possible duplicate of Unsolved highcharts datalabel dynamic rotation as column height
The Fiddle for a sample column chart : http://jsfiddle.net/Yrygy/266/
There are some very large columns, and one very small column. I want to show white labels vertically rotated to -90 degrees in the large columns, and for smaller columns, I want to display dark gray labels on the top of the column, with 0 degree rotation.
After some messing up, I have achieved this : http://jsfiddle.net/Yrygy/267/
I can change the color of the label based on the value in the formatter function, but using global variables to get the align and rotation right are not working.
Any help in this regard would be very helpful. I cannot use the solutions suggested in the duplicate question, as I need to keep the Y axis uniform and cannot set MinPointLength.
Final Code:
var GlobalRotation = -90;
var GlobalAlign = 'right';
var X;
var Y;
$(function () {
$('#container').highcharts({
chart: {
type: 'column',
height: 700
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
},
plotOptions: {
column: {
stacking: 'normal',
pointPadding: 0,
groupPadding: 0.2,
dataLabels: {
enabled: true,
inside: false,
style: {
fontWeight: 'bold'
},
formatter: function() {
var max = this.series.yAxis.max,
color = this.y / max < 0.05 ? 'black' : 'white';
//GlobalRotation = this.y / max < 0.05 ? 0 : -90;
//GlobalAlign = this.y / max < 0.05 ? 'left' : 'right';
//X = this.y / max < 0.05 ? 4 : 4;
//Y = this.y / max < 0.05 ? 0 : 5;
return '<span style="color: ' + color + '">' + this.y + ' </span>';
},
verticalAlign: "top",
rotation : GlobalRotation,
align: GlobalAlign
}
}
},
series: [{
data: [29.9, 71.5, 106.4, 129.2, 144.0, 176.0, 135.6, 148.5, 216.4, 194.1, 95.6, 2.33]
}]
});
});
You can change Highcharts.Series.prototype.drawDataLabels, the function to draw the dataLabels:
Highcharts.Series.prototype.drawDataLabels = (function (func) {
return function () {
func.apply(this, arguments);
if (this.options.dataLabels.enabled || this._hasPointLabels) realignLabels(this);
};
}(Highcharts.Series.prototype.drawDataLabels));
realignLabels would be the function to check for the shorter columns, and in it change the rotation, x and y of that specific dataLabel:
function realignLabels(serie) {
$.each(serie.points, function (j, point) {
if (!point.dataLabel) return true;
var max = serie.yAxis.max,
labely = point.dataLabel.attr('y'),
labelx = point.dataLabel.attr('x');
if (point.y / max < 0.05) {
point.dataLabel.attr({
y: labely - 20,
x: labelx + 5,
rotation: 0
});
}
});
};
http://jsfiddle.net/Yrygy/270/

Making y axis of highcharts in time format hh:mm

I need to put in y-axis time format hh:mm, for example y-axis should have 16:00,32:00 and etc. ticks or smth simmilar.
I've been working with highcharts - I'm new with JS and web-programming.
I have my data in miliseconds and convert it to hh:mm format, but when I have miliseconds more than 86400000 (24 hours) it shows me next date and I need it to be still displayed in hours:minutes format. Is there any way to do it? I've tried to change y-axis from type: 'datetime' to type: 'time', but it didn't help me alot.
Here is jsfiddle example of my charts and bellow you can find just js-code.
$(function () {
$('#container').highcharts({
chart: {
type: 'column'
},
xAxis: {
categories: [
'Jan',
'Feb',
'Mar',
'Apr',
'May',
'Jun',
'Jul',
'Aug',
'Sep',
'Oct',
'Nov',
'Dec'
]
},
yAxis: {
title: {
text: 'Time (hh:mm)'
},
type: 'datetime',
dateTimeLabelFormats: {
hour: '%H:%M'
}
},
plotOptions: {
column: {
pointPadding: 0.2,
borderWidth: 0
}
},
series: [{
name: 'Tokyo',
data: [0, 0, 0, 0, 76320000, 25920000, 102840000, 0, 0, 0, 0, 0]
}]
});
});
So here is the answer that I've got if anyone need it (here is the link to jsfiddle).
I set the time variables in ms:
data: [0, 0, 0, 0, 76320000, 25920000, 102840000, 0, 0, 0, 0, 0]
And then I format this value as I need:
yAxis: {
title: {
text: 'Time (hh:mm)'
},
labels: {
formatter: function () {
var time = this.value;
var hours1=parseInt(time/3600000);
var mins1=parseInt((parseInt(time%3600000))/60000);
return hours1 + ':' + mins1;
}
}
}
That's the only way I found to make y axis in pure hh:mm format. Also you can make the data not in ms, but in w/e you want or need.
then better use your own formatting method, here you will have more control on formatting. you can use formatter as shown below.
yAxis: {
labels: {
formatter: function () {
//get the timestamp
var time = this.value;
//now manipulate the timestamp as you wan using data functions
}
}
}
hope this will help you in achieving what you needed.

Highcharts min y-axis value

Is it possible to set a min y-axis value when the series values are the same?
For example:
http://jsfiddle.net/6hyfk/1/
I would like to see 0.00019 as y-axis value.
If i change it to:
series: [{
data: [0.00019,0.00020,0.00019,0.00019]
}]
it looks a lot better.
So the answer largely depends on your data. If for example, you know your values are all positive, setting a yAxis min helps your data display a bit better. You know your data better than I, so I'd look at the yAxis settings and see what you can change to get a better result, but for example, this is a JSFiddle that sets a minimum value:
$(function () {
$('#container').highcharts({
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
tickLength: 20
},
yAxis: {
min: 0
},
series: [{
data: [0.00019,0.00019,0.00019,0.00019]
}]
});
});
http://jsfiddle.net/gTG2z/
You can manually set the min and max on the X axis.
yAxis:{
min: 0,
max: .001
},
http://jsfiddle.net/6hyfk/2/
If you know what range is in your series, you can set accordingly minRange, so Highcharts will render more ticks as expected. For example: http://jsfiddle.net/Fusher/6hyfk/3/ Good thing about minRange is that it will work also for another values like that: http://jsfiddle.net/Fusher/6hyfk/5/
Probably,you don't need to hardcode min,max values.Do calculation for min and max and set to y Axis as shown below,
$(function () {
yMin = Math.min.apply(Math,data); // Find Min
yMax = Math.max.apply(Math,data); //Find Max
$('#container').highcharts({
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
},
yAxis: {
min: yMin,
max: yMax
},
series: [{
data: data //Array of values
}]
});
});

Highchart - change color of one x-axis label only

So I know how to change the color of x-axis labels in Highchart, which is described here.
http://jsfiddle.net/gh/get/jquery/1.7.1/highslide-software/highcharts.com/tree/master/samples/highcharts/xaxis/labels-style/
But what if I want to change the color of just ONE label, not all the labels? How do I apply style to individual labels?
You can also use the label-formatter to set the style. Full example on jsfiddle:
labels: {
formatter: function () {
if ('Jun' === this.value) {
return '<span style="fill: red;">' + this.value + '</span>';
} else {
return this.value;
}
}
}
I understood that you want to change the color for a specific item inside the x-axis.
I looked at the API but i didn't found an easy way to do it.
Since you can set a callback for the "chart ready event":
Chart (Object options, Function callback) :
Parameters
options: Object The chart options, as documented under the heading
"The options object" in the left menu.
callback: Function
A function to execute when the chart object is finished loading and rendering. In
most cases the chart is built in one thread, but in Internet Explorer
version 8 or less the chart is sometimes initiated before the document
is ready, and in these cases the chart object will not be finished
directly after calling new Highcharts.Chart(). As a consequence, code
that relies on the newly built Chart object should always run in the
callback. Defining a chart.event.load handler is equivalent.
Returns: A reference to the created Chart object.
You can do it in a dirty way:
$(function () {
var chart = new Highcharts.Chart({
chart: {
renderTo: 'container',
marginBottom: 80
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
labels: {
style: {
color: 'red'
}
}
},
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]
}]
},
function(c){
// this relies in that te xAxis is before the yAxis
// also, setting the color with color: #ABCDEA didn't work
// you have to use fill.
$(".highcharts-axis:first text").each(function(i, label){
var $label = $(label);
if($label.children().text() === "Jun") {
$label.css({fill: "blue"});
}
});
// You also can to something like:
$(".highcharts-axis:first text:eq(6)").css({fill: "green"});
})
});​
Hope this helps you
Note that when you use the highcharts exporting server at exporting.highcharts.com to render images for your graphs, javascript formatters will not be executed.
Fortunately highcharts translates some html tags and style attributes of individual label and title strings into equivalent SVG styling, but it is quite finicky about how it parses the html. It will strip tags that are using single quoted attributes, you need to use double quotes. Also, nesting a <br/> tag inside another tag will not work.
So if you want two lines of text colored red for example, you get:
<span style="color: #ff0000">First line</span> <br/>
<span style="color: #ff0000">Second line</span>
I am using dataLabels in a doughnut pie chart. I wanted to change the label text colors for individual pie slices, based on conditional logic, comparing values.
Just sharing because my search brought me here.
data: outerData,
dataLabels: {
formatter:
function () {
if ((outerData[this.point.x].y > innerData[this.point.x].y) && (this.point.x != 0)) {
return this.y > 0.1 ? '<span style="fill: red;">' + this.point.name + ': ' + this.y + '% ' + '</span>' : null;
} else {
return this.y > 0.1 ? '<span style="fill: #006400;">' + this.point.name + ': ' + this.y + '% ' + '</span>' : null;
}
}
}
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
labels: {
formatter: function () {
if ('Jan' === this.value) {
return '<span style="fill: blue;">' + this.value + '</span>';
} else {
return this.value;
}
}
}
},

Categories