locked
Reset zoom from chartjs-plugin-zoom only work for one single chart [MVC] RRS feed

  • Question

  • User-1313071134 posted

    Hi all,

    I am trying to implement the zoom/pan feature which is a plugin from chartjs-plugin-zoom. In my MVC application, I have multiple charts and I want to implement the zoom and pan button inspired from this example In a way that It can independently work on multiple charts, so I can enable zooming mode whenever needed and zoom in and out.

    Below is my code:

    <div>
        <div style="width: 50%;  float: left; background-color: lightblue">
            <button onclick="resetZoom()">Reset Zoom</button>
            <button id="drag-switch" onclick="toggleDragMode()">Disable drag mode</button>
            <canvas id="canvasAccl"></canvas>
        </div>
        <div style="width: 50%;  float: right; background-color: lightcyan">
            <button onclick="resetZoom()">Reset Zoom</button>
    <button id="drag-switch" onclick="toggleDragMode()">Disable drag mode</button> <canvas id="canvasYPR"></canvas> </div> </div>

    Function 1 (to plot the first chart) is below:
    function procAcclData(xhttp, sensorid) {
    
                var canvas = document.getElementById('canvasAccl');
                var ctx = document.getElementById('canvasAccl').getContext('2d');
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                if (xhttp.status >= 200 && xhttp.status < 400) {
    
                    var data = JSON.parse(xhttp.response);
    
                    if (data.length > 0)
                        addDataStatRecord("Accelrometer", data.length, data[0].TimeId, data[data.length - 1].TimeId);
                    else
                        addDataStatRecord("Accelrometer", 0, "NA", "NA");
    
                    // copy data to x and y axes arrays.
                    data.forEach(datapoint => {
                        Accel_x.push(datapoint.TimeId);
                        Accel_y.push(datapoint.SensorValue / 16384.0);
                    });
    
                    window.myLine = new Chart(ctx,
                        {
                            type: 'line',
                            data: {
                                labels: Accel_x,
                                datasets: [
                                    {
                                        label: 'Accelrometer in g',
                                        data: Accel_y,
                                        fill: false,
                                        lineTension: 0.1,
                                        backgroundColor: "rgba(60, 145, 230, 1)",
                                        borderColor: "rgba(60, 145, 230, 1)",
                                        borderCapStyle: 'butt',
                                        borderDash: [],
                                        borderWidth: 0.3
                                    }
                                ]
                            },
                            options: {
                                showLines: false,
                                scales: {
                                    yAxes: [
                                        {
                                            type: 'linear',
                                            position: 'left',
                                            ticks: {
                                                beginAtZero: true
                                            }
                                        }
                                    ]
                                },
                                plugins: {
                                    zoom: {
                                        // Container for pan options
                                        pan: {
                                            // Boolean to enable panning
                                            enabled: true,
    
                                            // Panning directions. Remove the appropriate direction to disable
                                            // Eg. 'y' would only allow panning in the y direction
                                            mode: 'xy'
                                        },
    
                                        // Container for zoom options
                                        zoom: {
                                            // Boolean to enable zooming
                                            enabled: true,
    
                                            // Zooming directions. Remove the appropriate direction to disable
                                            // Eg. 'y' would only allow zooming in the y direction
                                            mode: 'xy',
                                        }
                                    }
                                }
                            }
                        });
                    window.resetZoom = function () {
                        window.myLine.resetZoom();
                    };
                    window.toggleDragMode = function () {
                        var zoomOptions = window.myLine.options.plugins.zoom.zoom;
                        zoomOptions.drag = zoomOptions.drag ? false : dragOptions;
                        window.myLine.update();
                        document.getElementById('drag-switch').innerText = zoomOptions.drag ? 'Disable drag mode' : 'Enable drag mode';
                    };
                    window.onload = function () {
                        ctx = document.getElementById("canvasAccl").getContext("2d");
                        buildChart();
                    };
    
    
                } else {
                    ctx.font = '48px serif';
                    ctx.fillText('http status:' + xhttp.status, 10, 50);
                }
            }

    Function 2 (to plot the second chart) is shown below:

    function procCH4Data(xhttp, sensorid) {
    
                var canvas = document.getElementById('canvasCH4');
                var ctx = canvas.getContext('2d');
                ctx.clearRect(0, 0, canvas.width, canvas.height);
    
                if (xhttp.status >= 200 && xhttp.status < 400) {
    
                    var data = JSON.parse(xhttp.response);
                    console.log("procCh4Data: len=" + data.length);
                    // copy data to x and y axes arrays.
                    if (data.length > 0)
                        addDataStatRecord("CH4", data.length, data[0].TimeId, data[data.length - 1].TimeId);
                    else
                        addDataStatRecord("CH4", 0, "NA", "NA");
    
                    data.forEach(datapoint => {
    
                        Ch4_x.push(datapoint.TimeId);
                        Ch4_y.push(datapoint.SensorValue / 16384.0);
                    });
    
    
                    var myChart = new Chart(ctx,
                        {
                            type: 'line',
                            data: {
                                labels: Ch4_x,
                                datasets: [
                                    {
                                        label: 'CH4 %',
                                        data: Ch4_y,
                                        fill: false,
                                        lineTension: 0.1,
                                        backgroundColor: "rgba(255, 105, 17, 1)",
                                        borderColor: "rgba(255, 105, 17, 1)",
                                        borderCapStyle: 'butt',
                                        borderDash: [],
                                        borderWidth: 0.3
                                    }
                                ]
                            },
                            options: {
                                showLines: false,
                                scales: {
                                    yAxes: [
                                        {
                                            type: 'linear',
                                            position: 'left',
                                            ticks: {
                                                beginAtZero: true
                                            }
                                        },
                                    ]
                                },
                                plugins: {
                                    zoom: {
                                        // Container for pan options
                                        pan: {
                                            // Boolean to enable panning
                                            enabled: true,
    
                                            // Panning directions. Remove the appropriate direction to disable
                                            // Eg. 'y' would only allow panning in the y direction
                                            mode: 'xy'
                                        },
    
                                        // Container for zoom options
                                        zoom: {
                                            // Boolean to enable zooming
                                            enabled: true,
    
                                            // Zooming directions. Remove the appropriate direction to disable
                                            // Eg. 'y' would only allow zooming in the y direction
                                            mode: 'xy',
                                        }
                                    }
                                }
                            }
                        });
                    window.resetZoom = function () {
                        window.myLine.resetZoom();
                    };
                    window.toggleDragMode = function () {
                        var zoomOptions = window.myLine.options.plugins.zoom.zoom;
                        zoomOptions.drag = zoomOptions.drag ? false : dragOptions;
                        window.myLine.update();
                        document.getElementById('drag-switch').innerText = zoomOptions.drag ? 'Disable drag mode' : 'Enable drag mode';
                    };
                    window.onload = function () {
                        ctx = document.getElementById("canvasCH4").getContext("2d");
                        buildChart();
                    };
    
                } else {
                    ctx.font = '48px serif';
                    ctx.fillText('http status:' + xhttp.status, 10, 50);
                }
            }

    Sorry for the long code. I also have other charts too but I only showed 2 to avoid making the thread even longer than that.

    The current code only works for one chart, in fact by clicking "Reset Zoom" on the second chart will reset on the first chart, making all the buttons work for one particular chart. It looks like the code only picks up the function for "Reset Zoom" and "Enable/Disable Drag Mode" for the first chart. I am not sure how to duplicate it for the second chart and making it independent.

    I look forward for your help and assistance. Please don't hesitate to ask me for more clarification.

    Sami

    Monday, November 30, 2020 9:22 AM

