Petr Perner
Petr Perner

Reputation: 25

Highcharts dynamically restrict dragging limits

I'd like to dynamically restrict dragging limits (different limits for each point). I tried this (ending with error):

chart.series[1].update({dragMinY: 80});

http://jsfiddle.net/petiska/6g9tqrh5/2/

var chart = new Highcharts.Chart({
    chart: {
        renderTo: 'container',
        zoomType: 'xy',
        animation: false,
        type: 'line',
    },
    title: {
        text: 'Highcharts draggable points demo'
    },
    xAxis: [{
        categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
    },{linkedTo:0, offset:-128.5, lineWidth: 1, tickInterval: 10, zIndex:4}],
    yAxis: [{},{linkedTo:0,tickInterval:9.1}],
    plotOptions: {     
        series: {
            dataLabels:{useHTML: true},
            point: {
                events: {
                    drag: function (e) {
                        $('#drag').html('Dragging <b>' + this.series.name + '</b>, <b>' + this.category + '</b> to <b>' + Highcharts.numberFormat(e.y, 2) + '</b>');
                        //console.log(e);
                        //console.log(e.target)
                        //console.log(e.dragStart.x);
                        var point_index=e.target.index;
                        var point_oldX=e.dragStart.x;
                        var point_oldY=e.dragStart.y;
                        var point_newX=e.x;
                        var point_newY=e.y;
                        chart.series[1].update({dragMinY: 80});
                    },
                    drop: function () {
                        $('#drop').html('In <b>' + this.series.name + '</b>, <b>' + this.category + '</b> was set to <b>' + Highcharts.numberFormat(this.y, 2) + '</b>');
                        console.log("drop!")
                    }
                }
            },
            stickyTracking: false
        },
        line: {
            cursor: 'ns-resize'
        }
    },
    tooltip: {
        yDecimals: 2
    },
    series: [
        {
            type: "treemap",
            layoutAlgorithm: 'stripes',
            alternateStartingDirection: true,
            //  allowDrillToNode: true,
            data: [{id: "NS",name: 'NS_area', value:5},
                   {id: "NS_ABCDE",name: 'NS_ABCDE',value: 6,parent: 'NS'},
                   {id: "NSA",name: 'NSA',value: 1,parent: 'NS_ABCDE'},
                   {id: "A5",name: 'A5',value: 1,parent: 'NSA'},
                   {id: "A4",name: 'A4',value: 1,parent: 'NSA'},
                   {id: "A3",name: 'A3',value: 1,parent: 'NSA'},
                   {id: "A2",name: 'A2',value: 1,parent: 'NSA'},
                   {id: "A1",name: 'A1',value: 1,parent: 'NSA'},
                   {id: "A0",name: 'A0',value: 1,parent: 'NSA'},
                   {id: "NSB",name: 'NSB',value: 1,parent: 'NS_ABCDE'},
                   {id: "B5",name: 'B5',value: 1,parent: 'NSB'},
                   {id: "B4",name: 'B4',value: 1,parent: 'NSB'},
                   {id: "B3",name: 'B3',value: 1,parent: 'NSB'},
                   {id: "B2",name: 'B2',value: 1,parent: 'NSB'},
                   {id: "B1",name: 'B1',value: 1,parent: 'NSB'},
                   {id: "B0",name: 'B0',value: 1,parent: 'NSB'},
                   {id: "NSC",name: 'NSC',value: 1,parent: 'NS_ABCDE'},
                   {id: "C5",name: 'C5',value: 1,parent: 'NSC'},
                   {id: "C4",name: 'C4',value: 1,parent: 'NSC'},
                   {id: "C3",name: 'C3',value: 1,parent: 'NSC'},
                   {id: "C2",name: 'C2',value: 1,parent: 'NSC'},
                   {id: "C1",name: 'C1',value: 1,parent: 'NSC'},
                   {id: "C0",name: 'C0',value: 1,parent: 'NSC'},
                   {id: "NSD",name: 'NSD',value: 1,parent: 'NS_ABCDE'},
                   {id: "D5",name: 'D5',value: 1,parent: 'NSD'},
                   {id: "D4",name: 'D4',value: 1,parent: 'NSD'},
                   {id: "D3",name: 'D3',value: 1,parent: 'NSD'},
                   {id: "D2",name: 'D2',value: 1,parent: 'NSD'},
                   {id: "D1",name: 'D1',value: 1,parent: 'NSD'},
                   {id: "D0",name: 'D0',value: 1,parent: 'NSD'},
                   {id: "NSE",name: 'NSE',value: 1,parent: 'NS_ABCDE'},
                   {id: "E5",name: 'E5',value: 1,parent: 'NSE'},
                   {id: "E4",name: 'E4',value: 1,parent: 'NSE'},
                   {id: "E3",name: 'E3',value: 1,parent: 'NSE'},
                   {id: "E2",name: 'E2',value: 1,parent: 'NSE'},
                   {id: "E1",name: 'E1',value: 1,parent: 'NSE'},
                   {id: "E0",name: 'E0',value: 1,parent: 'NSE'},
                   {id: "NS_NP1",name:" ",value: 1,parent: 'NS',color: "#FFFFFF"},  //this is only to display division lines, any id can be used - not accessed
                   {id: "NS_NP11",name: " ",value: 1,parent: 'NS_NP1'},
                   {id: "NS_NP11",name: " ",value: 1,parent: 'NS_NP1'},
                   {id: "NS_NP11",name: " ",value: 1,parent: 'NS_NP1'},
                   {id: "NS_NP11",name: " ",value: 1,parent: 'NS_NP1'},
                   {id: "NS_NP11",name: " ",value: 1,parent: 'NS_NP1'},
                   {id: "NS_NP2",name:" ",value: 1,parent: 'NS',color: "#FFFFFF"},
                   {id: "NS_NP11",name: " ",value: 1,parent: 'NS_NP2'},
                   {id: "NS_NP11",name: " ",value: 1,parent: 'NS_NP2'},
                   {id: "NS_NP11",name: " ",value: 1,parent: 'NS_NP2'},
                   {id: "NS_NP11",name: " ",value: 1,parent: 'NS_NP2'},
                   {id: "NS_NP11",name: " ",value: 1,parent: 'NS_NP2'},
                   {id: "NS_NP3",name:" ",value: 1,parent: 'NS',color: "#FFFFFF"},
                   {id: "NS_NP4",name:" ",value: 1,parent: 'NS',color: "#FFFFFF"},
                   {id: "NS_NP5",name:" ",value: 1,parent: 'NS',color: "#FFFFFF"},                
                   //{id: "NS_NP",name:" ",value: 5,parent: 'NS',color: "#FFFFFF"},
                   {id: "LT",name: 'LT',value:3},
                   {id: "LT_FGH",value: 7,parent: 'LT'},
                   {id: "LT_FGH_R",parent: 'LT_FGH'},       //force to divide horizontaly or vertically, R-reverse
                   {id: "F",value: 6,parent: 'LT_FGH_R'},
                   {id: "LT_GH",value: 1,parent: 'LT_FGH_R'},
                   {id: "G",value: 2,parent: 'LT_GH'},
                   {id: "H",value: 1,parent: 'LT_GH'},   
                   {id: "LT_NP",name:" ",value: 2,parent: 'LT',color: "#FFFFFF"},
                   {id: "LT_NP1",name:" ",value: 1,parent: 'LT_NP'},    //this is only to display division lines
                   {id: "LT_NP2",name:" ",value: 1,parent: 'LT_NP'},    //this is only to display division lines
                   {id: "LT_NP3",name:" ",value: 1,parent: 'LT_NP'},    //this is only to display division lines
                   {id: "LT_IJK",value: 2,parent: 'LT'},
                   {id: "LT_I",value: 1,parent: 'LT_IJK'},
                   {id: "I0",value: 2,parent: 'LT_I'},
                   {id: "I1",value: 2,parent: 'LT_I'},
                   {id: "LT_J",value: 1,parent: 'LT_IJK'},
                   {id: "J0",value: 2,parent: 'LT_J'},
                   {id: "J1",value: 2,parent: 'LT_J'},
                   {id: "LT_K",value: 1,parent: 'LT_IJK'},
                   {id: "K0",value: 2,parent: 'LT_K'},
                   {id: "K1",value: 2,parent: 'LT_K'},            
                   {id: "SL",name: 'SL',value:1},
                   {id: "C",name: 'C',value:1},
                  ]
        },{
            data: [[0, 90.9], [10,81.81], [20,72.72], [30,63.63],[40,63.63],[50,45.45],[70,45.45],[80,36.36],[85,35],[95,33],[100,33]],
            step: 'left',
            type: 'line',
            yAxis: 0,
            xAxis: 0,
            draggableX: true,
            draggableY: true,
            dragMaxY: 90.9,
            dragMinY: 30,

        },
    ]
});
<script src="https://code.highcharts.com/highcharts.js"></script>
<script src="https://rawgithub.com/highcharts/draggable-points/master/draggable-points.js"></script>
<script src="https://code.highcharts.com/highcharts-more.js"></script>
<script src="https://code.highcharts.com/modules/exporting.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.highcharts.com/modules/treemap.js"></script>

