New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding point always appends instead of placing in the middle #1109

Closed
SujayKrishna opened this Issue Jul 13, 2012 · 13 comments

Comments

Projects
None yet
5 participants
@SujayKrishna

SujayKrishna commented Jul 13, 2012

It'd be great to have a function that would just not append the point to the series, and rather insert it at a particular index or x value.
This would be very useful for adding points on click event.
I already checked the forum and saw a few posts on the same line.
Including one that came up first on search.

Adding point in middle of series breaks tooltips, navigator?

Cheers,
Sujay

@TorsteinHonsi

This comment has been minimized.

Collaborator

TorsteinHonsi commented Jul 30, 2012

You can add points at a given x value. If an x value is not given, the point is appended.

series.addPoint({
x: 5,
y: 5
});

Edit: demo:

  1. Open http://jsfiddle.net/highcharts/bxm4W/
  2. Click the button

Expected: the new point to be spliced into the middle of the data

@SujayKrishna

This comment has been minimized.

SujayKrishna commented Aug 1, 2012

@highslide-software I think you've misunderstood the question. Adding a point at a particular x is not the problem.
The problem is that Highcharts extrapolates from the last point to the added point. I want to add it in the middle rather.
For this, we're currently doing as you have mentioned in the forum post link provided,

Highstock expects data to be ordered, so if you need to add a point in the middle you must add it to the raw data array, sort it then run setData.

This works fine, but then is quite slow on older browsers when we have around 5 years of data.

@SujayKrishna

This comment has been minimized.

SujayKrishna commented Feb 11, 2013

@highslide-software Please let me know if there is a easier solution than to add a point, sort and then use setData.
The above method works fine in most cases, but is visibly slow when the series has daily data for more than 5 years.

Thanks,
Sujay

@TorsteinHonsi

This comment has been minimized.

Collaborator

TorsteinHonsi commented Feb 12, 2013

I'm sorry, currently I don't know another way. You might be able to splice it into the options.data array, but you will have to run setData anyway.

@SujayKrishna

This comment has been minimized.

SujayKrishna commented Feb 12, 2013

Is there any plans of working on such a feature in the future?

@TorsteinHonsi

This comment has been minimized.

Collaborator

TorsteinHonsi commented Feb 12, 2013

I'll see what I can do...

@TorsteinHonsi

This comment has been minimized.

Collaborator

TorsteinHonsi commented Feb 12, 2013

I was able to get some part of the way by splicing in the new point instead
of pushing it:

// Get options and push the point to xData, yData and series.options. In
series.generatePoints
// the Point instance will be created on demand and pushed to the
series.data array.
 point = { series: series };
series.pointClass.prototype.applyOptions.apply(point, [options]);
 // Get the insertion point
i = xData.length;
 if (series.requireSorting && point.x < xData[i - 1]) {
while(i && xData[i - 1] > point.x) {
 i--;
}
}

xData.splice(i, 0, point.x);
yData.splice(i, 0, series.toYData ? series.toYData(point) : point.y);
 zData.splice(i, 0, point.z);
dataOptions.splice(i, 0, options);

However it seems like the point is not picked up...

@SujayKrishna

This comment has been minimized.

SujayKrishna commented Feb 12, 2013

I guess we'll have to live with the current way of doing it for now.
No worries.
Thanks for all the efforts.

@tlyakhov

This comment has been minimized.

tlyakhov commented Jul 31, 2013

After some research and experimentation, this seems to work for me. Anybody see issues with this?

hcInsertPoint = function(series, options, redraw) {
    // Get options and push the point to xData, yData and series.options. In series.generatePoints
    // the Point instance will be created on demand and pushed to the series.data array.
    var point = { series: series };
    series.pointClass.prototype.applyOptions.apply(point, [options]);
    // Get the insertion point
    var i = series.xData.length;
    if (series.requireSorting && point.x < series.xData[i - 1]) {
        while(i && series.xData[i - 1] > point.x) {
            i--;
        }
    }

    series.xData.splice(i, 0, point.x);
    series.yData.splice(i, 0, series.toYData ? series.toYData(point) : point.y);
    series.zData.splice(i, 0, point.z);
    if (series.names && point.name) {
        series.names[point.x] = point.name;
    }
    series.options.data.splice(i, 0, options);
    series.data.splice(i, 0, null);

    series.processData();
    series.generatePoints();

    // redraw
    series.isDirty = true;
    series.isDirtyData = true;
    series.chart.isDirtyBox = true;
    if (redraw) {
        series.getAttribs(); // #1937
        series.chart.redraw();
    }
};
@tellnes

This comment has been minimized.

tellnes commented Aug 8, 2013

Thanks @tlyakhov, this works great. I'll hope this goes into the library.

@TorsteinHonsi TorsteinHonsi reopened this Aug 9, 2013

@SujayKrishna

This comment has been minimized.

SujayKrishna commented Aug 30, 2013

@highslide-software since this has been re-opened, can we expect a similar method(like @tlyakhov's) from you soon?

TorsteinHonsi added a commit that referenced this issue Sep 4, 2013

Fixed issue where running addPoint with an X value not being able to …
…insert the point into the middle of a sorted series. Closes #1109.
@bazineta

This comment has been minimized.

bazineta commented Jan 10, 2014

Ran into an issue with this today with the latest release (of yesterday). The revised addPoint() function doesn't work in that while it places the new point in the correct spot, all points to the right of the new point are missing. Examining the series.data array at the end of addPoint(), I see a null in the middle of the array, at the insertion point.

The hcInsertPoint function above still works if

series.zData.splice(i, 0, point.z);

is removed.

Not sure what's wrong here.

@bazineta

This comment has been minimized.

bazineta commented Jan 11, 2014

Further investigation of my problem with addPoint() in the middle of a series leads me to this line in addPoint():

series.updateParallelArrays(point, 'splice', i); // insert undefined item

Which, in updateParallelArrays(), results in the series.[x|y]Data being truncated at i in the splice call. If I change this call to:

series.updateParallelArrays(point, 'splice', i, 0, 0); // insert undefined item

Then things work as desired. Probably not the best approach, but seems to resolve my issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment