How to show a custom message box at last point, Highcharts - javascript

http://www.highcharts.com/docs/chart-concepts/tooltip says
The tooltip appears when hovering over a point in a series.
But what if I need a custom tooltip to show at the last point even though not hover on the point to demonstrate some loading information like this:

You can set a flag on serie, which should have a label. Then in load event get last point from serie and print label by renderer.
load: function () {
var chart = this,
series = this.series,
len, lastPoint;
$.each(series, function (i, s) {
if (s.options.showLabel) {
len = s.data.length - 1;
lastPoint = s.data[len];
chart.renderer.text('Label', lastPoint.plotX + chart.plotLeft, lastPoint.plotY + chart.plotTop)
.css({
color: '#4572A7'
})
.add();
}
});
}
Example: http://jsfiddle.net/nf7ne/55/

Related

Data label not rendered on sapui5 viz dual y-axis graph when line and column intersect

I have a requirement to show data labels of two graphs on the same axes.
Only when they intersect, one of the two labels won't show. This can be demonstrated below:
As you can see on the 2nd, 5th and 6th columns from the left with values 0%, 7% and 8% respectively
only the orange line values are shown but the blue column values are missing.
This is the final html of the graph after rendering:
So data-datapoint-id 142, 145 and 146 are missing from the html.
I tried using the plotArea.dataLabel.renderer function as a manipulation of what was proposed here but nothing changed, still not rendering.
Anyone encountered a similar problem? Is that a sapui5 issue or can it be fixed by manually inserting the labels into the HTML if so how?
Thanks,
Ori
Using SVG text and jQuery I managed to manually insert the labels into the top middle of the blue rectangle columns.
This is the result, not perfect but works:
and this is the code:
chart.setVizProperties({
plotArea: {
dataLabel: {
formatString: {'פחת כללי': FIORI_PERCENTAGE_FORMAT_2},
renderer: function (oLabel) {
// Create empty text node to be returned by the function such that the label won't be rendered automatically
var node = document.createElement("text");
if (oLabel.ctx.measureNames === "כמות פחת כללי") {
var kamutLabelIdx = oLabel.ctx._context_row_number;
// Use jQuery and SVG to manipulate the HTML
var kamutLabelQuery = '[data-id=\"' + kamutLabelIdx + '\"]';
var kamutColumn = $(kamutLabelQuery)[0];
// Create text element as child of the column
kamutColumn.innerHTML += "<text>" + oLabel.text + "</text>";
var labelNode = $(kamutLabelQuery += ' text');
// Set the label position to be at the middle of the column
const labelLength = 60;
const xPos = (labelLength + oLabel.dataPointWidth) / 2;
const yPos = oLabel.styles['font-size'];
labelNode.attr({
"textLength" : labelLength,
"x" : xPos,
"y" : yPos,
"font-size" : yPos
});
return node;
}
}
}
}
});
The oLabel parameter of the renderer function provides useful info about the data label to be created:
I still wonder if that's a bug with sapui5 vizframe and if there is a simpler way to do this.
Please let me know of your thoughts

How can I align Chart title with the bar dynamically?

How can I align Chart title with the bar in highcharts?
The bar length may vary because of the data, so I want my title to end where the bar is ending.
I want to implement something like this:
To adjust the title you can set tittle.attr in the events.redraw event. You need to remember that a bar chart is an inverted column chart and where you have an x-axis there will be a y-axis.
chart: {
events: {
render: function() {
let chart = this,
series = chart.series[0],
title = this.title,
point = series.points[0];
title.attr({
x: chart.plotTop + point.x,
y: chart.plotLeft + point.y
});
}
}
},
API References:
https://api.highcharts.com/highcharts/chart.events.render
https://api.highcharts.com/class-reference/Highcharts.SVGElement
Demo: https://jsfiddle.net/BlackLabel/ud45prLg/
I would suggest adding a padding-right: ##px as you havent provided any code to work with. try applying the method via inspect element and add the code into your css after with the right amount of "px" needed.

Highcharts synchronize tooltip on multiple charts with multiple series