<div id="container" style="height: 600px"></div>
<div id="drag"></div>
<div id="drop"></div>
<button onclick="drawsomething()">Click me</button>

Upvotes: 1

Views: 692

Answers (1)

Halvor Holsten Strand
Halvor Holsten Strand

Reputation: 20536

As an example of handling dragMinY and dragMaxY more dynamically I've slightly modified draggable-points.js, essentially allowing for a dragMin and dragMax function instead (or rather, it has higher priority than dragMinY and dragMaxY). The functions dragMin and dragMax get two parameters, XorY specifying the axis and point, being the dragged point.

The change is to the following functions signature and functionality:

/**
 * Filter by dragMin and dragMax
 */
function filterRange(newY, point, series, XOrY) {
    var options = series.options,
        dragMin = pick(options.dragMin ? options.dragMin(XOrY, point) : undefined, options['dragMin' + XOrY], undefined),
        dragMax = pick(options.dragMax ? options.dragMax(XOrY, point) : undefined, options['dragMax' + XOrY], undefined),
        precision = pick(options['dragPrecision' + XOrY], undefined);

    if (!isNaN(precision)) {
        newY = Math.round(newY / precision) * precision;
    }

    if (newY < dragMin) {
        newY = dragMin;
    } else if (newY > dragMax) {
        newY = dragMax;
    }
    return newY;
}

