amCharts 4: display legend tooltip on truncated (with ellipsis) values only - tooltip

I've enabled the legend on a amCharts v4 chart with the following code but I have issues with ellipsis:
// Add legend
chart.legend = new am4charts.Legend();
chart.legend.fontSize = 11;
// Truncate long labels (more than 160px)
chart.legend.labels.template.maxWidth = 160;
chart.legend.labels.template.truncate = true;
chart.legend.labels.template.fullWords = true;
// Set custom ellipsis as default one is not displayed correctly
chart.legend.labels.template.ellipsis = "...";
// Set tooltip content to name field
chart.legend.itemContainers.template.tooltipText = "{name}";
As you can see I had to set a custom ellipsis property because Firefox v76 displayed €| instead of … on the truncated legend labels. It happens even on the sample on the amChart website but, surprisingly, not if I open the same URL in a private tab... How can I fix that?
Then I would like to display the tooltip on the legend only for truncated labels. Adding an adapter:
chart.legend.itemContainers.template.adapter.add("tooltipText", function(text, target) {
// 'text' here contains the non-truncated string
return "My modified " + text;
})
of course works, but how can I identify inside the adapter code if the label that I'm processing is truncated and clear the text variable? It doesn't make sense to display tooltips for non-truncated legend items.

Not sure the most ideal way but...
You get the text inside the adaptor callback.
You can add a text.length check like:
chart.legend.itemContainers.template.adapter.add("tooltipText", function(text, target) {
// 'text' here contains the non-truncated string
return text.length > someValyeBasedOnMaxwidth> ? "My modified " + text: "";
})

I found the answer about the tooltip adapter; this works:
chart.legend.itemContainers.template.adapter.add("tooltipText", function(text, target) {
if (!target.dataItem.label.isOversized) {
// Legend label is NOT truncated, disable the tooltip
return "";
}
// Legend label is truncated, display the tooltip
return text;
})
Still I don't know why the ellipsis are not displayed correctly without setting the property...

Related

AmCharts 4 tooltip negtive and positive color of single LineSeries

https://www.amcharts.com/demos/date-based-line-chart/
In above have a LineSeries Chart with positive and negative values with different line colors but tooltip have only negative value color.
Can this possible to have positive line have different color of tooltip and negtive have another tooltip color?
Yes, it's totally possible.
Firstly, to adjust the background color of a tooltip, you'll need to kill its default behavior of grabbing color information from the calling object (in this case it gets the fill from the series). That's done via:
series.tooltip.getFillFromObject = false;
Then to adjust the background:
series.tooltip.background.fill = // color here
To switch its background color based on the value it's showing, one way we can do that is use an adapter for the series' tooltipText, because when that triggers we know the tooltip is being shown and/or changing. In there we can detect the current dataItem being sourced, check the value, and adjust the tooltip's background fill accordingly.
Sample code:
series.tooltip.getFillFromObject = false;
series.tooltip.background.fill = "blue";
series.adapter.add("tooltipText", function(tooltipText) {
if (series.tooltipDataItem.dataContext.visits < 0) {
series.tooltip.background.fill = "red";
} else {
series.tooltip.background.fill = "blue";
}
return tooltipText;
});
Demo:
https://codepen.io/team/amcharts/pen/913514e19a189c8779e07ffcae861ce3

Highcharts - resize legend on chart resize?

Is there anyway to dynamically set a specific width of legend items when resizing the chart? I have some really long item names possible in the legend so I need to specify a width to force the text to wrap, but I would like to change the width when the width the chart changes. Thanks.
I found a better work around for this:
chart.legend.options.width = newwidth;
chart.legend.itemStyle.width = newwidth;
for(var index in this.chart.series) {
chart.legend.destroyItem(chart.series[index]);
}
chart.legend.render()
Generally it is not possible, but you can disable highcharts legend, and prepare your own div (positioned absolutely) which will include list of all series and click event. Simple example is available here
$legend = $('#customLegend');
$.each(chart.series[0].data, function (j, data) {
$legend.append('<div class="item"><div class="symbol" style="background-color:'+data.color+'"></div><div class="serieName" id="">' + data.name + '</div></div>');
});
$('#customLegend .item').click(function(){
var inx = $(this).index(),
point = chart.series[0].data[inx];
if(point.visible)
point.setVisible(false);
else
point.setVisible(true);
});
http://jsfiddle.net/N3KAC/10/
Than only what you need is adapt this to your chart by catching $(window).resize() function and resize element.

Remove datalabels from formatter with Highchart

I'm using the highchart library and try to display some datalabels with a dinamic format ( using the formatter mecanism).
I need to hide some of the labels, but any try to remove it let the background and the border color visible.
as seen in this JSFiddle (They are still some little yellow circles)
code :
formatter:function() {
if(this.y > 150)
return this.y;
else
return "";
}
By returning "" I set the label empty. I would like it to be entirely hidden but its not.
The question is:
Is there a way to hide some datalabels from the formatter ?
I know I could set the datalabels enabled or not for each point in the chart initialisation but I need to change it at run time dynamicaly.
Replace return "" with return null and datalables wil be correct.

In a Highchart, how to display the legend text in next row if the text is too long?

I have highchart like this.
How can I display the legend (Firefox,IE,chrome...) text in next row if the text is too long? Image describing my problem is
P.S. I am not familiar with jQuery.
Expecting a solution
You will need to make use of a labelFormatter
labelFormatter: function()
{
var legendName = this.name;
var match = legendName.match(/.{1,10}/g);
return match.toString().replace(/\,/g,"<br/>");
}
I have made an edit to the fiddle and you can find it Here. It pushes the legend item text to next line after every 10 characters. Guess this is what you needed.Hope this helps.

Set z-index to dynamically generated image label to prevent overlapped label hidden from image

I am implementing drag and drop, user can drag few images and drop them in a div, and I dynamically append a p tag as label to each image once user click on a button.
Currently I meet problem when I have 2 images which is very close to each other (one is on top of another). The appended p tag for the top images will be hidden by the bottom image. I tried to alert the z-index for each dropped image, and found out it is 'auto'. I guess I need to assign a new z-index for each div, but I tried in the function which i append the label, and it dint work as expect:
function generateLabel() {
var current = 5000;
$('#rightframe img').each(function () {
var cImgName = $(this).attr('id');
var width = $(this).width();
// To select the respective div
var temp = "div#" + cImgName;
$.ajax({
url: '/kitchen/generatelabel',
type: 'GET',
data: { containerImgName: cImgName },
async: false,
success: function (result) {
$(temp).append(result);
// I guess the each function loop through each div according to the time it is created, so I try to assign a decreasing z-index
$(temp).css('z-index', current);
current -= 100;
// To select the label for the image
temp += " p";
// Set label width based on image width
$(temp).width(width);
}
});
});
However, what I get is, bottom image which dropped later do NOT hide the label of the image above, but if the above image is dropped after than the bottom image, above image's label is hide by the bottom image.
It's a very specific situation and I hope I do make myself clear...
Hope can get some help here... Appreciate any feedback...
I am so glad that I able to work out a solution for this kinda weird problem. I get to one useful plugin, the jquery-overlaps which check 2 dom whether they are overlapped with each other or not. Then i assign a z-index to the label accordingly.
Just to show my solution here, in case anyone jump into this bottleneck :)
// To assign an increasing z-index to the label
var count = 100;
$('#rightdiv p').each(function () {
// If any label overlaps with the image (used overlaps plugin)
if ($(this).overlaps($('#rightdiv img'))) {
// Increase count (the z-index)
count += 10;
// Set the parent div z-index 1st, if not the label z-index do not have effect
$(this).parent().css('z-index', count);
$(this).css('z-index', count);
}
});
Thanks! :D

Resources