HighStock CrossHair Values Displayed Outside of Tooltip With Multiple Trends - highcharts

I have a HighStock chart (below) where I display 10-15 trends on average. I have found that the Tooltip becomes slow and too large when running so many trends on a single display. I would like to disable the tooltip, but still display the values for each trend hovered on by the crosshairs. What event do I subscribe to in HighStock to essentially move the values displayed in the tooltip to something custom?
I have attached an image of my graph with the tooltip visible and a custom legend to the left. I would like to have the hovered on values (at the crosshairs) appear next to their legend items on the left just like they do in the tooltip, disable the tooltip, but keep the crosshairs.
I have found several ways to do this using PlotOptions.Series.Point.Events.MouseOver, but that only works for one trend. How do I do it for all my trends?
It is worth noting that my code works well. The picture of the graph above is a picture of a working graph dynamically generated in MVC4 that displays beautifully on a PC/MAC/iPhone/iPad. My question ultimately needs someone proficient with HighStock to answer as they will have the intimate knowledge necessary to know what event needs to be subscribed to or what changes I need to make in order to push the data I need into a Javascript function (so I can push the crosshair values to my custom legend). It's not a question of "Is my code correct?". It's a question of "What code do I use to get the desired effect?".
But here is the code just in case it's relevant. Notice I am building a C# generic "var" and returning it via "Javascript()".
// BUILD HIGHCHARTS JAVASCRIPT
var data = #"$(function () {
$.post(""";
if (Request.ApplicationPath.ToString() == "/")
{
data += #"/HighCharts/GetData"", function (data) {";
}
else
{
data += Request.ApplicationPath.ToString() + #"/HighCharts/GetData"", function (data) {";
}
data += #"// Create the chart
window.chart = new Highcharts.StockChart({
chart: {
events : {
load : LoadComplete
},
renderTo: 'container',
zoomType: 'x'
}, ";
data += #"colors: [ ";
foreach (var a in model.listOfSensors)
{
data += "'" + a.ColorHex.ToString() + "'";
y = y + 1;
if (y != model.listOfSensors.Count)
{
data += ",";
}
}
data += #"], ";
data += #"plotOptions: {
series: {
point: {
events: {
mouseOver: function () {
SeriesMouseOver(this.series.name)
},
mouseOut: function () {
SeriesMouseOut(this.series.name)
}
}
}
}
},";
data += #"navigator : {
adaptToUpdatedData: false
}, ";
data += #"exporting : {
enabled: true
}, ";
data += #"rangeSelector : {
buttons: [{
type: 'hour',
count: 12,
text: '12h'
}, {
type: 'day',
count: 1,
text: '1d'
}, {
type: 'day',
count: 2,
text: '2d'
}, {
type: 'all',
text: 'All'
}],
inputEnabled: true, // it supports only days
inputStyle: {
color: '#CCCCCC',
fontFamily: 'Arial'
},
labelStyle: {
color: '#000000',
fontFamily: 'Arial',
fontWeight: 'bold'
},
selected : 3 // all
},
xAxis : {
events : {
afterSetExtremes : afterSetExtremes
},
minRange: 3600 * 1000 // one hour
},
yAxis: [";
// BUILD SCALES
foreach (IECRM_Data_Project.Entities.Scale a in model.scales)
{
data += "{ ";
data += "min: " + a.Min.ToString() + ",";
data += "showEmpty: " + a.ShowIfEmpty.ToString().ToLower() + ",";
data += "max: " + a.Max.ToString() + ",";
data += "lineColor: '" + a.ColorHex.ToString() + "',";
data += "labels: { enabled: false }" ;
data += "}";
x = x + 1;
if (x != model.scales.Count) //ADD A COMMA AFTER EACH EXCEPT THE LAST
{
data += ",";
}
}
data += #"],
tooltip: {
pointFormat: '<span id=""{series.name}.replace(/\./g, """")"" style=""color:{series.color}"">{series.name}: {point.y}</span><br />',
useHTML: true,
valueDecimals: 1
},
series: data
});
});
});";
return JavaScript(data);

Related

HighChart data table keeps adding number of tables at bottom on every call

