So there seems to be an error when dynamically adding data to a hidden series in Highcharts.
Say I have two series on a chart that both update on the same interval of time. Say also that I'd like to ensure that neither of the two series have more than a certain number of points, therefore leading me to use the optional shift boolean during a series.addPoint() operation.
The problem I run into is that, if one of the series is toggled and made invisible for some time, when re-toggling that series, much of the data that should've been shifted is still present.
I've made an example fiddle of this (just toggle data1 in the chart legend for a few seconds and then re-toggle)
http://jsfiddle.net/mmuelle4/c00cLfs5/ (change funcToTest to see how various fixes don't quite give the "shift" look)
I'm using the latest version at the time of this post (Highcharts JS v4.0.4).
I think what I've uncovered is still an error that will need to be addressed by Highcharts, but I figured I'd ask the question - is there a better way to perform series length checking and data adding/shifting for multiple series than in the linked fiddle that would get around this issue? I can think of some clunky ones off the top of my head, but I thought I'd come to SO for some elegance :)
Link to bug on Github (for tracking): https://github.com/highslide-software/highcharts.com/issues/3420
You can workaround this issue by managing shift on your own. Simply store in some array all points and shift them there. Then call series.setData(array_of_points,redraw,animation) instead of series.addPoint(points,redraw,animation, shift).
In short:
when series is hidden use series.setData()
when series is visible use series.addPoint() with shift-param set to true|false
Related
i am using the leaflet slider by[dwilhelm89][1], i'm letting it slide through days( i made each day a layer and added it to the slider) but i need to add a label(timeline) so that you can see where the slider will go, any idea how to do that? thanks
var sliderControl = L.control.sliderControl({ position: "topright", layer: layerk, range: true, follow:true,alwaysShowDate : true});
map.addControl(sliderControl);
sliderControl.startSlider();
this code is what i used to make the slider, any options or edits i can use? [1]: https://github.com/dwilhelm89/LeafletSlider
If you mean adding a scale with tick marks, the LeafletSlider doesn't seem to have any options for that. Though I don't have any suggestions for modifying or extending the LeafletSlider code, a couple other approaches spring to mind:
First, if you are only dealing with a few days, and you just need a few labels along the length of the slider, it may be possible to adapt one of the examples from the answers to this stackoverflow question. The top-voted answer in particular looks promising, as it is probably the simplest solution.
[EDIT: After looking into the Leaflet Slider code a bit more, I realised that it does not actually filter the data by the quantity in the time field. It simply steps from one feature to the next as you slide it (i.e. an interval of two seconds is treated the same as an interval of two years). Thus, this first method actually will not work with LeafletSlider unless the time field is monotonically increasing, or very nearly so, from one feature to the next.]
Second, you could adapt another non-Leaflet-specific slider to do the job, like the jQRangeSlider, which has some pretty decent options for scales. Here is an example of that approach:
http://fiddle.jshell.net/nathansnider/p850sr8y/
In addition to the slider itself, it consists of a custom control, which allows you to place the slider on the map, and a function to filter the data, which is called each time the slider is moved. If you want further details on this, I'd be happy to elaborate.
I have a working highcharts area chart, I initialize it with almost no data in its series, just 4 series with one point each. Then I call:
function(output){
var chart = $('#mychart').highcharts();
chart.series[0].setData(output[0]);
chart.series[1].setData(output[1]);
chart.series[2].setData(output[2]);
chart.series[3].setData(output[3]);
}
That works perfectly fine. Later on, the data gets changed and I call that very same function again, and it works, but the problem lies in the amount of time it takes.
I set up logging to log the amount of time that this single function took. The first time it runs it takes about 140ms, the following times when it updates, it takes an average of 2 seconds.
Why does it take so long? Is there a way to speed this up or get around it?
Sorry to post this question, but I will leave this answer here for anyone who encounters the same problem:
The problem was the data I was using. In the first iteration, I was using a simple array:
[123,912]
The rest of the time, I was using an array of objects:
[{y: 123},{y: 912}]
For some reason, that equates to having a different load speed. From now on, if a fast performance is required, it seems you have to do your part to help highcharts. I hope this helps somebody else who comes across this problem.
I've got a whole set of graphs I produce from a financial model: each one has, say, 5-10 data series on it.
I now want to compare the outputs of two different models: they produce exactly equivalent data series, just with (probably) different numbers in them. I can see three ways of displaying a comparison:
have a graph just showing 2 series, one from each model. Allow the user to select which series to show. This is pretty easy to do, but has the disadvantage that it doesn't show any relationships there might be between series coming from the same model.
Have side by side graphs, one for each model. The highlighting is synchronized, so that the series highlighted on one is highlighted on the other, and the same x value is also highlighted. It seems that this is possible (see this question). This has the disadvantage that the two versions of the series you are most interested in at the moment (the one that is highlighted) are on different charts, so are more difficult to compare.
Have a graph showing all the series from both models. Use the same colors for the series, but have model 1 solid line and model 2 dotted line, say. When you highlight one series, its pair is also highlighted (presumably using the highlight callback). But is it possible to highlight two series at once? This would definitely be my preferred option, if it's possible.
So, is it possible to highlight two series at once? Or, alternatively, is there a better way to show the comparison?
It's not possible to highlight two series at once (in the sense of highlightSeriesOpts), but you can do something similar. When the selected series changes, call:
g.updateOptions({series: { otherSeriesName: { strokeWidth: 2 } })
Or however you want to indicate highlighting. You can do this using highlightCallback and unhighlightCallback.
I would like to make a scatter plot using D3 with the ability of only looking at a small section at a time using some sort of slider across the x-axis. Is there a method in javascript where I can efficiently buffer the data and quickly access the elements as the user scrolls left or right?
My goal is similar to this protovis example here, but with 10 times the amount of data. This example chokes when I make that many data points.
I have done a scatterplot with around 10k points where I needed to filter sections of the plot interactively.
I share a series of tips that worked for me, which I hope some may hopefully help you too:
Use a key function for your .data() operator as it is done at the end of this tutorial. The advantage of using keys is that you do not need to update elements that do not change.
Not related to d3, but I divided my data space into a grid, so that each data point is associated to a single cell (in other words each cell is an index to a set of points). In this way, when I needed to access from, let's say, from x_0 to x_1, I knew what cells I needed, and hence I could access a much more refined set of possible data points (avoiding iterating along all points).
Avoid transitions: from my personal experiences the .transition() is not very smooth when thousand of SVG elements are selected (it may be better now in newer versions or with faster processors)
In my case it was more convenient to make points invisible (.attr("display","none")) or visible rather than removing and creating SVG elements (I wonder if this is more time efficient too)
I want this highchart - http://jsfiddle.net/zPDca/ inside a popup. But if i decrease its width to lets say to 200 px, it dissapers. Any suggestions!
It looks like 251 px is the lower limit for the width.
This was probably a decision the developers made due to readability. Think about it:
This is a stock chart and it contains the "detail" view and a navigator view, you have export enabled and by default you are showing the buttons, the default selection buttons for zooming are also shown. Wouldn't this be really crowded for the user? Why not use a different kind of chart (standard highchart maybe) that shows latest data and gives user option to expand view. This would save a lot of space in the view.
Things you can try:
Remove the export buttons (you can write your own extension to still do exporting without useing the built-in buttons)
Remove the "Zoom" text
Change chart to be less "busy" overall
Having a data visualization is all about quickly seeing the data you need - not necessarily seeing all the options you may need in a tight space. If this chart is to be used for continuous monitoring you can strip it of all option settings but have it use the options set by the user in a "primary/setup" chart.
Look this example http://jsfiddle.net/zPDca/1/
It's working well.
If you take a look the reference you can see that it can be calculated by the containing element. So you just have to remove width from your chart as you can see on my example.
Okay I got the answer. Versions higher than 1.1.5 do not allow charts smaller than certain dimension. I do not know why. But I'm detouring right now by using version 1.1.5.