How to distinguish datazoom callback from drag or scroll in Echarts

Posted Jun 4, 20203 min read

demand

Use echarts to draw a curve of data for each hour of the week, and it can be zoomed by a scroll wheel. When not zoomed, the abscissa only displays the day(every other day). When zoomed to a certain extent, the full date is displayed, that is, yyyy-mm-dd hh-mm -ss this format.

effect

When the curve is not enlarged ?
Xnip2020-06-04_22-37-57.jpg

When the curve is enlarged to a certain degree ?
2.jpg

solve

Where is the pit of this demand? Originally, only the day was displayed from beginning to end, but when echarts zoomed to a certain degree, the abscissa and the data could not match. Remove the formatter and find that it was originally a regular 2020-05-27 00:00:00, 2020-05-28 00:00:00(27, 28 after the formatter, corresponding to the zero point data...)... But after zooming in, echarts automatically changed me to 2020-05-27 00:04:00, 2020-05-28 00:06:00(after formatter it is still 27, 28... but it does not correspond to zero point data)... All in all, in short, if the formatter, naturally, the time is not visible The number of seconds changes, so there is a situation where the data does not match.

After solving the person who raised the problem, the demand compromise became the full time after zooming in, but when I got started, I found that it was not so easy. The problem was with datazoom monitoring. Normally, echarts monitoring datazoom is like this:

this['echart' + this.id].on('datazoom', function(params) {
    //......
});

But although echarts gave datazoom params, but did not provide a zoom factor(?) I don’t quite understand it. I searched carefully and found that there is really no factor. I checked how others solved it, but I didn’t find it.

After some painful thinking, I am ready to judge by the scaled end-start:

let start = params.batch[0].start;
    let end = params.batch[0].end;
    let diff = end-start;
    //diff is less than 50, count as ‘zoom to a certain degree’
    if(diff <50) {
        let option = $this['echart' + $this.id].getOption();
        delete option.xAxis[0].axisLabel.formatter;
        $this['echart' + $this.id].clear();
        $this['echart' + $this.id].setOption(option, true);
    }
    if(diff >= 50) {
        let option = $this['echart' + $this.id].getOption();
        option.xAxis[0].axisLabel.formatter = function(value, index) {
            let str =(value.split(''))[0];
            str =(str.split('-'))[2];
            return str;
        };
        $this['echart' + $this.id].clear();
        $this['echart' + $this.id].setOption(option, true);
    }

I thought it was solved in this way. Who can think that after putting it on, the curve can't be dragged after zooming in? ? ?

After a bit of painful thinking and testing, I found a design that echarts does not understand(let's mention the issue!) Dragging the curve will also trigger the datazoom callback! I don’t know what was the original intention of this design at the beginning. I only know that I lost a lot of hair because of it... The dragging curve also triggered a callback, which caused the setOption to stop, and naturally there was no time to handle dragging.

The final solution

No way, after losing a handful of hair, I finally found the difference between drag and zoom params:the change range of start and end is very small, basically can be maintained between 0-1, that is, as long as the last record diff, and this time diff, then calculate the absolute value of the difference, if >1, it can be regarded as a zoom trigger, the code above:

let lastdiff = 0;
this['echart' + this.id].on('datazoom', function(params) {
    let start = params.batch[0].start;
    let end = params.batch[0].end;
    let diff = end-start;
    //mircodiff> 1, indicating zoom in instead of dragging
    let mircodiff = Math.abs(diff-lastdiff);
    if(diff <50 && mircodiff> 1) {
        //Operation after zooming in
    }
    if(diff >= 50 && mircodiff> 1) {
        //Operation to zoom back
    }
    lastdiff = diff;
});

to sum up

There are still a lot of echarts pits, and there is no answer online. I hope that students who have similar problems with me can see this article to quickly solve this problem and continue to develop the next requirement, instead of getting nothing after a long query ^ ^.