I am using HighChart library to show Pie Chart on my page, I am keeping showTable always true to show every time.
The problem is whenever data binds to charts using JQuery Ajax post dynamically, i see proper data in chart but also it keeps adding new data table everytime at the bottom. E.g. First time there will be only one table, after another call there will be two tables added and so on. Why Hightcharts not updating the same table again or is there a way to kill any existing table.?
hc = Highcharts.chart(chartName, {
chart: {
type: 'pie',
options3d: {
enabled: false,
alpha: 45
},
style: {
color: '#575962'
}
},
title: {
text: title,
style: {
color: '#575962',
fontweight: '400'
}
},
subtitle: {
text: 'Current Month(Top 10)'
},
plotOptions: {
pie: {
innerSize: 100,
depth: 45,
allowPointSelect: true,
cursor: 'pointer',
dataLabels: {
enabled: false
},
showInLegend: true
}
},
credits: {
enabled: false
},
exporting: {
showTable: true
},
series: [{
name: 'Price',
data: [],
dataLabels: {
formatter: function () {
//const point = this.point;
//return '<span style="color: #575962;font-size:11px;font-weight: 400">' +
// point.name + ': $' + point.y + '</span>';
}
}
}]
});
Why Hightcharts not updating the same table again or is there a way to kill any existing table.?
I have achieved this by removing the series on each call and adding them again with new data. Hope this helps if anyone else looking and couldn't find any other answer.
//Removing Series
while (hc.series.length > 0) {
hc.series[0].remove(false);
}
//Adding new Series
hc.addSeries({
name: 'Price',
data: [],
dataLabels: {
formatter: function () {
const point = this.point;
return '<span style="color: #575962;font-size:11px;font-weight: 400">' +
point.name + ': $' + point.y + '</span>';
}
}
});
//Binding Series data
var res = result.Data.slice(0, 10);
res.forEach(function (element, index) {
hc.series[0].addPoint({
name: element.ResourceGroupName,
y: element.TotalMonthlyPrice,
});
});

Highcharts dynamic data from an Api