The product can be seen here: GitRaw GitHub

Or in this JSFiddle example, where the drag is limited on X between the left and right neighbor, and Y lower than left and higher than right neighbor, as in the below example code:

var chart = new Highcharts.Chart({
    chart: {
        renderTo: 'container',
    },
    series: [{
        data: [[0, 90.9], [10,81.81], [20,72.72], [30,63.63],[40,63.63],[50,45.45],[70,45.45],[80,36.36],[85,35],[95,33],[100,33]],
        step: 'left',
        type: 'line',
        draggableX: true,
        draggableY: true,
        dragMin: function(XorY, point) {
            leftPoint = point.series.data[point.index-1];
            rightPoint = point.series.data[point.index+1];
            if('X' == XorY) {
                // Strictly higher than left point, if any
                if(leftPoint) {
                    return leftPoint.x + 1;
                }
                return undefined;
            }
            else {
                // Lower than right point, if any
                if(rightPoint) {
                    return rightPoint.y;
                }
                return undefined;
            }
        },
        dragMax: function(XorY, point) {
            leftPoint = point.series.data[point.index-1];
            rightPoint = point.series.data[point.index+1];
            if('X' == XorY) {
                // Strictly lower than right point, if any
                if(rightPoint) {
                    return rightPoint.x - 1;
                }
                return undefined;
            }
            else {
                // Higher than left point, if any
                if(leftPoint) {
                    return leftPoint.y;
                }
                return undefined;
            }
        }
    }]
});

Note that I've simply edited the code created by Torstein Honsi of Highsoft under the MIT License.

Upvotes: 1

Related Questions