Commit 2434c7f6 authored by Patrik Meijer's avatar Patrik Meijer
Browse files

Handle reposition using dragFree - now it works again and should be more efficient

parent b36cdc9d
Loading
Loading
Loading
Loading
+68 −73
Original line number Diff line number Diff line
@@ -32,11 +32,11 @@ const coseBilkentOptions = {
    name: 'cose-bilkent',
    // Called on `layoutready`
    ready: function ready() {
        console.log('coseBilkent ready');
        // console.log('coseBilkent ready');
    },
    // Called on `layoutstop`
    stop: function stop() {
        console.log('coseBilkent stop');
        // console.log('coseBilkent stop');
    },
    // Whether to include labels in node dimensions. Useful for avoiding label overlap
    nodeDimensionsIncludeLabels: true,
@@ -112,8 +112,8 @@ export default class GraphEditor extends Component {

    constructor(props) {
        super(props);
        this.styles = DEFAULT_STYLES.concat(this.props.extraStyles);
        this.reposition = {};
        const {extraStyles} = props;
        this.styles = DEFAULT_STYLES.concat(extraStyles);
        this.cyId = `cy-${Date.now()}`;
    }

@@ -190,26 +190,26 @@ export default class GraphEditor extends Component {
            const node = nodes[id];

            return JSON.parse(JSON.stringify(node.registries[CONSTANTS.CYTOSCAPE_POS_REG_KEY]
                || node.registries.position || {x: 100, y: 100}));
                || node.registries.position
                || {
                    x: 100,
                    y: 100,
                }));
        };

        const isRenderedAsGmeConnection = (id) => {
            return nodes[id] &&
                typeof nodes[id].pointers.src === 'string' &&
                typeof nodes[id].pointers.dst === 'string' &&
                targetsExist(nodes[id].pointers.src, nodes[id].pointers.dst);
        }
        const targetsExist = (src, dst) => nodes[src] && nodes[dst] && src !== activeNode && dst !== activeNode;

        const targetsExist = (src, dst) => {
            return nodes[src] && nodes[dst] && src !== activeNode && dst !== activeNode;
        };
        const isRenderedAsGmeConnection = id => nodes[id]
            && typeof nodes[id].pointers.src === 'string'
            && typeof nodes[id].pointers.dst === 'string'
            && targetsExist(nodes[id].pointers.src, nodes[id].pointers.dst);

        const hasEdgeTargets = (src, dst) => {
            function isEdge(target) {
                return nodes[target].pointers &&
                    typeof nodes[target].pointers.src === 'string' &&
                    typeof nodes[target].pointers.dst === 'string' &&
                    targetsExist(nodes[target].pointers.src, nodes[target].pointers.dst);
                return nodes[target].pointers
                    && typeof nodes[target].pointers.src === 'string'
                    && typeof nodes[target].pointers.dst === 'string'
                    && targetsExist(nodes[target].pointers.src, nodes[target].pointers.dst);
            }

            return isEdge(src) || isEdge(dst);
@@ -327,8 +327,8 @@ ${activeSelection.includes(id) ? 'in-active-selection' : ''}`,
                Object.keys(childData.pointers)
                    .forEach((pName) => {
                        const targetId = childData.pointers[pName];
                        if (!targetId || activeFilters[`pointers$${pName}`] || !targetsExist(id, targetId) ||
                            (isGmeConnection && (pName === 'src' || pName === 'dst'))) {
                        if (!targetId || activeFilters[`pointers$${pName}`] || !targetsExist(id, targetId)
                            || (isGmeConnection && (pName === 'src' || pName === 'dst'))) {
                            return;
                        }

@@ -371,26 +371,31 @@ ${activeSelection.includes(edgeId) ? ' in-active-selection' : ''}`,
        return result;
    }

    storePosition = (nodeId) => {
        const {gmeClient} = this.props;
    storePositions = (repositions) => {
        const {gmeClient, nodes} = this.props;

        if (Object.keys(this.reposition).length > 0) {
        if (repositions.length > 0) {
            gmeClient.startTransaction();
            Object.keys(this.reposition)
                .forEach((id) => {
                    if (id.indexOf(nodeId) === 0 || nodeId.indexOf(id) === 0) {
                        gmeClient.setRegistry(
                            id,
                            CONSTANTS.CYTOSCAPE_POS_REG_KEY,
                            this.reposition[id].position,
                        );
            repositions.forEach((posData) => {
                const childNodeDesc = nodes[posData.id];

                if (!childNodeDesc) {
                    return;
                }
                });

                const floorPos = {
                    x: Math.floor(posData.position.x),
                    y: Math.floor(posData.position.y),
                };

                if (!childNodeDesc.registries[CONSTANTS.CYTOSCAPE_POS_REG_KEY]
                    || floorPos.x !== childNodeDesc.registries[CONSTANTS.CYTOSCAPE_POS_REG_KEY].x
                    || floorPos.y !== childNodeDesc.registries[CONSTANTS.CYTOSCAPE_POS_REG_KEY].y) {
                    gmeClient.setRegistry(posData.id, CONSTANTS.CYTOSCAPE_POS_REG_KEY, floorPos);
                }
            });
            gmeClient.completeTransaction();
        }

        this.reposition = {};
    };

    showFilterSelector = () => {
@@ -417,51 +422,42 @@ ${activeSelection.includes(edgeId) ? ' in-active-selection' : ''}`,
        });
    };

    attachCytoscapeHandlers() {
        this.cy.on('position', ({target}) => {
            const {nodes} = this.props;
            const nodeId = target.id();
            const childNodeDesc = nodes[nodeId];

            if (!childNodeDesc) {
                return;
            }

            const floorPos = {
                x: Math.floor(target.position().x),
                y: Math.floor(target.position().y),
    atLayoutStop = () => {
        this.storePositions(this.cy.nodes('.gme-node')
            .map(ele => ({
                id: ele.id(),
                position: ele.position(),
            })));
    };

            if (!childNodeDesc.registries[CONSTANTS.CYTOSCAPE_POS_REG_KEY]) {
                this.reposition[nodeId] = {
                    id: nodeId,
                    position: floorPos,
                };
            } else if (floorPos.x !== childNodeDesc.registries[CONSTANTS.CYTOSCAPE_POS_REG_KEY].x
                || floorPos.y !== childNodeDesc.registries[CONSTANTS.CYTOSCAPE_POS_REG_KEY].y) {
                this.reposition[nodeId] = {
                    id: nodeId,
                    position: floorPos,
                };
            }
        });

        this.cy.on('free', ({target}) => {
    attachCytoscapeHandlers() {
        this.cy.on('dragfree', ({target}) => {
            const {setActiveSelection} = this.props;
            if (typeof target.id === 'function' && target.hasClass('aux-node') === false) {
                this.storePosition(target.id());
                const repositions = [
                    {
                        id: target.id(),
                        position: target.position(),
                    },
                ];

                target.descendants('node.gme-node')
                    .forEach(child => repositions.push({
                        id: child.id(),
                        position: child.position(),
                    }));

                this.storePositions(repositions);
                setTimeout(() => {
                    setActiveSelection([target.id()]);
                });
            } else {
                // Free outside of canvas
                this.reposition = {};
                setActiveSelection([]);
            }
        });

        this.cy.on('vclick', 'node', (e) => {
            this.reposition = {};
            const {setActiveSelection, gmeClient} = this.props;
            const {createPointer} = this.state;
            if (typeof e.target.id === 'function') {
@@ -469,7 +465,6 @@ ${activeSelection.includes(edgeId) ? ' in-active-selection' : ''}`,
                    this.setState({createPointer: null});
                    gmeClient.setPointer(createPointer.nodeId, createPointer.ptrName, createPointer.target);
                } else if (e.target.hasClass('aux-node') === false) {
                    // console.log('vclick', e.target.id(), JSON.stringify(this.reposition));
                    this.setState({
                        showNodeMenu: {
                            id: e.target.id(),
@@ -494,9 +489,9 @@ ${activeSelection.includes(edgeId) ? ' in-active-selection' : ''}`,
        this.cy.on('mouseover', 'node', (e) => {
            const {createPointer} = this.state;
            const {gmeClient} = this.props;
            if (createPointer &&
                typeof e.target.id === 'function' &&
                e.target.hasClass('aux-node') === false) {
            if (createPointer
                && typeof e.target.id === 'function'
                && e.target.hasClass('aux-node') === false) {
                const gmeNode = gmeClient.getNode(e.target.id());
                if (gmeNode && gmeNode.isValidTargetOf(createPointer.nodeId, createPointer.ptrName)
                    && createPointer.target !== e.target.id()) {
@@ -561,7 +556,7 @@ ${activeSelection.includes(edgeId) ? ' in-active-selection' : ''}`,
                                onClick={() => {
                                    const layout = this.cy.layout(coseBilkentOptions);
                                    layout.on('layoutstop', () => {
                                        this.storePosition(activeNode);
                                        this.atLayoutStop();
                                    });
                                    layout.run();
                                }}
@@ -574,7 +569,7 @@ ${activeSelection.includes(edgeId) ? ' in-active-selection' : ''}`,
                                onClick={() => {
                                    const layout = this.cy.layout({name: 'dagre'});
                                    layout.on('layoutstop', () => {
                                        this.storePosition(activeNode);
                                        this.atLayoutStop();
                                    });
                                    layout.run();
                                }}