Questions about Diagram Merging

since the library does not have a diagram merge functionality, we decided to create our own. We use 2 modelers (the local and a hidden one called remote). It works for most of the cases, but there is one case that fails.

When merging a collaboration diagram into a process diagram, seems to work fine, but when we export the diagram the processes that go inside the participants are lost. Code follows:

        if (!checkCollisions(modeler, hiddenModeler)) {

            if (remoteParent.type === 'bpmn:Process' && parent.type === 'bpmn:Collaboration') {
                const process = bpmnFactory.create('bpmn:Process');
                participant = modeling.createShape(
                    { type: 'bpmn:Participant', processRef: process },
                    { x: null, y: null },
                parent = participant;

            if (remoteParent.type === 'bpmn:Collaboration' && parent.type === 'bpmn:Process') {
                // Put everything into another pool and then copy stuff
                countShapes = parent.children.length;

                participant = modeling.createShape(
                    { type: 'bpmn:Participant'},
                    { x: null, y: null },
                parent = modeler.get('canvas').getRootElement();

            // Recursive shape creator
            recursiveCreator(remoteParent, parent, modeling, modeler, recursiveCreator, shapeRegistry);

            // Connections
            connectorCreator(hiddenModeler, modeling, shapeRegistry);

            if (countShapes === 0) {

I suspect the bug is in the recursive creator. I try to create a new process each time the type of the shape was a process and set element.businessObject.procesRef to that new process, but didn’t work.

    recursiveCreator(element, parent, modeling, modeler, recursiveCreator, shapeRegistry) {
        // Shapes
        let shape = parent;
        const props = JSON.parse(JSON.stringify(element.businessObject.$attrs));

        if ( === 'Shape') {
            const x = element.x + (element.width / 2);
            const y = element.y + (element.height / 2);

            shape = modeling.createShape(
                    type: element.type, businessObject: element.businessObject,
                    width: element.width, height: element.height,
                { x: x, y: y },
            // Set id translation table
            shapeRegistry[] = shape;

            // Set props
            modeling.updateProperties(shape, props);

        if ('children' in element) {
            for (let i = 0; i < element.children.length; i++) {
                recursiveCreator(element.children[i], shape,
                    modeling, modeler, recursiveCreator, shapeRegistry);

The code is a hack and is not 100% cleaned up yet. Is what we could do doing some reverse engineering.
Can you give a us a hint of what is wrong? @nikku


You cannot use JSON.stringify to serialize business objects. They are not simple objects and might contain properties that aren’t either. We’ve solved that problem quite recently in dmn-js but as you can see it’s not trivial.

Great to see you picking up this topic. Diagram merging is on my internal road map for a longer time. Do you mind open-sourcing your solution? This way the whole community would benefit.

We may look into the details of your implementation. To do that we would need a publicly accessible piece of code that precisely demonstrates what is going on wrong (call it implementation + accompanying test case).