Highcharts, custom formatting for labels - xAxis - highcharts

I've just encountered a problem I could not find solution for, so that's the cause of my post.
I am using:
xAxis: {
gridLineWidth: 0,
type: 'datetime',
labels: {
useHTML: true,
formatter: function() {
return '<div class="labels" style="margin-top:20px;font-family:Open Sans;">' + $charts.convert_label_time(this.value) + '</div>';
}
}
},
After AJAX call labels are going to disappear and the "DIV" ('.highcharts-axis-labels') that is related to them is removed.
The cause of this reaction is - Adding dynamically series using
chart.addSeries();
Any tips?

Related

Show only first and last xAxis label in Highcharts

I would like to display only the first and the last label on my xAxis. This would give enough of a »frame« for the user. However, I don't succeed in it. I am working with a synchronized chart, which can be found here. Is the second and third »column« of (smaller) graphs, I am targeting at.
I tried to work with »startOnTick« and »endOnTick«, but it won't do it.
xAxis: {
crosshair: true,
events: {
setExtremes: syncExtremes
},
visible: i === 1,
showFirstlabel: true,
showLastlabel: true,
startOnTick: true,
endOnTick: true,
labels: {
step: 500,
format: '{value}'
}
},
What is the correct way to force Highcharts to display only first and last label?
Here is a short fiddle (don't know why the line does not appear; it shows the values with mouseover...).
Thanks for any hints.
You can use the xAxis.labels.formatter callback to show wanted ticks:
Demo: https://jsfiddle.net/BlackLabel/m2Ln8sdg/
xAxis: {
tickAmount: 10,
labels: {
formatter() {
if(this.isFirst || this.isLast) {
return this.value
} else {
return ''
}
}
}
},
API: https://api.highcharts.com/highcharts/xAxis.labels.formatter
If you want to have more control about it (like hide label and tick) you can use the load callback method and proper logic to hide/show ticks:
Demo: https://jsfiddle.net/BlackLabel/fbcdskmv/
chart: {
events: {
load() {
let chart = this;
for (let i in chart.xAxis[0].ticks) {
//hide all
chart.xAxis[0].ticks[i].label.hide()
chart.xAxis[0].ticks[i].mark.hide()
// show first and last tick
if (chart.xAxis[0].ticks[i].isFirst || chart.xAxis[0].ticks[i].isLast) {
chart.xAxis[0].ticks[i].mark.show()
chart.xAxis[0].ticks[i].label.show()
}
}
}
}
API: https://api.highcharts.com/highcharts/chart.events.load
Or use the tickPositioner callback to achieve it: https://api.highcharts.com/highcharts/xAxis.tickPositioner
The above answers are good, but i just wanted to show another approach which works just fine.
In my styling i do this;
.highcharts-xaxis-labels > text:not(:first-child):not(:last-child) {
visibility: hidden !important;
}
Summing up #luftikus143 and #Sebastian Wędzel comments:
const data = [
['Jan 2020', 167],
['Feb 2020', 170],
['Mar 2020', 172]
];
xAxis: {
type: 'category',
tickPositions: [0, data.length - 1]
}
Will output only the first and last labels. #martinethyl's workaround answer might need some extra tweaks specially if you have multiple data points. Suggestions (might not work well with smaller media types):
xAxis: {
type: 'category',
labels: {
rotation: 0,
x: 5, // Optional: moves labels along the x-axis
style: {
textOverflow: 'none', // Removes ellipsis
whiteSpace: 'nowrap', // Gets the label text in one line
},
},

In Highcharts drilldown charts, Custom Formatting of X-Axis label displays the label with underline even in the last level

I have a chart drawn using Highcharts API, which has two series and multiple levels of data shown using DrillDown feature of the API. When i tend to modify the default Axis label format using formatting property and by setting useHTML 'true', the labels are displayed with underline even in the last level which is not the expected behaviour.
xAxis: {
type: 'category',
labels: {
rotation: -45,
formatter: function (e) {
return '<div class="chartXAxisLabel" title="' + this.value + '" ><span>' + this.value + '</span></div>';
},
useHTML: true
},
title: {
enabled: true,
align: 'high'
}
},
The issue could be seen in the below fiddle link.
http://jsfiddle.net/6LXVQ/418/
I find it odd that only adding/removing useHTML: true causes this problem by itself. The formatter does not need to be involved (as shown in this minimal example).
I found that adding this minimal code fixes the problem (JSFiddle example with your code):
xAxis: {
labels: {
useHTML: true,
style: {
"text-decoration": "none"
}
}
}
I'm not exactly sure why, but it removes the underline from the span element that is causing it.

D3.js tooltips not displaying correctlty when generated with Highcharts

I want to make some tooltips visible in my d3 map. The tooltips are column charts generated by Highcharts regarding the chosen city. The trick is that everything is displaying correctly (axis, labels ...) except that the columns are not visible!
Here my d3 code (only the relevant parts):
var tooltip = d3.select("body")
.append("div")
.attr("id","tooltip")
.style("position", "absolute")
.style("visibility", "hidden");
cities.on("mouseover", function(d, i) {
d3.select(this).style('fill', '#95a5a6');
tooltip.html(zoomCityComm(d))
return tooltip.style("visibility", "visible")})
.on("mousemove", function(d, i){
return tooltip.style("top", (d3.event.pageY - 130) + "px").style("left",(d3.event.pageX - 120) + "px");
})
}
The function zoomCityComm is HighCharts (example of data: [5,10]):
function zoomCityComm(d) {
chart = new Highcharts.Chart({
chart : {
renderTo: 'tooltip',
type: 'column',
width:200,
height:200,
plotBackgroundColor: '#FCFFC5',
zoomType: 'xy'
},
title: {
text: "TOTO"
},
legend: {
enabled: false
},
xAxis: {
categories: ['In','Out']
},
yAxis: {
title: {
text: 'Sum',
style: {
color: '#4572A7'
}
},
labels: {
style: {
color: '#4572A7'
}
},
},
series:[{color: '#4572A7',data: res}]
});
return document.getElementById("tooltip").innerHTML;
}
When the graph is displayed in a "normal" div within the document, it appears correctly.
Sorry if my explanations are not clear but ask me for some details if needed.
Thanks
Cyril
You're setting the HTML content of the div twice, as highcharts renders it itself. In your mouseover handler function, it is enough to do
zoomCityComm(d);
instead of
tooltip.html(zoomCityComm(d));
For the interested, here's what's happening. Setting the HTML of the tooltip div from the return value of the function captures the first animation frame that highchart uses to grow the bars. As it is the first frame, the height of the bars is still 0 -- that is, the bars are there, but not visible because they have essentially no height. Replacing the HTML of the div means that the animation won't work anymore, as the elements that would be animated have been replaced.

Highcharts - tooltip / yaxis zindex issue

The issue I am having is that the tooltip on my line graph for the first few points is behind the values on the Y-Axis. I assume this is just a z-index issue between the tooltips and yaxis.
I wasnt sure the correct way to fix this issue, if there was some option I should use or is this something that needs to be addressed CSS.
This issue did not start happening until I changed the yaxis to use HTML. Maybe is it caused by my formatting?
yAxis: {
labels: {
useHTML:true,
formatter: function() {
var amount = this.value;
if(this.value > 0 ){
return '<span class="format_positive">' + amount + '</span>';
} else {
return '<span class="format_negative">' + '(' + amount + ')' + '</span>'
}
}},
alternateGridColor: '#F5F5F5',
minorTickInterval: 'auto',
lineWidth: 1,
tickWidth: 1,
title:{ text: 'Total Amounts'}
}

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/

Resources