Highchart pie - datalabel cannot be selected when setting useHTML=true - highcharts

when i set useHTML=true on pie datalabels the labels are not respond to mouse hover and not show tooltip
http://jsfiddle.net/wh4mw0o7/
$(function () {
$('#container').highcharts({
chart: {},
plotOptions: {
pie: {
dataLabels: {
useHTML:true, // <- THE PROBLEM !!!!!
}
}
},
series: [{
type: 'pie',
data: [
['AAA', 10],
['BBB', 20],
['CCC', 15]
]
}]
});
});
do some one know how to fix it ?
i use html in the labels(different sizing and colors so i must use html as label).

See the http://www.highcharts.com/docs/chart-concepts/labels-and-string-formatting
and paragraph "The downsides are that it will always be laid out on top of all other SVG content, and that it is not rendered the same way in exported charts." It means that HTML elements are below SVG, which keeps events.
Related topic: https://github.com/highslide-software/highcharts.com/issues/2158
EDIT:
$.each(chart.series[0].data, function (i, d) {
$('.highcharts-data-labels div span').eq(i).mouseover(function (e) {
chart.tooltip.refresh(d);
});
});
Workaround: http://jsfiddle.net/wh4mw0o7/6/

As a solution you can call the covering of each part of your pie chart.
dataLabels: {
useHTML:true, // Make our labels HTML
formatter: function() { // Wrap the text of each label with a span tag
// Id of the span is equal to 'label-<Name of your label>'
return "<span id='label-" + this.point.name+ "'>" +
this.point.name + // And draw the label itself inside the span
"</span>";
}
}
Below the your chart options write event handlers:
// On the hover event of each label we can manually call the hover of
// each segment of your pie chart
$('#label-AAA').hover(
// When the mouse pointer enters the label, make it hovered and show its tooltip
function() {
// data[0] - AAA segment of the chart
mychart.series[0].data[0].setState('hover');
// Refresh the tooltip of this segment
mychart.tooltip.refresh(mychart.series[0].points[0]);
},
function() { // When the mouse pointer leaves the label
mychart.tooltip.hide();
});
For each label the code is same. The disadvantage of this approach is that you have to know all labels names in advance. Here is JSFiddle: http://jsfiddle.net/wh4mw0o7/4/

Related

Center title of chart relative to the plot background

I would like to center the title of a pie chart relative to the plot background (not the element containing the chart), so that if there is a legend next to the char the title is still centered relative to the pie.
Using
title: {
text: 'Title',
align: 'center'
}
centers the title relative to the containing element.
See this fiddle for the full example.
Is it possible somehow?
You can position the title in the render event, for example:
chart: {
...,
events: {
render: function() {
var seriesGroupBBox = this.seriesGroup.getBBox();
this.title.attr({
x: seriesGroupBBox.x + seriesGroupBBox.width / 2 - this.title.getBBox().width / 2
});
}
}
}
Live demo: https://jsfiddle.net/BlackLabel/6a9sroe7/
API Reference: https://api.highcharts.com/highcharts/chart.events.render

High charts bar chart label overlaps with the graph when labels are long

I need the xAxis label to have a tool tip. But when I use a formatter to add the tool tip , then long labels tend to overlap with the chart instead of pushing it to the right. Also this only happens if the label has a white space , if white spaces are removed then it work properly and pushes the chart to the right. This problem is shown in this fiddle: http://jsfiddle.net/W5wag/44
$(function(){
var chart1;
$(document).ready(function(){
var options = {
chart: {
renderTo: 'container',
type: 'bar'
},
xAxis: {
categories: ['cat1aaaaaaaaaaaaaaaasadadadad adadaaaaaaaaaaaaaaaaaaaaa', 'cat2', 'cat3', 'cat4', 'cat5'],
labels: {
formatter: function() {
return '<span title="abc">' + this.value + '</span>';
},
useHTML: true,
style: {
whiteSpace: 'nowrap'
}
},
},
};
options.series = [{
data: [3, 4, 4, 3, 9]
}];
chart1 = new Highcharts.Chart(options);
});
})
I tried to execute some code after the labels have been rendered, but my experience is a bit limited there. I'd try to find the maximum width of any of the x-axis labels, set that as the min-width of the parent (as below), and invalidate the labels to trigger a redraw. Maybe you can find a way to do that.
If all else fails, you could "cheat" with these quick-n-dirty solutions:
Set the text without spaces, and add them afterwards, when the layout is done.
window.setTimeout(()=>document.querySelector('span[title=abc]')
.innerHTML='cat1aaaaaaaaaaaaaaaasadadad adadadaaaaaaaaaaaaaaaaaaaaa', 500);
Or, add css to the page (which requires knowing how wide the labels will be, though):
.highcharts-axis-labels.highcharts-xaxis-labels > * { min-width: XXXpx }

Highstock, split tooltip and opposite xAxis?