I want to create a chart that reads its data from an Api. To do that i have this fiddle http://jsfiddle.net/68oe1oLf/69/
Note: https://jsfiddle.net/68oe1oLf/69/ will lead to mixed content error and will fail to load data from the api
This is the javascript code
$(document).ready(function () {
$.get( "http://firmbridgecapital.com/live.php", function( dt ) {
localStorage.setItem("data", dt);
});
window.setInterval(function(){
$.get( "http://firmbridgecapital.com/live.php", function( dt ) {
localStorage.setItem("data", dt);
});
}, 5000);
Highcharts.setOptions({
global: {
useUTC: false
}
});
Highcharts.chart('container', {
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
events: {
load: function () {
// set up the updating of the chart each second
var series = this.series[0];
setInterval(function () {
var x = (new Date()).getTime(), // current time
y = parseInt(localStorage.getItem("data"));
series.addPoint([x, y], true, true);
}, 5000);
}
}
},
title: {
text: 'Live random data'
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
max: 3,
title: {
text: 'Value'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
formatter: function () {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: [{
name: 'Random data',
data: (function () {
// generate an array of random data
var data = [],
time = (new Date()).getTime(),
i;
for (i = -150; i <= 0; i += 25) {
data.push({
x: time,
y: parseInt(localStorage.getItem("data"))
});
}
return data;
}())
}]
});
});
I borrowed the idea from this docs example http://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/highcharts/demo/dynamic-update/
My chart is always grounded on value 1 and does not show the changing values in the y axis. How may i fix this?.
The value you are referencing, i.e. live php page, seems to be 1.x and increasing very slowly. (1.7 while I was looking).
In your parsing you do the following:
y = parseInt(localStorage.getItem("data"));
And since the value is 1.7, and you try to parse it as an integer with parseInt, it gets converted to 1. Using parseFloat will give you a slowly increasing graph.

Wrong data display when i set multiple series type in highstock chart

I try to make a chart with multiple series type, lines and column.
Exemple here :Jsfiddle
$(function () {
var seriesOptions = [],
seriesCounter = 0,
names = ['MSFT', 'AAPL', 'GOOG'];
/**
* Create the chart when all data is loaded
* #returns {undefined}
*/
function createChart() {
$('#container').highcharts('StockChart', {
rangeSelector: {
selected: 4
},
yAxis: {
labels: {
formatter: function () {
return (this.value > 0 ? ' + ' : '') + this.value + '%';
}
},
plotLines: [{
value: 0,
width: 2,
color: 'silver'
}]
},
plotOptions: {
series: {
compare: 'percent'
}
},
tooltip: {
pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y}</b> ({point.change}%)<br/>',
valueDecimals: 2
},
series: seriesOptions
});
}
$.each(names, function (i, name) {
$.getJSON('https://www.highcharts.com/samples/data/jsonp.php?filename=' + name.toLowerCase() + '-c.json&callback=?', function (data) {
seriesOptions[i] = {
name: name,
data: data,
};
if(name == 'GOOG'){
seriesOptions[i].type = 'column';
}
// As we're loading the data asynchronously, we don't know what order it will arrive. So
// we keep a counter and create the chart when all the data is loaded.
seriesCounter += 1;
if (seriesCounter === names.length) {
createChart();
}
});
});
});
When i'm not zooming i have wrong data (more than normal) and when i zoom in i have the good data.
what is the problem ? i don't know why the serie type can change datas
Thanks for you help !
Defaulty the Highstock uses the dataGrouping, which groups points according to units. You can disable that by the parameter.
plotOptions:{
series:{
dataGrouping:{
enabled: true
}
}
}

Function to create Highcharts where the series has the correct prototype

I am attempting to write a function to add a highchart to a page and a function that can update the data for that chart based on a streaming API. I added a setInterval to simulate the streaming api.
The issue occurs on line 80. I believe it is because I have not set the series array with the chart object properly. When I need to add new data via 'addPoint', the prototype is not there. What am I missing in my AddChart function that wires the series up to highcharts?
FIDDLE:
http://jsfiddle.net/puto3Lg0/2/
$(function () {
$(document).ready(function () {
var metrics = [];
Highcharts.setOptions({
global: {
useUTC: false
}
});
function AddChart(metric) {
$("#divMain").append('<div id="' + metric.key + '" style="min-width: 310px; height: 200px; margin: 0 auto"></div>');
$('#' + metric.key).highcharts({
chart: {
type: 'spline',
animation: Highcharts.svg, // don't animate in old IE
marginRight: 10,
},
title: {
text: metric.Title
},
xAxis: {
type: 'datetime',
tickPixelInterval: 150
},
yAxis: {
title: {
text: 'Messages'
},
plotLines: [
{
value: 0,
width: 1,
color: '#808080'
}
]
},
tooltip: {
formatter: function() {
return '<b>' + this.series.name + '</b><br/>' +
Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
Highcharts.numberFormat(this.y, 2);
}
},
legend: {
enabled: false
},
exporting: {
enabled: false
},
series: metric.series
});
};
function ParseData(message) {
var jsonObj = JSON.parse(message);
$.each(jsonObj.Metrics, function(index, value) {
var metricName = value.Metric.Name.replace(' ', '');
if (metrics[metricName] == undefined) {
metrics[metricName] = {
"title": value.Metric.Name,
"key": metricName,
"series": [
{
name: value.Metric.Name,
data: []
}
],
}
AddChart(metrics[metricName]);
}
metrics[metricName].series.addPoint([new Date().getTime(), parseInt(value.Metric.CurrentValue)], true, false);
});
};
setInterval(function () {
var m = "{\"Metrics\": [{\"Metric\":{\"Name\":\"Queue 01\",\"CurrentValue\":\"0\",\"TimeStamp\":\"\\\x2FDate(1415826323291)\\\x2F\"}},{\"Metric\":{\"Name\":\"Queue 02\",\"CurrentValue\":\"3\",\"TimeStamp\":\"\\\x2FDate(1415826323344)\\\x2F\"}},{\"Metric\":{\"Name\":\"Queue 03\",\"CurrentValue\":\"9\",\"TimeStamp\":\"\\\x2FDate(1415826323405)\\\x2F\"}}]}";
ParseData(m);
}, 1000);
});
});
First, you have metrics declared as an array. Should be an empty object:
var metrics = {};
Second, the data structure you've created, metrics[metricName].series is not a Highcharts series object. It's an object you created and used to supply Highcharts data. To get the real series object, you'll have to get it back from the chart.
// getting the chart from the DOM, then the first series...
$("#"+metricName).highcharts().series[0].addPoint([new Date().getTime(), parseInt(value.Metric.CurrentValue)], true, false);
Updated fiddle.

How to use a different formatter on Highcharts in each curve of the same graphic?

I am using Highcharts and i want to use a different formatter for the numbers displayed in the tooltip, for each curve in the same graphic.
Thank you
First of all you have to store your series tooltip text. You can do it using the following example:
.
.
.
series: [{
'name': 'serie 1',
'data': serieData, // use your array of data
'tooltipText': 'text 1' // text which will be inside the tooltip
}]
.
.
.
Then you have to get your tooltip text inside the serie tooltip.
Not shared tooltip:
tooltip: {
shared: false,
formatter: function() {
return this.series.options.tooltipText + '<br>' + // return stored text
'Value: ' + this.y;
}
}
demo1
Shared tooltip:
tooltip: {
formatter: function() {
var tooltip = '';
for(var i = 0, length = this.points.length; i < length; i++) {
var point = this.points[i];
tooltip += point.series.options.tooltipText + '<br>' +
'Value: ' + point.y + '<br>';
}
return tooltip;
}
}
demo2

Resources