plainheart / echarts-extension-gmap

🌎 A Google Map (https://www.google.com/maps) extension for Apache ECharts (https://github.com/apache/echarts)
https://github.com/plainheart/echarts-extension-gmap
MIT License
48 stars 8 forks source link

The echart/zrender canvas is not resized when Google Map goes fullscreen. #14

Closed maeln closed 1 year ago

maeln commented 1 year ago

Hi !

I have an issue where the echart/zrender canvas onto which echart draw the points is not resized when Google Map goes fullscreen. This lead to an issue where part of the points become "hidden" because they are outside the canvas, but they are still whithin the map boundaries where they should be drawn. Here are some screenshots that might be more understandable:

1 When not in fullscreen, everything works as expected.

2 We can clearly see that the canvas cover the whole map.

But when we go fullscreen (using the google map fullscreen button) : 3

We clearly see that the canvas didn't change size (it gain a few pixel on the width but that's it), and only cover part of the map. This makes it so that the point are only visible on the part of the map that the canvas cover, and everything else is cutoff.

Is there anyway to fix this ? I use the latest version (1.5.0) with echart-for-react.

maeln commented 1 year ago

Ok, so I have been able to track down and replicate the issue. The issue come from how zrender compute the canvas resize. In Painter.js (in zrender/echart) you can find the function CanvasPainter.resize :

CanvasPainter.prototype.resize = function (width, height) {
        if (!this._domRoot.style) {
            if (width == null || height == null) {
                return;
            }
            this._width = width;
            this._height = height;
            this.getLayer(CANVAS_ZLEVEL).resize(width, height);
        }
        else {
            var domRoot = this._domRoot;
            domRoot.style.display = 'none';
            var opts = this._opts;
            var root = this.root;
            width != null && (opts.width = width);
            height != null && (opts.height = height);
            width = getSize(root, 0, opts);
            height = getSize(root, 1, opts);
            domRoot.style.display = '';
            if (this._width !== width || height !== this._height) {
                domRoot.style.width = width + 'px';
                domRoot.style.height = height + 'px';
                for (var id in this._layers) {
                    if (this._layers.hasOwnProperty(id)) {
                        this._layers[id].resize(width, height);
                    }
                }
                this.refresh(true);
            }
            this._width = width;
            this._height = height;
        }
        return this;
    };

This function call the getSize function, which do the following:

export function getSize(root, whIdx, opts) {
    var wh = ['width', 'height'][whIdx];
    var cwh = ['clientWidth', 'clientHeight'][whIdx];
    var plt = ['paddingLeft', 'paddingTop'][whIdx];
    var prb = ['paddingRight', 'paddingBottom'][whIdx];
    if (opts[wh] != null && opts[wh] !== 'auto') {
        return parseFloat(opts[wh]);
    }
    var stl = document.defaultView.getComputedStyle(root);
    return ((root[cwh] || parseInt10(stl[wh]) || parseInt10(root.style[wh]))
        - (parseInt10(stl[plt]) || 0)
        - (parseInt10(stl[prb]) || 0)) | 0;
}

It looks complex, but it basically more or less just get the width and height of the root div. This div is the root div which contains the map. The issue comes from when the container div has a size that is not the fullscreen size. The canvas will match this size no matter what instead of matching the fullscreen size. For exemple, if you take the default exemple codepen, it works with no issue because the root div has a width and height of 100% and has no parent except the body: https://codepen.io/plainheart/pen/VweLGbR

But if you update the codepen and change the style of the div to a fixed sized, you will be able to reproduce the issue: https://codepen.io/maeln/pen/XWxmPpe Try to go fullscreen and you should see all the point disappear unless you move the map so that they are in the left top corner.

A potential fix to this would be to pass the first child of the ec-extension-google-map to the resize function instead, since this one has an absolute position (so it doesn't depend on the parent sizing) and correctly resize to fullscreen: 4

maeln commented 1 year ago

Since the PR has been approved, I close this issue. Thanks @plainheart !

plainheart commented 1 year ago

Released v1.6.0 and published it to npm.