How to stop chartjs zoom more than visible points?

1.8k views Asked by At

Can i limit chartjs to stop zooming if there are no points in selected area? Please find the image below.

enter image description here

As you can see, there is one month gap between two points on xaxis and if I try to zoom in there, it goes on and on. Find the image below.

enter image description here

I don't want it to happen. when the user tries to zoom in on certain points, I want the chart to stop zooming at those two points. one on the extreme left and the other is on the extreme right.

My chart config is as follows:

scales: {
                    yAxes: [
                        {
                            id: 'yAxis',
                            ticks: {
                                autoSkip: true,
                                maxTicksLimit: 10,
                                beginAtZero: true,
                            },
                        },
                    ],
                    xAxes: [
                        {
                            distribution: 'linear',
                            type: "time",
                            time: {
                                min: range_min.getTime(),
                                max: range_max.getTime(),
                                unit: "day",
                                unitStepSize: 1,
                                displayFormats: {
                                    day: '\nDD/MM/YYYY hh:mm a\n'
                                },
                            },
                            id: 'xAxis',
                            ticks: {
                                autoSkip: true,
                            }
                        },
                    ],
                },
                pan: {
                    enabled: false,
                    mode: "x",
                    speed: 1,
                    threshold: 1,
                },
                zoom: {
                    enabled: true,
                    drag: true,
                    sensitivity: 0.5,
                    mode: "x",
                    rangeMax: {
                        x: end_date,
                    },
                    rangeMin: {
                        x: start_date,
                    }
                },
1

There are 1 answers

0
The Lost JavaScripter On

In case anyone facing about the same issue, I found a solution to this. After zoom, we can set the chart to its closest left and right points by overriding its original zoom functionality in onZoom function. please find the answer.

         zoom: {
                    enabled: true,
                    drag: true,
                    sensitivity: 0.5,
                    mode: "x",
                    threshold: 0,
                    rangeMax: {
                        x: end_date,
                    },
                    rangeMin: {
                        x: start_date,
                    },
                    onZoom: function () {
                        debugger
                        console.log("zoom");
                        var leftEnd = myChartRef.current.chartInstance.getDatasetMeta(0).dataset._scale.chart.scales['xAxis']._table[0].time;
                        var rightEnd = myChartRef.current.chartInstance.getDatasetMeta(0).dataset._scale.chart.scales['xAxis']._table[1].time;

                        var labels = myChartRef.current.chartInstance.chart.config.data.labels


                        var closestleft = labels.reduce(function (prev, curr) {
                            return (Math.abs(curr - leftEnd) < Math.abs(prev - leftEnd) ? curr : prev);
                        });
                        var closestRight = labels.reduce(function (prev, curr) {
                            return (Math.abs(curr - rightEnd) > Math.abs(prev - rightEnd) ? curr : prev);
                        });
                        myChartRef.current.chartInstance.options.scales.xAxes[0].time.min = closestleft
                        myChartRef.current.chartInstance.options.scales.xAxes[0].time.max = closestRight
                        myChartRef.current.chartInstance.update()

                        console.log(leftEnd)
                        console.log(rightEnd)
                    }
                },

Kudos!