Highcharts' verifying stacking issues - javascript

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

Related

Conditional hover effect on the selected data using Chart.js

I want to disable the hover effect on certain data points of a dataset under certain conditions using Chart.js.
I basically need to modify the dataset before drawing the line graph so it looks in the way i want. (e.g extending the line along x axis) And i don't want the hover effect to take place on some of those data points.
After implementing the business logic, I've looked for a scriptable option
so i can use the context regarding the data point the user is on. I've came across solutions for basically cancelling all the hover effects on a single graph but not conditionally just like I've mentioned.
I've tried to use onHover with the context and set the hoverRadius conditionally and it looks as i expected but it gives me an error saying "Cannot assign to read only property 'hoverRadius' of object".
// in the options object
onHover: function (event, context) {
if (!isEmpty(context)) {
context[0]._options.hoverRadius = 0;
}
}
Most probably, the regarding object has been made immutable intentionally.
So what's the correct way of implementing this behavior in Chart.js?

Sigma JS node animation

I want to move nodes in Sigma JS on click event. Say from position x 0.7 to position x -0.7.
Is it possible to move nodes in Sigma js, and if it is, kindly guide me to achieve that.
Yes, it is possible. I created a jsfiddle showing how to change node position, size, and color on mouse click here:
http://jsfiddle.net/kaliatech/P255K/
You can bind to custom "downnodes" events like this:
sigInst.bind('downnodes',onNodeDown);
The event callback contains an array of selected node ids. I don't know when it would be more than one when clicking. Perhaps when zoomed out in a complex graph.
One of the more subtle issues when using sigmajs, is that most methods, such as getNodes, return clones, not the instances themselves. This is to protect "private" data in the graph I think, especially data that can not be redrawn after initialization. To actually modify properties, you need to use the iterator methods. Even then, you are only given clones. The library updates the actual node instances using a list of predefined allowable properties. (See the checkNode function in graph.js).
After properties have been set, you then need to refresh/redraw the graph. While the "refresh" method would seem to be an obvious candidate, it did not work. I was able to get it to redraw using the draw method though. You will need to review the source code to understand the different parameters. Example:
function onNodeDown(evt) {
var sigmajs = evt.target;
var nodeId = evt.content[0];
sigmajs.iterNodes(function(n){
n.size = 10;
n.color = "#0000FF";
},[nodeId]);
sigmajs.draw(2, 2, 2, true);
};
For more advanced needs, the sigmajs website includes plugin examples showing other ways of getting mouse events and updating nodes dynamically. One is the advanced plugin example for a fisheye effect:
http://sigmajs.org/examples/a_plugin_example_advanced.html
Another is the example for accessing node attributes:
http://sigmajs.org/examples/more_node_info.html
The sigmajs documentation is weak, so you will need to review the source code to understand things.
There are plugins permitting to move isolated nodes from the graph.
Check
https://github.com/Linkurious/linkurious.js/blob/develop/examples/lasso.html

Dynamically pass series in jqplot line chart

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.

Hiding all series except one very slow in IE [duplicate]

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

Hiding _groups_ of series in Highcharts and jQuery: how to get acceptable performance?

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

Categories