Highcharts label format with tickPositioner in a datetime x Axis - highcharts

In my chart ,I try to display only 5 ticks in a datetime axis, I use the tickPositioner function and set only 5 ticks ,this work perfect but the data labels loss it's format and show only numbers.
I use the formatter function but i need a grouping labels for the zoom.

It's little hacky, but you need also calculate information about labels and add them, for example: http://jsfiddle.net/AVhaL/
tickPositioner: function (min, max) {
var ticks = this.getLinearTickPositions(this.tickInterval, min, max),
tLen = ticks.length;
ticks.info = {
unitName: "week",
higherRanks: {},
totalRange: ticks[tLen - 1] - ticks[0]
};
return ticks;
}
So according to totalRange, you need to pass unitName - it's information which format should be taken from dateTimeLabelFormats.

You only need format label, after put ticks.
Options.xAxis.tickPositioner = function () {
const ticks = this.series[0].xData;
let result = [];
for (let index = 0; index < ticks.length; index++) {
result.push(ticks[index]);
}
return result;
};
and format xAxis
labels: {
format: "{value:%b-%Y}",
align: "center"
}
to tooltips
tooltip: {
valueSuffix: "",
valuePrefix: "",
xDateFormat: "%B - %Y",
valueDecimals: 0
},

Related

Highcharts Stock Chart - Custom X axis date times format

I'm wondering if it's possible to define a custom ordering or format for the xAxis in stock highcharts. My dataset has a date time which would be used for the xAxis however my client has specified that it should show in the middle T-0 on the xAxis. Rest of them from the left side should be like -3m -2m -1m and from the right side +1m +2m +3m(In case of year timeframe).
Example for 1 year timeframe
I have tried using formatter function on xAxis labels. However I can not figure out how to get the middle tick first and then start chaging labels to the left and to the right from that middle position tick.
If the formatting, amount and interval of the labels is static, you can use variables from outside of the chart.
For example:
const labels = [];
let labelIndex = 0;
for (let i = -6; i < 7; i++) {
labels.push(i);
}
Highcharts.stockChart('container', {
xAxis: {
...,
labels: {
formatter: function() {
labelIndex++;
if (this.isFirst) {
labelIndex = 0;
}
const label = labels[labelIndex];
if (label < 0) {
return label + 'm';
} else if (label === 0) {
return 'T-' + label;
}
return '+' + label + 'm';
}
}
},
...
});
Live demo: http://jsfiddle.net/BlackLabel/L7uy29kw/
API Reference: https://api.highcharts.com/highstock/xAxis

Highcharts : Show ticker on the start of plot

How show Ticker from the start of plot along with the label value?
I want the ticker to start at the plot and also show the correct value.
I set pointStart to start of the x-axis value.
When I set startOnTick to true. And for know tickIntervalto 30 minutes. (tickInterval varies based on the data interval)
this is what I get.
Any way to show the ticker at the start of the plot.
Use the tickPositioner function, for example:
xAxis: {
type: 'datetime',
startOnTick: true,
labels: {
formatter: function() {
return Highcharts.dateFormat('%k:%M', this.value);
}
},
tickPositioner: function() {
var ticks = [],
dataMin = this.dataMin,
dataMax = this.dataMax,
tickInterval = (dataMax - dataMin) / 5;
for (var i = this.dataMin; i <= this.dataMax; i += tickInterval) {
ticks.push(i);
}
return ticks;
}
}
Live demo: http://jsfiddle.net/BlackLabel/aswzfrnc/
API Reference:
https://api.highcharts.com/highcharts/xAxis.tickPositioner
https://api.highcharts.com/class-reference/Highcharts#.dateFormat

Highcharts - Stack Graph Display Average of all values

I am using highcharts for statistical data displaying. I want to display , on the stack label , the average of all the values .
Below is what i am doing but i cant seem to get it right :
yAxis: {
min: 0,
title: {
text: 'Task'
},
stackLabels: {
style: {
color: 'black'
},
enabled: true,
formatter: function() {
return (this.axis.series[1].yData[this.x]).toPrecision(2) + '%';
}
}
},
The above only takes the last value on the stack and shows the percentage. For instance , if the last value is 50 , the above displays 50% as the stack value . I want to take an average of all the values. Any help would be appreciated.
If you want to show any stack's percentage mean if your stacked column has two stack A-5 and B-10 , then the % of B in column is 66% and % of A is 33%. If you want to show that use following in formatter function ( refer This Fiddle Link)
formatter: function() {
return (this.axis.series[1].yData[this.x] / this.total * 100).toPrecision(2) + '%';
}
Updating as per OP 's comment Refer Working fiddle here
Use following code : Make your data in a variable and calculate the sum
var seriesData = [{
name: 'Incomplete',
data: [1, 3, 4, 7, 20]
}, {
name: 'Complete',
data: [3, 4, 4, 2, 5]
}];
var total = 0;
$.each(seriesData,function(item){
$.each(seriesData[item].data,function() {
total += this;
});
});
And then use following in stacklabel formatter :
formatter: function() {
return ( this.total/ total * 100).toPrecision(2) + '%';
}
series:seriesData
hope it helps :)
This doesn't seem to be as easy as it should be.
I would accomplish this by pre-processing the data to generate an array of averages, and then referencing that array from the stackLabels formatter function.
Example, build the averages (assumes array 'data' with sub array for each series data values):
var sum = 0;
var averages = [];
var dataLen = data.length;
$.each(data[0], function(x, point) {
sum = 0;
for(var i = 0; i < dataLen; i++) {
sum += data[i][x];
}
averages.push(sum/dataLen);
})
And then in the formatter:
yAxis : {
stackLabels: {
enabled: true,
formatter: function() {
return Highcharts.numberFormat(averages[this.x],2);
}
}
}
Example:
http://jsfiddle.net/jlbriggs/vatdrecb/
If I could find a way to get a reliable count of the points in each stack, you could just use
return this.total/countOfPoints;
in the formatter without needing to build an array, but I can't seem to reliably get that count.

