clientIO / joint

A proven SVG-based JavaScript diagramming library powering exceptional UIs
https://jointjs.com
Mozilla Public License 2.0
4.48k stars 839 forks source link

paper.scaleContentToFit not working when paper width is percentage #964

Closed iyobo closed 5 years ago

iyobo commented 5 years ago

I have a responsive jointjs graph and I have the width of the paper set to 100% i.e

var paper = new joint.dia.Paper({
            el: domNode
            width: '100%',
            height: 800,
            gridSize: 10,
            model: graphModel
        });

This works well and width scales responsively.. However when I do paper.scaleContentToFit();, I get an empty graph.

If I attempt to click into the empty graph dom, I get the error:

joint.min.js:53 Uncaught DOMException: Failed to execute 'inverse' on 'SVGMatrix': The matrix is not invertible.
    at child.clientToLocalPoint (http://localhost:4001/static/frontdash/index.bundle.dev.js:72909:29431)
    at child.snapToGrid (http://localhost:4001/static/frontdash/index.bundle.dev.js:72909:28601)
    at child.pointerclick (http://localhost:4001/static/frontdash/index.bundle.dev.js:72910:325)
    at executeBound (http://localhost:4001/static/frontdash/index.bundle.dev.js:24057:67)
    at HTMLDivElement.<anonymous> (http://localhost:4001/static/frontdash/index.bundle.dev.js:24070:14)
    at HTMLDivElement.<anonymous> (http://localhost:4001/static/frontdash/index.bundle.dev.js:23417:29)
    at HTMLDivElement.dispatch (http://localhost:4001/static/frontdash/index.bundle.dev.js:90507:27)
    at HTMLDivElement.elemData.handle (http://localhost:4001/static/frontdash/index.bundle.dev.js:90315:28)

obviously the stacktrace lines are being obfuscated by my bundler, but it is clear that paper does not know hot to handle scaling if the dimension [i.e width] is a percentage.

I suggest that, when doing this scaling, width and height should be grabbed from the DOM's actual width and height, as opposed to what may have been set when initializing the paper object.

This ensures responsive styling of the graph AND allows auto scaling.

kumilingus commented 5 years ago

We can introduce a method for getting paper dimensions. If the value is percentage we ask the DOM for the size. if it's a number we return this number.

In the meantime, you might also experiment with getters/setters as shown below.

Object.defineProperty(paper.options, 'width', {
  get: function() { return $(this.el).width(); }
});

paper.$el.css('width', '100%');

paper.scaleContentToFit();
kumilingus commented 5 years ago

Fixed by f40c4f2fe0e344afed759e5c964deb0f466583d7

frankie-zeng commented 2 months ago

How to handle the issue in 4.x version? image

kumilingus commented 2 months ago

Please provide a steps to reproduce.