I'm using Highcharts to represent groups of time series. So, data points collected from the same individual are connected by lines, and data points from individuals that belong to the same group share the same color. The Highcharts legend displays each individual time series instead of groups, and I have over a hundred time series, to it's ugly and impractical to hide and show data that way.
Instead I made buttons and used jQuery to associate them with functions that would search for matching colors among the time series and toggle the visibility of each matching series.
Here is an example with a small dataset: http://jsfiddle.net/bokov/VYkmg/6/
Here is the series-hiding function from that example:
$("#button").click(function() {
if ($(this).hasClass("hideseries")) {
hs = true;
} else {
hs = false;
}
$(chart.series).each(function(idx, item) {
if (item.color == 'green') {
if (hs) {
item.show();
} else {
item.hide();
}
}
});
$(this).toggleClass("hideseries");
});
The above works. The problem is, my real data can have over a hundred individual time series and it looks like checking the color of each series is really slow. So, can anybody suggest a more efficient way to solve this problem? Are there some built-in Highcharts methods that already do this? Or, can I give jQuery a more specific selector?
I tried digging into the <svg> element created by Highcharts but I can't figure out which child elements correspond to the series in the chart.
Thanks.
The issue here is that Highcharts is redrawing the chart after every series change. I checked the API to see if there was a param you could pass to defer that, but that doesn't appear to be the case.
Instead, you can stub out the redraw method until you are ready, like so:
var _redraw = chart.redraw;
chart.redraw = function(){};
//do work
chart.redraw = _redraw;
chart.redraw();
Check out the full example here. For me, it was about 10 times faster to do it this way.
Rather than calling show() or hide() for each series, call setVisible(/* TRUE OR FALSE HERE */, false);. This second parameter is the redraw parameter, and you can avoid causing a redraw (which is slow) for each series.
Then, after you're done changing visibilities, call chart.redraw() once.
http://api.highcharts.com/highcharts#Series.setVisible
Related
I have this map with two series very much like this one: JSFiddle
On the load() event I'm able to zoom in to a specific element of the first series like this:
this.get('TX').zoomTo();
That works as expected. But I can't figure out how to zoom to an item of the second series (a bubble). I tried the same call with the ID of a bubble and it says it is undefined. I suppose I need somehow to specify it is in the second series, but how do I do that?
The mapbubble series point has not zoomTo method in it's prototype, but you can add it in this way:
Highcharts.seriesTypes.mapbubble.prototype.pointClass.prototype.zoomTo = function() {
var point = this,
series = point.series;
series.xAxis.setExtremes(point._minX, point._maxX, false);
series.yAxis.setExtremes(point._minY, point._maxY, false);
series.chart.redraw();
}
Live demo: http://jsfiddle.net/BlackLabel/6m4e8x0y/4783/
I will try to explain my problem as much accurate as possible. I am looking for a javascript chart library filling the two following conditions:
From an ajax request retrieving time series,
display dynamically data when changing the time window.
such as it is perfectly done on highstocks: http://www.highcharts.com/stock/demo/basic-line
And
plot an horizontal line corresponding to the mean,
changing when the user update the time window on the chart.
Actually it is possible to display an horizontal line. But they are fixed on the whole data and do not change accordingly when the time window is modified:
http://www.highcharts.com/stock/demo/yaxis-plotlines
I am quite new to the topic and would like to know if it'sp ossible to modify Highstock classes to have such a result. Or maybe some other js libraries exists?
Using a combination of the answer here:
Highchart, get total of visible series data after setExtremes
And an example of dynamic average using all visible series that I made for a previous question, here:
http://jsfiddle.net/jlbriggs/gweuLegq/
I put together this example, using the afterSetExtremes event, like this:
xAxis : {
events:{
afterSetExtremes:function() {
var ext = this.getExtremes();
getAverage(this.chart, ext.min, ext.max, show, width, avgColor, dashStyle);
}
}
},
Working example here:
http://jsfiddle.net/jlbriggs/c93543yL/
The idea is:
1) capture the afterSetExtremes event
2) get the resulting axis min and max
3) loop through the series data
4) if a point is between the min and max, increment the count, and add the
point's y value to the sum
5) calculate the average accordingly, check for existence of average series, if exists, update, if not, add
It could as easily use a plot line that you add/remove as needed instead of a series, but I like having it as a series so that it has a legend entry.
I'm using Highcharts for plotting some graphics for my system's users. It works fine, but I'm having some trouble with the stacking option.
To stack a chart, here's what I'm doing:
chart.options.plotOptions.series.stacking = 'normal';
That's how it's done, according to Highcharts API. It works fine; but aside stacking, I also need to show some information to the user, but these information should only be visible if the chart is stacked. So here's what I'm doing:
var stacking = chart.options.plotOptions.series.stacking;
if (stacking == 'normal'){
//show something
}
That should make sure the chart is stacked, but "stacking" is always returning "undefined" instead of 'normal' or blank - even though in another function I just attributed it 'normal'. Keep in mind "chart" is a global variable, so any changes on it should be accessable by any other JS function.
For details: http://jsfiddle.net/GtjdU/
Any ideas?
The problem is that you said you did the following:
chart.options.plotOptions.series.stacking = 'normal';
^
But you did it ?
No, if you take a look your fiddle, you'll see that you did the following:
chart.options.plotOptions.column.stacking = 'normal';
^
That's why you're getting undefined
demo
You need to define what series you want to know the stacking for.
var stackedVal;
stackedVal = chart.series[0].options.stacking;
alert(stackedVal);
The reason you can't get the global stacking value is because it is on override from the individual series elements. So you could set the plotOptions.series.stacking = 'normal' but in each of the series you can set its own individual stacking. It is always better to read from what a particular series is actually doing.
DEMO
I have used jqplot line chart.
I have get data from php page using ajax.In some condition I will display specific series.So
How to pass series dynamically in jqplot line chart and also set legend of series ?
I have manually write code for above requirement.I have apply click event on legend series and draw graph as per click on legend.
I have also change y-axis value as per select/deselect series legend.
I originally tried the answer posted by #sdespont, but due to additional properties that need to be in place for the series, it wasn't working properly. I was able to get this working by doing the following:
plot1.data = data;
plot1.replot( data );
data is a 3D array of the same makeup as you would pass in when creating the plot. If I did either part without doing the other, it wouldn't refresh properly, but the combination of the two seems to do the trick. Refreshing the plot in this fashion would dynamically add or remove any series I added to the data array.
Hope that helps.
You could add or remove series by playing with plot1.series array.
Here is a good jsfiddle : jsfiddle.net/fracu/HrZcj
The idea is to create an array with data
myNewSerie = Array();
x = (new Date()).getTime();
y = Math.floor(Math.random() * 100);
myNewSerie.push([x, y]);
Then add it to the graph using the next available slot
plot1.series[plot1.series.length] = myNewSerie
And finally redraw using plot1.replot();
Check out the updateSeries function in the end of the fiddle
Not tested, but should work
I had the same problem recently. "replot" works but is veeerrryyy slow. I used "jQPlot.drawSeries" which is blazingly fast. Just give your new series data to jQPlot as usual and call jQPlot.drawSeries({}, <nr of your series from 0...xxx)
My realtime chart with 800 values runs with >> 60 FPS on my PC and also very fast on my mobiles.
I'm using Highcharts to represent groups of time series. So, data points collected from the same individual are connected by lines, and data points from individuals that belong to the same group share the same color. The Highcharts legend displays each individual time series instead of groups, and I have over a hundred time series, to it's ugly and impractical to hide and show data that way.
Instead I made buttons and used jQuery to associate them with functions that would search for matching colors among the time series and toggle the visibility of each matching series.
Here is an example with a small dataset: http://jsfiddle.net/bokov/VYkmg/6/
Here is the series-hiding function from that example:
$("#button").click(function() {
if ($(this).hasClass("hideseries")) {
hs = true;
} else {
hs = false;
}
$(chart.series).each(function(idx, item) {
if (item.color == 'green') {
if (hs) {
item.show();
} else {
item.hide();
}
}
});
$(this).toggleClass("hideseries");
});
The above works. The problem is, my real data can have over a hundred individual time series and it looks like checking the color of each series is really slow. So, can anybody suggest a more efficient way to solve this problem? Are there some built-in Highcharts methods that already do this? Or, can I give jQuery a more specific selector?
I tried digging into the <svg> element created by Highcharts but I can't figure out which child elements correspond to the series in the chart.
Thanks.
The issue here is that Highcharts is redrawing the chart after every series change. I checked the API to see if there was a param you could pass to defer that, but that doesn't appear to be the case.
Instead, you can stub out the redraw method until you are ready, like so:
var _redraw = chart.redraw;
chart.redraw = function(){};
//do work
chart.redraw = _redraw;
chart.redraw();
Check out the full example here. For me, it was about 10 times faster to do it this way.
Rather than calling show() or hide() for each series, call setVisible(/* TRUE OR FALSE HERE */, false);. This second parameter is the redraw parameter, and you can avoid causing a redraw (which is slow) for each series.
Then, after you're done changing visibilities, call chart.redraw() once.
http://api.highcharts.com/highcharts#Series.setVisible