Set navigator min zoom

I'm trying to set the min zoom (max range) of my chart. Basically I'm trying to do the opposite of the minRange property. I'm struggling for a while with this problem. I have a "solution", but I don't like it, this solution allow the user to choose a range greater then the "max range", and immediately correct it.
POSSIBLE SOLUTION
$(function() {
var lastMin;
var lastMax;
var maxRange = 12 * 30 * 24 * 3600 * 1000; //12 month
$('#container').highcharts('StockChart', {
scrollbar: {
liveRedraw: false
},
xAxis: {
events: {
afterSetExtremes: function(e) {
var max = this.max,
min = this.min;
if (lastMin && lastMax) {
if(max-min > maxRange) {
if (min < lastMin) {
min = max - maxRange;
} else {
max = min + maxRange;
}
}
}
var x = this;
setTimeout(function(){
x.setExtremes(min,max); //chart xAxis
}, 1);
lastMin = min;
lastMax = max;
}
}
},
rangeSelector: {
selected: 1
},
series: [{
name: 'USD to EUR',
data: usdeur
}]
});
});
I want to block the user from choosing a range greater than the allowed, in other words, block the navigator when it's too big
I'm also following this issue, I tried all the proposed solution, but I'm having errors ("Uncaught ReferenceError: Highcharts is not defined")
Thanks Sebastian!
I managed to find a solution (fiddle) wrapping the "render" function. Doing that I managed to really set a "min zoom" on the navigator bar.
$(function() {
var lastX0;
var lastX1;
var maxRange = 100; //100 pixels
(function (H) {
H.wrap(H.Scroller.prototype, 'render', function (proceed) {
console.log(arguments)
if(arguments[4] - arguments[3] > maxRange + 2) {
if (arguments[3] < lastX0) {
arguments[3] = lastX0;
} else {
arguments[4] = lastX1;
}
}
proceed.apply(this, [].slice.call(arguments, 1));
lastX0 = arguments[3];
lastX1 = arguments[4];
});
}(Highcharts));
$('#container').highcharts('StockChart', {
scrollbar: {
liveRedraw: true
},
series: [{
name: 'USD to EUR',
data: usdeur
}]
});
var highchart = $('#container').highcharts();
var extremes = highchart.xAxis[0].getExtremes();
var rangeTotal = extremes.max - extremes.min;
var f = maxRange / $('#container').width();
highchart.xAxis[0].setExtremes(extremes.max - (f * rangeTotal), extremes.max);
});
In the sample code I'm used a fixed amount of pixels, but in my real application i'm making it dynamic. I making this, because I can't use the data grouping property in the software that I'm working, and since the minimum size of a bar in a chart is 1 pixel (obviously) highcharts hide some bars (or points).
I'm setting the minimum zoom so all bar in the displayed range are visible , since the user can't display a higher range in the x Axis the "hidden" bar "problem" (is an awesome feature, but I can't make use of it) won't happen

Change first tick label on yAxis

I need change first tick label on yAxis. I changed the minimum value on the yAxis:
yAxis: [{
title : {
text : 'Position'
},
gridLineWidth: 1,
startOnTick: false,
min: 1, //changed min value
reversed: true,
}]
but the value is not shown in front yAxis. How to sign the first value in the yAxis?
Here's my chart.
if I write:
yAxis: [{
title : {
text : 'Позиция'
},
startOnTick: false,
showFirstLabel: true,
min: 1,
reversed: true,
tickInterval: 1,
labels: {
formatter: function() {
if (this.value < 1)
return null;
else if (this.value == 1)
return this.value;
else if (this.value % 2 == 0)
return this.value;
}
}
}]
then scaling yAxis turns bad for my data :( chart
You can define your own yAxis.tickPositioner to define all positions where you wish a tick should be placed.
Since in your case you don't want to override the entire behavior, but just place a tick at the min position, you can leverage the axis.getLinearTickPositions(interval, min, max) method to get the array of default positions that would be otherwise generate, and then append your additional ticks to this array.
The code below has ticks added on both the min and max of the y-axis
yAxis: {
showFirstLabel: true,
showLastLabel: true,
tickPositioner: function(min, max) {
// specify an interval for ticks or use max and min to get the interval
var interval = Math.round((max - min) / 5);
var dataMin = this.dataMin;
var dataMax = this.dataMax;
// push the min value at beginning of array
var positions = [dataMin];
var defaultPositions = this.getLinearTickPositions(interval, dataMin, max);
//push all other values that fall between min and max
for (var i = 0; i < defaultPositions.length; i++) {
if (defaultPositions[i] > dataMin && defaultPositions[i] < dataMax) {
positions.push(defaultPositions[i]);
}
}
// push the max value at the end of the array
positions.push(dataMax);
return positions;
}
}
Show tick on min and max of y axis | Highchart & Highstock # jsFiddle
Demo of your chart # jsFiddle
For me it seems everything is working fine. The minimum value of your reversed chart is 1, which is right on top of the y-Axis. However if you want to show this value on the axis, have a look at this post for a description.

Resources