I'm displaying the x-axis of my Highstock chart at the top of the chart area with xAxis: { opposite: true}.
However the tooltip continues to show the x-axis value at the bottom of the chart, see for example here http://jsfiddle.net/ckj7kf2y/
Is there any way I can change the positioning of this be at the top, close to the x-axis?
Bonus points if someone knows why the tooltip.positioner callback isn't called when tooltip: { split: true }
It's possible to wrap core code to add this feature like in this demo: http://jsfiddle.net/ygmbwxtx/
(function(H){
H.wrap(H.Tooltip.prototype, 'renderSplit', function (proceed) {
proceed.apply(this, [].slice.call(arguments, 1));
var tooltip = this,
topAxis = tooltip.options.topAxis,
axisTT = tooltip.tt,
top = tooltip.chart.plotTop;
if (topAxis) {
axisTT.attr({
y: top - axisTT.height,
anchorY: top + 10
});
}
});
}(Highcharts))
and in chart's options:
...
tooltip: {
split: true,
topAxis: true
...
Bonus: positioner is not used for split tooltip - split uses own logic for positioning

Refresh highchart after hiding bar data

How do I hide the bar data by clicking the bar and refresh the chart? I would like to have almost the same functionality as clicking on the legend.
Jsfiddle: https://jsfiddle.net/Nadiyaka/005z7dut/1/
For example, if I click on 'Asia' bar, I want the data to become hidden and the chart to be reloaded to see other data bigger.
So far I'm able only to hide the data, but the chart isn't refreshing:
series: [{
data: [1052, 954, 4250, 740, 38],
events: {
click: function(e) {
var chart = $("#container").highcharts();
index = event.point.x;
chart.series[0].data[index].graphic.hide();
chart.series[0].data[index].dataLabel.hide();
}
}
}]
There is no option for hiding points (except the points in pie series), but you can achieve the same effect by setting the point's value to null.
events: {
click: function(e) {
var point = e.point;
point.series.chart.pointer.reset(false); // this is needed to prevent the tooltip from moving around
point.update({
y: null,
holdY: point.y // I preserve original value needed on showing
});
}
}
For showing the columns, attach events to labels
load: function() {
var chart = this,
points = this.series[0].data;
points.forEach(function(point) {
chart.xAxis[0].ticks[point.x].label.on('click', function() {
if (point.y === null) {
point.update({
y: point.holdY
});
}
});
});
}
example: https://jsfiddle.net/005z7dut/2/

Add tooltip to legend in highcharts when hovering

Id like to let the user know that he can remove items from the legend by simply clicking on them. To some, this may be intuitive but others may not know that they can do that. I would like to let the users know when they over the legend item that then can click to remove it.
I am using the GWT-wrapper class for highcharts.
Thank you.
Highcharts doesn't have built-in tooltip for item legend, but still you can create your own tooltip for that. It's simple to add custom events to legendItem (mouseover and mouseout for example) and show that tooltip.
See example how to add events to elements in Highcharts: http://jsfiddle.net/rAsRP/129/
events: {
load: function () {
var chart = this,
legend = chart.legend;
for (var i = 0, len = legend.allItems.length; i < len; i++) {
(function(i) {
var item = legend.allItems[i].legendItem;
item.on('mouseover', function (e) {
//show custom tooltip here
console.log("mouseover" + i);
}).on('mouseout', function (e) {
//hide tooltip
console.log("mouseout" + i);
});
})(i);
}
}
}
There is another opportunity to get tooltips at hovering over the Highcharts legend. You just need to enable useHTML for the legend and redefine the labelFormatter function; this function should return the label text enclosed into the "span" tag. In this "span" tag one may include a class to apply jQuery-based tooltips (jQuery UI or Bootstrap for example). Also it is possible to transfer some data (for example, the index of a legend item) using the 'data-xxx' attribute:
labelFormatter: function () {
return '<span class="abc" data-index="' + this.index + '">' + this.name + '</span>';
}
Tooltips can be formatted as you wish; hyperlinks are also possible. The fiddle is here.
Although there're great answers already, I still want to share my simplified solution (inspired by the answers provided above).
If you just need a plain text tooltip, you can use title attribute of <span> (W3 School, title attribute - most often shown as a tooltip text when the mouse moves over the element.) No jQuery setup is needed then.
In your Highcharts options object set legend.useHTML: true & configure legend.labelFormatter:
legend: {
enabled: true,
useHTML: true,
labelFormatter: function () {
// if legendTooltip set, put it into title attr
if (this.options.custom && this.options.custom.legendTooltip) {
return '<span title="' + this.options.custom.legendTooltip + '">' + this.name + '</span>';
}
return '<span>' + this.name + '</span>';
}
},
And add custom.legendTooltip to the options object of a series you want a tooltip for:
series: [{
name: 'counter',
data: [110, 50, 130],
custom: {
// provide a tooltip text here:
legendTooltip: "Counter custom tooltip"
}
}]
(using custom obj is recommended by Highcharts)
Also see the JS fiddle: http://jsfiddle.net/uhocybpj/8/
You can do that.
At first, Highcharts has callback function.
https://stackoverflow.com/a/16191017
And modified version Tipsy can show tooltip in SVG.
http://bl.ocks.org/ilyabo/1373263
*Use jquery.tipsy.js and tipsy.css on this page.
Then, start highcharts like this.
$('#your-chart').highcharts(your_chart_options,function(chart){
$('#your-chart').find('.highcharts-legend-item').each(function(){
// set title text example
var _text = $(this).text(),
_title = '';
switch(_text){
case "legend 1":
_title = 'legend 1 title';
break;
case "legend 2":
_title = 'legend 2 title';
break;
}
// add <title> tag to legend item
$(this).append($('<title></title>').text(_title));
});
$('#your-chart').find(".highcharts-legend-item").tipsy({
gravity: 's',
fade: true
})
});

Resources