Highcharts X-Axis value on top of stacked column - highcharts

I'm using some PHP loops generate a series of charts for individuals.I'm trying to place the X-Axis category point on top of my column for each point. The relavent code is:
xAxis: {
categories: [<?php echo implode(',', $year); ?>],
title: {
text: 'Year'
}
},
yAxis: [{
min: 0,
title: {
text: 'ADR'
},
stackLabels: {
enabled: true,
formatter: function() {
return '<b>' + this.x.category + '</b>';
},
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'black'
}
},
I'm unsure how to go about this i've tried this.x, this.x.category, this.x.value and so far I've not been able to get my x-axis category value. How do I do this in Highcharts?

The stack is a separate entity from the series or the point, so doesn't have direct access to the same properties.
But with a little digging, you can make the link from the stack to the x axis categories (I always just do a console.log(this) within the formatter to see what it can access...)
formatter: function() {
var x = this.x;
var cat = this.axis.chart.xAxis[0].categories[x];
return cat;
}
Example:
http://jsfiddle.net/jlbriggs/xgucespk/
You could also just define your categories array outside of the chart, and reference that array for both the categories definition, and in the formatter function.
Example:
http://jsfiddle.net/jlbriggs/xgucespk/1/

Related

Highcharts: when having multiple columns for the same X axis value, how can I get 1 tooltip per column?

I am using highcharts (StockChart) to draw a timeline of events (X axis therefore represents a datetime) and my JS knowledge is extremely basic. Each event (represented as a bar/column) has some data attached which I show in a tooltip. My timeline has multiple types of event (= series) and it can happen that there is 2 or more events of different types that happen at the exact same time. So in other words, 2 points in the plot series share the same X axis value.
My issue is that in these cases I end up with a timeline that has 2 columns but only 1 tooltip containing a merge of the 2 piece of data.
Here is how it looks like right now:
hover any column
1.7xxxx represents the first column value
3.xxx represents the second column value
To be noted as well: the "snap" point is roughly in the middle of the 2 columns (the slim white vertical bar) instead of on the column itself, which is a bit weird on a UX standpoint.
What I want is to have them split so that each column has its own tooltip floating over the column like a regular scenario.
What I want it to look like (rough sketch):
hover left column
hover right column
Here is how I handle the chart:
return function (yaxisTitle, targetId, dataHighStock) {
// Line timeline chart
// create the chart
var config = {
chart: {
renderTo: targetId,
height: 269,
type: 'column'
},
plotOptions: {
column: {
cursor: 'pointer',
pointRange: 1,
pointPlacement: "on",
pointWidth: 10
}
},
xAxis: {
type: 'datetime',
ordinal: false,
dateTimeLabelFormats: {
millisecond: '%Y-%m-%d',
second: '%H:%M:%S',
minute: '%H:%M',
hour: '%H:%M',
day: '%e. %b',
week: '%e. %b',
month: '%b \'%y',
year: '%Y'
},
minPadding: 0.05,
maxPadding: 0.05
},
yAxis: {
offset: 30,
min: 0,
title: {
text: yaxisTitle
},
labels: {
enabled: true
}
},
rangeSelector: {
inputDateFormat: '%Y-%m-%d',
inputBoxStyle: {
left: '270px',
width: '250px'
},
selected: 5
},
tooltip: {
formatter: function () {
var s = '';
var examDate = new Date(this.x);
var month = examDate.getMonth() + 1;
var day = examDate.getDate();
s = examDate.getFullYear() + "-" + (month < 10 ? '0' + month : month) + "-" + (day < 10 ? '0' + day : day) + "<br />";
$.each(this.points, function (i, point) {
s += point.y+"<br>";
});
return s;
},
snap: 1
},
legend: {
y: 20,
x: 80,
enabled: true,
align: 'left',
layout: 'horizontal',
verticalAlign: 'top',
shadow: true
},
series: dataHighStock
};
//add series to navigator
new Highcharts.StockChart(config, function (loadedChart) {
for (var i = 0; i < dataHighStock.length; i++) {
loadedChart.addSeries($.extend({}, dataHighStock[i],
{
enableMouseTracking: false,
type: "spline",
xAxis: loadedChart.xAxis.length - 1,
yAxis: loadedChart.yAxis.length - 1,
color: loadedChart.options.colors[i],
showInLegend: false
}));
}
});
};
"dataHighStock" is just a regular json I pass, which looks something like this:
[ { type: "column", name: "Event Type 1", color: "#08A5E1", data: [ { x: 1431430804000, y: 1.7153846153846155, name: '1' }] }, { type: "column", name: "Event Type 2", color: "#772971", data: [ { x: 1431430804000, y: 3.63636, name: '14915'}] }, ]
I could make the tooltip "kinda" work (= 1 tooltip per column) when I changed the Highcharts creation to be done through Highcharts.chart(...) instead of Highcharts.StockChart(...) and removing the for loop in the navigator + removing the specific data displayed in the tooltip formatter ($.each(this.points, ......){...}). The downside to that is that I lose all the features of a StockChart (time range, navigator, etc.), obviously, but also the tooltip content.
Here is a jfiddle link that reproduces all this: https://jsfiddle.net/eq3mz7y1/20/
Changing the tooltip.split into false is a solution for your issue. Notice that this solution requires some changes in your formatter callback output because the this.points array doesn't exist anymore.
Demo: https://jsfiddle.net/BlackLabel/01sqhdyv/
API: https://api.highcharts.com/highcharts/tooltip.split

HighCharts display total of stacked column in labels

I have a stacked group column graph as shown in the fiddle provided below. In the xAxis labels (red blocks), I would like to display the total of the stacked amounts subtracted from the total of the second column. For example, for "Value1" I want to display 42 in the label (100-(43+15)). Right now, I am only able to access x values, which I am returning in the formatter function (this.value). https://jsfiddle.net/er1187/n6sr0znx/
xAxis: [{
offset: -280,
tickWidth: 0,
lineWidth: 0,
categories: ['Value1', 'Value2', 'Value3'],
labels: {
x: 5,
useHTML: true,
style:{
backgroundColor: 'red',
color: 'white'
},
formatter: function () {
return this.value;
}
}
}, {
linkedTo: 0,
categories: ['Value1', 'Value2', 'Value3']
}]
In the axis formatter you dont have access to the processed data yet. However, you can access the options of series and obtain the raw data.
formatter: function () {
const axis = this.axis;
const points = axis.series.map(series =>
series.options.data[axis.categories.indexOf(this.value)]
);
return points[2] - (points[0] + points[1]);
}
example: https://jsfiddle.net/n6sr0znx/2/

How to illustrate angular data series in highcharts?

I have a data set where the series values are angles in degrees (0 to 360). Is it possible to plot a graph like the one illustrated here (ignore the green vertical line) in highcharts? Specifically, if any of the following criteria holds, the chart should avoid linking the two data points directly in the sense of passing through south (180), and should pass through north (0/360) instead:
A point is below 90 and the next one is above 270, or;
A point is above 270 and the next one is below 90.
Any help is appreciated.
What I would do to make this happen is to simply pre-process your data to create two series and then plot both of them onto the same plot. One series is for 0-179 and the other is for 180-359.
You may also want to consider a scatter plot instead of a line plot especially if your data in either of the series is not as smooth as the data in the example. Meaning that one data point is say 10 and the next one is 110 and then the next one after that is 12 or some such.
This code gives you an example, the data is provided by JSON but you should be able to just easily replace it with however your data comes in:
<script type="text/javascript">
$(document).ready(function () {
var chart = new Highcharts.Chart({
title: {
text: 'Wind Direction'
},
chart: {
renderTo: 'dataplot4',
borderWidth: 1,
defaultSeriesType: 'scatter',
zoomType: 'x'
},
legend: {
enabled: false
},
plotOptions: {
series: {
marker: {
radius: 3,
states: {
hover: {
enabled: true
}
}
}
}
},
xAxis: {
type: 'datetime'
},
yAxis: {
tickInterval: 90,
min: 0,
max: 360,
title: {
text: 'Wind Direction (deg)'
}
},
tooltip: {
crosshairs: true,
formatter: function () {
return '<b>' + Highcharts.dateFormat('%e. %b %Y, %H:00', this.x) + ' AKST</b> ' +
this.series.name + ': ' + this.y + ' deg';
}
},
series: [
{
name: 'Wind Direction',
data: JSON.parse("[" + wind_dir + "]"),
pointStart: Number(startDateTime),
pointInterval: 3600000
}
]
});
});
</script>
I'd like to think that I have a jsfiddle for this somewhere, will update the answer when I dig it up.
EDIT: Here's a fiddle that shows the scatter plot in action. http://jsfiddle.net/Reality_Extractor/pNFYL/

Dual Axis in Highstock?

Is there any way to make a Dual Axis in Highstock like this one on Highcharts?
http://www.highcharts.com/demo/combo-dual-axes
It looks like you can do it the same way as in highcharts. Each series specifies yAxis:n where n is the axis you want to plot it against, and you need to define n yAxis entries. I modified one of the example highstock demos: http://jsfiddle.net/ykfmG/
$.getJSON('http://www.highcharts.com/samples/data/jsonp.php?filename='+ name.toLowerCase() +'-c.json&callback=?', function(data) {
seriesOptions[i] = {
name: name,
data: data,
yAxis:i
};
}
yAxis: [{
labels: {
formatter: function() {
return (this.value > 0 ? '+' : '') + this.value + '%';
}
},
plotLines: [{
value: 0,
width: 2,
color: 'silver'
}]
},{opposite:true},{opposite:true},{opposite:true}],

highchart not displaying bars chart while printing

I am new to highchart and am using it to render bar chart on my webpage. But the chart is not getting displayed while printing. Only the X and Y axis is printing with values but not the bars on it.
I am using IE8. The bar chart is visible(on print) in IE8 mode but its not visible in IE8 Compatible mode. I need to make it work on IE default mode i.e. IE8 compat. mode.
Can anyone help me in this issue.
I am adding a code chunk of my js function where I am printing my highchart in a lightbox window.
var chart = new Highcharts.Chart({
chart: {
renderTo: 'containerDivID',
type: 'column'
},
title: {
text: ''
},
xAxis: {
categories: xDataValues
},
yAxis: {
min: 0,
title: {
text: ''
}
},
tooltip: {
formatter: function() {
return ''+
this.x +': '+ this.y +' kr';
}
},
plotOptions: {
column: {
stacking: 'normal',
borderWidth: 1,
dataLabels: {
enabled: false,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
}
}
}
,
yAxis: {
labels: {
formatter: function() {
return this.value;
}
},
title:{
text: ''
}
},
series: [
{
name: 'YAxis',
color: '#37789F',
data: yDataValues
}
],
credits:{
enabled: false
}
});
In this lightbox I have a print button on pressing this button I am calling window.print() to print the page. On my print page I can see the y and x axis and there data but cannot see my bar charts. But If I change IE8 mode from Compatible to IE8 standard mode then I can see my chart on printing.
Regards,
Andi
For me I didn't use the print() function to print the chart as I need to print extra data with the chart; As my chart is part of a report.
kindly find the custom print function I wrote:
function printReport() {
w = window.open();
var svg = myChart.getSVG();
//clone the div you want to print which contains your chart
var toprint = $('#bs-results') .clone();
//replace the chart with the svg
toprint.find('#graph_div').html(svg);
//right the output to print it
w.document.write(toprint.html());
w.print();
w.close();
}
Please take look at compatibility page http://www.highcharts.com/documentation/compatibility, we support native browser but not compatibility mode.

Resources