Answers

  • User1686398519 posted

    Hi samiarja, 

    1. Because both resetZoom and toggleDragMode in your second chart (myChart) are setting the first chart (window.myLine), so when you click the button of the second chart, the first chart changes.
      • You can check this picture (at the end) to help you understand the cause of the problem.
    2. You can modify the code of your second chart like this:
      1. var myChart = new Chart(ctx,
        • window.myLine2 = new Chart(ctx,
      2.                 window.resetZoom = function () {
                            window.myLine.resetZoom();
                        };
                        window.toggleDragMode = function () {
                            var zoomOptions = window.myLine.options.plugins.zoom.zoom;
                            zoomOptions.drag = zoomOptions.drag ? false : dragOptions;
                            window.myLine.update();
                            document.getElementById('drag-switch').innerText = zoomOptions.drag ? 'Disable drag mode' : 'Enable drag mode';
                        };
        • window.resetZoom = function () { 
          window.myLine2.resetZoom();
          };
          window.toggleDragMode = function () {
          var zoomOptions = window.myLine2.options.plugins.zoom.zoom;
          zoomOptions.drag = zoomOptions.drag ? false : dragOptions;
          window.myLine2.update();
          document.getElementById('drag-switch').innerText = zoomOptions.drag ? 'Disable drag mode' : 'Enable drag mode';
          };
    3. Note: If you have multiple charts, and you want each chart to be able to resetZoom independently, you can refer to the first example I gave in this post.

    Best Regards,

    YihuiSun

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, December 2, 2020 2:46 AM

All replies

  • User-474980206 posted

    You have several bugs. Both buttons call the same code, so they perform the same logic. Each chart redefines methods on window, so the methods are what the  the last chart defines. The reset zoom methods explicitly references the first chart, 

    Monday, November 30, 2020 3:37 PM
  • User1686398519 posted

    Hi samiarja, 

    1. Because both resetZoom and toggleDragMode in your second chart (myChart) are setting the first chart (window.myLine), so when you click the button of the second chart, the first chart changes.
      • You can check this picture (at the end) to help you understand the cause of the problem.
    2. You can modify the code of your second chart like this:
      1. var myChart = new Chart(ctx,
        • window.myLine2 = new Chart(ctx,
      2.                 window.resetZoom = function () {
                            window.myLine.resetZoom();
                        };
                        window.toggleDragMode = function () {
                            var zoomOptions = window.myLine.options.plugins.zoom.zoom;
                            zoomOptions.drag = zoomOptions.drag ? false : dragOptions;
                            window.myLine.update();
                            document.getElementById('drag-switch').innerText = zoomOptions.drag ? 'Disable drag mode' : 'Enable drag mode';
                        };
        • window.resetZoom = function () { 
          window.myLine2.resetZoom();
          };
          window.toggleDragMode = function () {
          var zoomOptions = window.myLine2.options.plugins.zoom.zoom;
          zoomOptions.drag = zoomOptions.drag ? false : dragOptions;
          window.myLine2.update();
          document.getElementById('drag-switch').innerText = zoomOptions.drag ? 'Disable drag mode' : 'Enable drag mode';
          };
    3. Note: If you have multiple charts, and you want each chart to be able to resetZoom independently, you can refer to the first example I gave in this post.

    Best Regards,

    YihuiSun

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, December 2, 2020 2:46 AM
  • User-1313071134 posted

    thanks for the suggestion I am now looking for the example in the link you posted.

    Wednesday, December 2, 2020 7:39 AM