AlexeyBoiko / DgrmJS

Dgrm.net - flowchart editor. Works on desktop, phone and tablet. Has no dependency. Pure JavaScript.
https://dgrm.net
Apache License 2.0
913 stars 83 forks source link

defensive check #6

Closed tbo47 closed 2 years ago

tbo47 commented 2 years ago

This bug happens when there is nothing on the diagram and we want to catch the update event.

AlexeyBoiko commented 2 years ago

Hello, thank you for the pull request. Please provide reproduce steps for the bug.

AlexeyBoiko commented 2 years ago

Hello, thank you for the pull request. Please provide reproduce steps for the bug.

tbo47 commented 2 years ago
  1. in src/app/index.js:30 use const diagram = svgDiagramCreate(svg, null).on('select', select); to use SvgShape and try to catch the update event
  2. when clicking on an empty diagram you will have an error stack in devTools
AlexeyBoiko commented 2 years ago

Can't reproduce. I try this:

const svg = document.getElementById('diagram');
const diagram = svgDiagramCreate(svg, null)
    .on('select', evt => console.log(evt));

Then click on svg DOM Element in browser -> no errors.

Please provide full code. I don't understend how to:

use SvgShape and try to catch the update event

tbo47 commented 2 years ago
const svg = document.getElementById('diagram');
const diagram = svgDiagramCreate(svg, null)
    .on('select', (evt) => {
        evt.detail.target.update({
            props: {
                text: { textContent: 'New title' }
            }
        })
    });

causes this error

svg-shape.js:113 Uncaught TypeError: Cannot read properties of null (reading 'x')
    at textParamsParse (svg-shape.js:113:13)
    at svg-shape.js:96:8
    at Array.forEach (<anonymous>)
    at svg-shape.js:91:29
    at Array.forEach (<anonymous>)
    at Function._attrsSet (svg-shape.js:86:22)
    at SvgShape.update (svg-shape.js:69:13)
    at Diagram.<anonymous> (index.js:36:21)
    at Diagram._dispatchEvent (diagram.js:253:15)
    at Diagram._selectedSet (diagram.js:172:9)
AlexeyBoiko commented 2 years ago

It is not a bug. Your code calls a function update with wrong arguments. Canvas element realy have no inner svg-element with data-key="text".

const diagram = svgDiagramCreate(svg, null)
    .on('select', /** @param {CustomEvent<IDiagramEventSelectDetail<IPresenterShape>> } evt */ evt => {
        switch (evt.detail.target.type) {
            case 'canvas':
                // when click on empty space
                console.log('select canvas');
                break;
            case 'shape':

                // Note:
                //  not all shapes must have inner svg-element with 'data-key="text"',
                //  you have to be sure that evt.detail.target can process props that you try to update
                evt.detail.target.update({
                    props: {
                        // update 'textContent' value of the inner element with 'data-key="text"'
                        text: { textContent: 'New title' }
                    }
                });
                break;
        }
    });

If you want to update different props for different shapes -> you can use evt.detail.target as a key to get concrete shape:

const diagram = svgDiagramCreate(svg)
    .on('select', /** @param {CustomEvent<IDiagramEventSelectDetail<IPresenterShape>> } evt */ evt => {
        if (evt.detail.target === shape1) {
            // update shape
            shape1.update({
                props: {
                    circle: { fill: '#ff6600' }
                }
            });
        } else if (evt.detail.target === shape2) {
            // delete shape
            diagram.shapeDel(shape2);
        } else { console.log('canvas selected'); }
    });

// add shape
const shape1 = diagram.shapeAdd(...);

// add second shape
const shape2 = diagram.shapeAdd(...);

Full example - https://github.com/AlexeyBoiko/DgrmJS-Example

You can store shapes in a Set or Map. dgrm.net uses Map:

const shapeData = new Map();
shapeData.set(shape1, ...)

// to get a shape 
 shapeData.get(evt.detail.target)
tbo47 commented 2 years ago

oh, perfect, thanks!