Highcharts series not updating when hidden with current live time - javascript

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);

Related

how to toggle entire group by clicking on axis label tick in incubator eCharts?

I am using eCharts to create a stacked and grouped bar chart, it is my first time using eCharts. but clicking on axis label tick not working properly , I want when clicking on axis label tick (example: Brand1) it should hide that Brand but is not working, the code looks like:
myChart.on("click", (params) => {
if (params.targetType === "axisLabel") {
params.event.target.invisible = true;
params.event.target.silent = true;
params.event.target.scale[0] = 0;
params.event.target.scale[1] = 0;
// myChart.setOption();
console.log("params ", params, "option ", option);
}
});
you can check the full demo in demo
any help please?

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
}

amcharts customized label position

Right now my graph's label is placed in a default position, but my label texts are rather long and its sticking out from the graph.
If possible, I want to place it so that the labels don't stick out from the graph.
Pic of Current situation & Ideal graph
Or if the above is not possible, I want to fix the visible labels. Is this possible?
right now, the "best" label gets lost/hidden when the graph width is reduced. The "too much" label also gets lost when the width is largely reduced.
I have been searching all over stackoverflow and amcharts website but I can't seem to find a good solution.
Is there any way to solve either of the problems...?
// tried these but doesnt work for what I want to do
va.labelOffset = -5;
va.position = "bottom";
va.inside = false;
full code in JSfiddle
In order to keep the chart from hiding the labels on resize, you need to disable the valueAxis' autoGridCount and set the gridCount to the number of tick marks you want to see. You'll also need to remove the labelFrequency setting.
va.autoGridCount = false;
va.gridCount = 3;
//va.labelFrequency = 5;
As for label positioning, you are limted to rotating and vertical offsets out of the box. As a workaround, you can position the labels by modifying the SVG nodes directly through the drawn event, for example:
// prior to chart.write
chart.addListener("drawn", function(e) {
var textNodes = e.chart.valueAxes[0].labelsSet.node.childNodes;
var transform;
//Position "too little"
transform = parseTransform(textNodes[0].getAttribute('transform'));
transform.translate[0] = parseFloat(transform.translate[0]) + 25;
textNodes[0].setAttribute('transform', serializeTransform(transform));
// Position "too much"
transform = parseTransform(textNodes[2].getAttribute('transform'));
transform.translate[0] = parseFloat(transform.translate[0]) - 25;
textNodes[2].setAttribute('transform', serializeTransform(transform));
});
// ...
// from http://stackoverflow.com/questions/17824145/parse-svg-transform-attribute-with-javascript
function parseTransform(a) {
var b = {};
for (var i in a = a.match(/(\w+\((\-?\d+\.?\d*e?\-?\d*,?)+\))+/g)) {
var c = a[i].match(/[\w\.\-]+/g);
b[c.shift()] = c;
}
return b;
}
//serialize transform object back to an attribute string
function serializeTransform(transformObj) {
var transformStrings = [];
for (var attr in transformObj) {
transformStrings.push(attr + '(' + transformObj[attr].join(',') + ')');
}
return transformStrings.join(',');
}
Updated fiddle

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

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/

Highstock panning asynchronously loading data

Using Highstock is it possible to drag the chart and load the data asynchronously?
I've seen the async demo on the highcharts website http://jsfiddle.net/hcharge/5zPLV/
However this uses the navigator/scrollbar to move the chart along the series and loads the data when you stop sliding it along, Ideally I want to use the panning capability of highstock to move along instead of the navigator as it takes up too much space.
Playing around with the demo if I turn off the navigator and scrollbar and disable the zoomtype: x then as soon as you start dragging the chart it tries to fetch the data, making the chart unusable. Here is a fiddle of that http://jsfiddle.net/hcharge/6YSvk/
navigator: {enabled: false}, scrollbar: {enabled: false}
Ideally we'd need to know when the user starts dragging and when they stop then load the data.
Is this even possible to do? Thanks
I think this is possible, but it won't be easy.
As you wrote, you should start with detecting drag & drop. It's not possible using build-in options, but we can add our own event listeners. Take a look at this code:
new Highcharts.StockChart({
// here comes your chart options, but we can pass callback function as the second parameter
}, function (chart) {
var report = document.getElementById('report'), // just an element to display current extremes
xAxis = chart.xAxis[0],
startX;
function drag(e) {
e = chart.tracker.normalizeMouseEvent(e);
startX = e.chartX;
}
function drop(e) {
e = chart.tracker.normalizeMouseEvent(e);
var delta = e.chartX - startX,
extremes = xAxis.getExtremes(),
newMin = Math.round(extremes.min - delta),
newMax = Math.round(extremes.max - delta);
// display extremes retrieved by panning
report.innerHTML = "<b>From:</b> " + new Date(newMin) + " <b>to:</b> " + new Date(newMax);
}
// bind events
Highcharts.addEvent(chart.container, 'mousedown', drag);
Highcharts.addEvent(chart.container, 'mouseup', drop);
});
Simply we detect mouseDown & mouseUp events, then calculate the difference, translate difference to x data and finally, substract difference from extremes.
Here you can find the jsfiddle demo with code posted above: http://jsfiddle.net/dSEAA/1/
To make #slawekkolodziej's example work, you need to translate the delta into ms on the xAxis, then update the xAxis extremes like so:
window.chart = new Highcharts.StockChart({
// chart options go here
}, function(chart) {
var xAxis = chart.xAxis[0],
startX;
function drag(e) {
e = chart.pointer.normalize(e);
startX = e.chartX;
}
function drop(e) {
e = chart.pointer.normalize(e);
var delta = e.chartX - startX,
extremes = xAxis.getExtremes(),
deltaMs = (extremes.max - extremes.min) / chart.plotWidth * delta,
newMin = Math.round(extremes.min - deltaMs),
newMax = Math.round(extremes.max - deltaMs);
xAxis.setExtremes(newMin, newMax)
}
Highcharts.addEvent(chart.container, 'mousedown', drag);
Highcharts.addEvent(chart.container, 'mouseup', drop);
});
});
Here's a working example with async data loading: http://jsfiddle.net/xw7goLj4/5/

Categories