Search code examples
javascripthighchartsdraggable

Dynamically set dragmax using dragable points for Highcharts


I am using highcharts with dragable points for highcharts. I want to be able to drag the chart points, but not past the next point. Their website shows demos of how dragMaxX can be set, but not dynamically: http://www.highcharts.com/plugin-registry/single/3/Draggable%20Points

This fiddle shows how I have set the Highchart settings, without setting dragMax : http://jsfiddle.net/AyUbx/3263/

I want to limit the user to not be able to drag a point past the next point. Something like this:

var thisX = this.series.xData.indexOf(this.x);
var nextX = this.series.xData[thisX+1];
this.series.dragMaxX = nextX;

Except this doesn't work. Does anyone know if this is possible or how it can be done? I have looked at the API for Highcharts but couldn't find something that worked.


Solution

  • I have changed this plugin a little bit to give you the possibility for setting max distance between points. I have added new parameter, named dragMaxToPoint, you can use it in series.

    Here you can see function I have changed:

    function getNewPos(e) {
      toClose = false;
      var originalEvent = e.originalEvent || e,
        pageX = originalEvent.changedTouches ? originalEvent.changedTouches[0].pageX : e.pageX,
        pageY = originalEvent.changedTouches ? originalEvent.changedTouches[0].pageY : e.pageY,
        series = dragPoint.series,
        draggableX = series.options.draggableX && dragPoint.draggableX !== false,
        draggableY = series.options.draggableY && dragPoint.draggableY !== false,
        dragSensitivity = pick(series.options.dragSensitiviy, 1),
        dragMaxToPoint = pick(series.options.dragMaxToPoint, 0.3),
        deltaX = draggableX ? dragX - pageX : 0,
        deltaY = draggableY ? dragY - pageY : 0,
        newPlotX = dragPlotX - deltaX,
        newPlotY = dragPlotY - deltaY,
        newX = dragX === undefined ? dragPoint.x : series.xAxis.toValue(newPlotX, true),
        newY = dragY === undefined ? dragPoint.y : series.yAxis.toValue(newPlotY, true),
        ret;
      newX = filterRange(newX, series, 'X');
      newY = filterRange(newY, series, 'Y');
      Highcharts.each(dragPoint.series.data, function(p, i) {
        if ((dragPoint.x - p.x) !== 0 && (dragPoint.y - p.y) !== 0) {
          if (Math.abs(newX - p.x) < dragMaxToPoint && Math.abs(newY - p.y) < dragMaxToPoint) {
            toClose = true;
          }
        }
      });
      if (!toClose && Math.sqrt(Math.pow(deltaX, 2) + Math.pow(deltaY, 2)) > dragSensitivity) {
        return {
          x: draggableX ? newX : dragPoint.x,
          y: draggableY ? newY : dragPoint.y
        };
      } else {
        return null;
      }
    }
    

    Here you can see an example how it can work: http://jsfiddle.net/AyUbx/3269/

    Best regards.

    EDIT: If you want to stop the drag if the point you are dragging gets a higher x value than the next point, you can change the same function a little bit. You can add if statement similar to:

      if (dragPoint.index > 0 && (newX - dragPoint.series.data[dragPoint.index - 1].x) < dragMaxToPoint || dragPoint.index < dragPoint.series.data.length - 1 && (newX - dragPoint.series.data[dragPoint.index + 1].x) > -dragMaxToPoint) {
        toClose = true;
      }
    

    Here you can see an example how it can work: http://jsfiddle.net/AyUbx/3270/