I am trying to synchronize shared tooltip across multiple charts, each having multiple series.
The problem is in the below example, the tooltip always shows the 3 series, even though at that particular point there are only two series present.
1) How do I make sure that a series is shown in tooltip only when it is actually present?
2) How do I make sure the tooltip is closed when we move out of the chart?
JSFiddle: https://jsfiddle.net/qoL7fx27/1/
Code for synchronization in fiddle:
$('#container').bind('mousemove touchmove touchstart', function (e) {
var chart,
point,
i,
event;
for (i = 0; i < Highcharts.charts.length; i = i + 1) {
chart = Highcharts.charts[i];
var points = [];
// Find coordinates within the chart
event = chart.pointer.normalize(e.originalEvent);
// Get the hovered point
for(var j=0; j<chart.series.length; j++) {
point = chart.series[j].searchPoint(event, true);
points.push(point);
}
chart.tooltip.refresh(points);
}
});
Here is my solution. It's perfectly working for me. I made adjustments based on Synchronisation of multiple charts
Demo here
The following code shows/hides the tooltip and makes sure they are aligned on mousemove and mouseleave.
Note that I found that I only need to find the first point searched and use it to show/hide the tooltip. It's because all my time series share the same x values.
$("#container").bind("mousemove mouseleave", function(e) {
for (let i = 0; i < Highcharts.charts.length; ++i) {
let hart = Highcharts.charts[i];
let event = chart.pointer.normalize(e.originalEvent); // Find coordinates within the chart
let point;
for (let j = 0; j < chart.series.length && !point; ++j) {
point = chart.series[j].searchPoint(event, true);
}
if (!point) return;
if (e.type === "mousemove") {
point.onMouseOver();
chart.xAxis[0].drawCrosshair(event, point); // Show the crosshair
} else {
point.onMouseOut();
chart.tooltip.hide(point);
chart.xAxis[0].hideCrosshair();
}
}
});
Keep reseting the reset function so as to disallow HighCharts resetting the points -- we take over the control.
Highcharts.Pointer.prototype.reset = function() {
return undefined;
};
1) How do I make sure that a series is shown in tooltip only when it is actually present?
The unwanted behavior is caused by searchPoint function - it returns the nearest point even though the x position doesn't mach with other points. So if the series has only one point it'll be always found.
Solution:
Manually select points to display in tooltip.formatter:
formatter: function() {
var outputString = '';
this.points.forEach(function(point) {
if (point.x === this.x) {
outputString += "<span style='color:" + point.color + "'>\u25CF</span> " + point.series.name + ": <b>" + point.y + "</b><br/>";
}
}, this);
return outputString;
}
API reference: https://api.highcharts.com/highcharts/tooltip.formatter
2) How do I make sure the tooltip is closed when we move out of the chart?
Restore the default Highcharts.Pointer.prototype.reset function by removing these lines:
Highcharts.Pointer.prototype.reset = function() {
return undefined;
};
Demo for both questions: https://jsfiddle.net/BlackLabel/2mxxrk5n/
Update:
I posted the wrong answer for the second question. This code hides tooltips:
$('#container').bind('mouseout', function(e) {
Highcharts.charts.forEach(function(chart) {
chart.tooltip.hide();
// undo point highlight
chart.series.forEach(function(series) {
series.points.forEach((point) => point.setState(''));
});
});
});
can you please tell me how to highlight the corresponding points in each chart? As of now, the tooltip shows correctly, however the points are not highlighted in three charts
This piece of highlights points:
points.forEach(function(point_) {
if (point_) {
point_.highlight(e);
}
}, this);
To achieve the desired behavior you must provide a logic for filtering points that should be Highlighted. Here's a very simplified example adjusted to this particular case:
// provide a logic for filtering points
if(points[0] && points[1].x > 0) {
points.pop(); // remove the unwanted point
}

Highcharts series not updating when hidden with current live time

i am getting problem here is, when the highchart series is hidden the points not updating with its current live time but when it is not hidden(shown) it is updating data with its current live time currectly.
how can i updates the points with its current time when the series is hidden.
http://i.stack.imgur.com/H64Ky.png
please open the link and see the purple color line was hidden before and then i shown after some interval of time as you can see the purple color line points is not till at the end.
when i inspect element from the browser the hidden series was not updating.
Any idea???
$(document).on('click', '.SpeedCheckbox', function () {
var chart = $('#SpeedGraph').highcharts();
var series = chart.get(id);
if (series.visible) {
series.hide();
} else {
series.show();
}
});
function addpoints(){
for (var key in lineview.Signals) {
var signal = lineview.Signals[key];
var series = chart.get(signal.MachineId);
y = parseInt(signal.LatestValue);
var speedTrendData = series.data;
var lastTime = speedTrendData[speedTrendData.length - 1].x;
var x = new Date(lastTime + PageVariables.GraphRefreshRate()).getTime();
series.addPoint([x, y], true, true);
}
setInterval("addpoints()", 1000);

Finding the Y axis value for a plot line in HIghCharts.js

I am trying to size a background image on a HighCharts line chart dynamically depending on the position of the top plot line. The image I am trying to size is the bell curve in the image below.
I can't set the height of the image as a static value because the size of the screen can change and the top plot line also changes over time.
At the moment I am setting the position of the plot lines with external functions like this:
plotLines: [
value: upperControl3()}, {
color: '#ccc',
zIndex: 3,
width: 1,
label: {
text: '-2s',
x: 520,
y: 3
}
The closest thing to the y value of the top plot line I have been able to find is a dataMax value but this stays the same on every chart load.
I have been trying to overlay and size the image with a function at the end of the chart like this:
function(chart) {
console.log(chart.yAxis[0].plotLinesAndBands[7].axis.plotLinesAndBands[0].axis);
var h = chart.yAxis[0].plotLinesAndBands[7].axis.plotLinesAndBands[0].axis.dataMax;
var y = chart.yAxis[0].axisTitle.y + extra;
// X, Y, Width, Height
chart.renderer.image('images/bell.jpg', 60, y, 200, h).add();
}
Is the any way to find the coordinates of a plot line in highcharts?
You can use plotLinesAndBands object, where plotlines are kept. In the options you have value, whcih can be translated into pixels value by toPixels function.
var $button = $('#button'),
$report = $('#report'),
chart = $('#container').highcharts();
$button.click(function () {
chart.xAxis[0].addPlotLine({
value: 5.5,
color: 'red',
width: 2,
id: 'plot-line-1'
});
var plotline = chart.xAxis[0].plotLinesAndBands[0];
$report.html('Value: ' + plotline.options.value + ' Pixels: ' + chart.xAxis[0].toPixels(plotline.options.value));
});
http://jsfiddle.net/HhP39/1/
If you know which plot line (by index) it is, you can do this:
chart.yAxis[0].plotLinesAndBands[0].options.value
Of course, you need to make sure your data is actually normally distributed, or else that normal curve means nothing :)
And zero-bounded data is not usually normally distributed.

Categories