Highcharts - append % to first axis label? - highcharts

When styling a chart axis, a common style in publications is to include the unit or percentage sign only on the topmost label of the Y-axis. I am trying to figure out how to do this in Highcharts.
I know I can hard-code a number, like this:
yAxis: {
labels: {
formatter: function() {
if ( this.value == 12 ) {
return this.value + "%";
} else {
return this.value;
}
}
},
But this is not a very flexible solution.
Is there a way to test for the first (or nth) value displayed? Is there a way to get the index of a value within the formatter function?
2013 Update
This works in most circumstances:
if ( this.value == this.axis.getExtremes().max )
return this.value + '%';
else
return this.value;
However, it does not work if you have yAxis.endOnTick set to false—because in that case the maximum value of the axis is not the same as the highest label on the axis.
Is there a way to get that highest label from within the formatter function?

As far as I know, it isn't possible to find the 'nth' item on an axis, but first and last can be dome using the properties this.isFirst and this.isLast' in stead of checkingthis.value`
If you want to, you can also access the axis itself directly using this.axis, so you should be able to run whatever complex logic you want on the axis itself..

With 4.2.x version of highchart I have achieved it with following code
labels: {
formatter: function () {
if(this.isFirst)
return this.value + "%";
else
return this.value;
}
}
}

You could also add [%] to the name of the yAxis. Then you wouldn't have to tamper with the ticks.

You can draw at max value plotLine and after extremes are changed - remove and add new one). Then label for that plotLine you can set as '%' and move to the left side.
Another solution is to use axis title - set it to top and remove rotation.
The last solutions (or rather workaround) is to use second yAxis, and set there min and max(or tickPositions), and show only last label, and first hide.

Related

Amcharts 4, xychart, limiting the number of tooltips and combining infos in one tooltip

I am using amcharts 4 to display temperature lines. At times there are many stations so I would like to have just one tooltip and just for the value the cursor is at instead of one tooltip for every line (because then they overlap and some are unreadable).
And there might be several stations with the same temperature so I would have to list all of them in the tooltip.
Anyone knows how to achieve that?
In amcharts 3 I used a balloonFunction attached to the graphs to create my own tooltip. But yet I couldn't find how to do it with the series in amcharts 4.
Thanks for a hint!
So as David Liang mentioned, since all the data items converge along their x axis value (a datetime in this case), you can limit tooltips down to one by only setting one series' tooltipText, and it will have access to the rest of the data fields via data placeholders. E.g. even though series1's value field is E852_t4m, it can use series30's value by just putting "{median_tBel}".
But if you want to have a tooltip based on which line you're hovering over, how to do that depends whether or not you require the Chart Cursor.
If you don't need it, simply set the tooltipText on the line's bullets, e.g.
series1.bullets.getIndex(0).tooltipText = "{name} {valueY}°C";
Here's a demo of your fiddle with that:
https://codepen.io/team/amcharts/pen/803515896cf9df42310ecb7d8d7a2fb7
But if you require Chart Cursor, unfortunately there isn't a supported option at the moment. There's a kind of workaround but it's not the best experience. You start with doing the above. The Chart Cursor will trigger hover effects on all lines and their bullets, including triggering their tooltips. A bullet's tooltip is actually its series' (series1.bulletsContainer.children.getIndex(0).tooltip === series1.tooltip). If we remove the reference to the bullet's tooltip, e.g. series1.bullets.getIndex(0).tooltip = undefined;, the chart will check up the chain and refer to series' anyway. If we do the same to the series' tooltip, it'll go up the chain to chart.tooltip, if we do this to all series, we basically turn chart.tooltip into a singleton behavior of sorts. But it's not as responsive to mouseovers.
You'll see what I mean with this demo:
https://codepen.io/team/amcharts/pen/244ced223fe647ad6df889836da695a8
Oh, also in the above, you'll have to adjust the chart's tooltip to appear on the left/right of bullets with this:
chart.tooltip.pointerOrientation = "horizontal";
Edit:
Since the first method sufficed, I've updated it with an adapter that checks for other fields in range. In the adapter, the target will be the CircleBullet, target.dataItem.valueY is the currently hovered value, and target.dataItem.dataContext are the other fields at the same date.
This is how I modified tooltipText to show other series within +/-0.5C range of the currently-hovered bullet:
// Provide a range of values for determining what you'll consider to be an "overlap"
// (instead of checking neighboring x/y coords.)
function inRange(valueA, rangeA, rangeB) {
return valueA >= rangeA && valueA <= rangeB;
}
// Provide adapters for tooltipText so we can modify them on the fly
chart.series.each(function(series) {
series.bullets
.getIndex(0)
.adapter.add("tooltipText", function(tooltipText, target) {
// the other data fields will already match on the date/x axis, so skip
// the date and this bullet's data fields.
// (target.dataItem.component is the target's series.)
var skipFields = ["date", target.dataItem.component.dataFields.valueY];
// this bullet's value
var hoveredValue = target.dataItem.valueY;
// all the other data fields at this date
var data = target.dataItem.dataContext;
// flag for adding additional text before listing other nearby bullet values
var otherPoints = false;
Object.keys(target.dataItem.dataContext).forEach(function(field) {
// if the field is neither date, nor bullet's
if (!~skipFields.indexOf(field)) {
if (inRange(data[field], hoveredValue - 0.5, hoveredValue + 0.5)) {
if (!otherPoints) {
tooltipText += "\n\nOthers:";
otherPoints = true;
}
// Keep {data placeholder} notation to retain chart formatting features
tooltipText += "\n" + field + ": {" + field + "}°C";
}
}
});
return tooltipText;
});
});
If your series' data points have different x values, it's impossible to combine all the information into one tooltip.
But if they do have same x values, you can just turn on the tooltip for just one of the series:
...,
series: [{
type: "LineSeries",
tooltipHTML: `xxx`,
...
}, {
type: "LineSeries",
...
}, {
type: "LineSeries",
...
}],
...
And within the tooltip HTML, you have access to the data:
...,
tooltipHTML: `
<strong>Year: </strong>{year}<br />
<strong>Cars: </strong>{cars}<br />
<strong>Motorcycles: </strong>{motorcycles}<br />
<strong>Bicycles: </strong>{bicycles}
`,
...
demo: http://jsfiddle.net/davidliang2008/aq9Laaew/286519/

Highcharts: Show navigator range in subtitle

I have a small problem (i hope it is small) with highcharts.
My target is, to show the chosen min/max range from the navigation to the subtitle.
But I have no idea how to do this.
Here a sample picture
Any ideas?
You could use the chart.render event to achieve this in the following way:
chart: {
events: {
render: function(){
this.setSubtitle(
{text:
'<b>From:</b> ' +
(new Date(this.xAxis[0].getExtremes().userMin).toLocaleString()) +
' <b>To: </b>' +
(new Date(this.xAxis[0].getExtremes().userMax).toLocaleString())
}
)
}
}
},
This will give you a min/max when the chart is loaded, and when user selects their interval.
The timeformat can be changed of course, I used .toLocaleString() because it is easy.
Working example: http://jsfiddle.net/ewolden/37bp1qpc/
API reference: https://api.highcharts.com/highstock/chart.events.render

Highcharts: Tooltip on a single series only

I have 3 datasets within my series (low, normal, high) displaying on a scatter plot.
How can I force the tooltip and markers to be enabled only for the normal data set?
Many thanks
formatter: Function
Callback function to format the text of the tooltip. Return false to disable tooltip for a specific point on series.
Reference:
http://api.highcharts.com/highcharts#tooltip.formatter
See shared tooltip formatter. It gives you better control over the tooltip.
http://api.highcharts.com/highcharts#tooltip
EDIT: I have added some code. See the custom tooltip formatter;
tooltip: {
formatter: function () {
if (this.series.name == "Male") {
return "<b>" + this.series.name + "</b><br>" + this.x + " cm, " + this.y + " kg";
} else return " ";
}
}
See the fiddle for example: http://jsfiddle.net/androdify/cweC6/
This solution is for keeping tooltips on all series, but only display one tooltip at a time corresponding to the point actually hovered over.
Look through the code for where it is specifying a variable by the name of hoverPoints and change it to this:
{hoverPoint:l,hoverSeries:b,hoverPoints:l?[l]:[]}
This is the code for Highstock, so if you are using vanilla Highcharts you may need to change variable names around a bit. To explain how this works, the default value for hoverpoints is an array of all points on that spot on the x axis. Changing it to an array containing the single point that you actually hovered over, the value of hoverPoint, causes highcharts to ignore the other hit points.

Highcharts - line chart dataLabels on every other point?

I have a Highcharts line graph that has dataLabels configured in the plotOptions. This is all working well and I have a nice label displayed over each point.
plotOptions: {
line: {
dataLabels: {
enabled: true,
formatter: function() {
return '$' + Highcharts.numberFormat(Math.round(this.y),0,0,",");
}
}
}
}
However, is there a way to set an interval that determines how often the dataLabels appear over the points? I want to show every point in my graph, but due to space constraints, only show the dataLabel every 2 or 3 points.
Edit:
Difficulty level: My graph has multiple y-axes, uses datetime for the x-axis, and has irregular data.
http://jsfiddle.net/SQkMW/68/
Yes, you could just return a blank string if the point x mod 2 is 0, for every 2nd to show up, for example (http://jsfiddle.net/HzYtV/):
formatter: function() {
if(this.point.x % 2 == 0) return '';
return this.y +'mm';
}
For datetime axis you will have to create a variable and increment it manually http://jsfiddle.net/SQkMW/69/

Axis Label centered in highchart

I have a custom chart here
I have set label property as
labels: {
formatter: function() {
return Highcharts.dateFormat('%Y', this.value);
},
align:'center',
x:150
}
I have a linked axis which shows year.
What I want is the axis label should be in center of the two extremes as in image.
what I have done now is, I have given x:150 to label.but that wont work if I resize the browser window.
Is there a way to do it?
Thanks in advance.
Here is the way I found it.
Instead of using static values,
I used useHTML, and positioned labels by CSS styles.
labels: {
useHTML:true,
formatter: function() {
return '<span class="label">'+Highcharts.dateFormat('%Y', this.value)+'</span>';
}
}
Simple example here

Resources