All Downloads are FREE. Search and download functionalities are using the official Maven repository.

diagram.lib.diagram.js Maven / Gradle / Ivy

There is a newer version: 1.3.46
Show newest version
var graph;

function queryParameter(parameterName) {
    let query = window.location.search.substring(1);
    let parms = query.split('&');
    for (let i = 0; i < parms.length; i++) {
        let pos = parms[i].indexOf('=');
        if (pos > 0 && parameterName == parms[i].substring(0, pos)) {
            return parms[i].substring(pos + 1).replace(/%22/g, '');
        }
    }
    return undefined;
}

function collectBases(currentObject, all, hierarchyObjects) {
    let currentBase = currentObject.extends;
    if (currentBase !== undefined) {
        for (let object of all) {
            if (object.name === currentBase) {
                hierarchyObjects.push(object);
                collectBases(object, all, hierarchyObjects);
                return;
            }
        }
    }
}

function draw(graph, parent, data, layout, othersLayout, focused) {



    let objVertexes = {};

    /* objects */

    let objMap = {};
    let allObjects = data.content;
    for (let object of allObjects) {
        objMap[object.name] = object;
    }
    // create Object map (not vertex map)

    let focusedObject;
    let hierarchyObjects;

    if (focused) {
        for (let object of allObjects) {
            if (object.name == focused) {
                focusedObject = object;
                hierarchyObjects = [];
                hierarchyObjects.push(object);
                collectBases(focusedObject, allObjects, hierarchyObjects);
            }
        }
    } else {
        hierarchyObjects = allObjects;
    }

    let relationEdges = [];

    const focusedObjectsContainer = focusedObject ? graph.insertVertex(parent, null, '', 0, 0, 10, 10, 'virtual') : parent
    const otherObjectsContainer = focusedObject ? graph.insertVertex(parent, null, '', 0, 0, 1000, 1000, 'virtual') : parent
    for (let object of hierarchyObjects) {

        let vObj = objVertexes[object.name];
        if (vObj === undefined) {
            drawObject(graph, parent, focusedObjectsContainer, otherObjectsContainer, object, objMap, objVertexes, 'object', 'title', relationEdges, true, focusedObject !== undefined, false);
        }

    }

    if (focusedObject) {
        let focusedRootVertex = null
        let rootVertexes = []
        for (let object of hierarchyObjects) {
            const v = objVertexes[object.name];
            if (v) {
                rootVertexes.push(v)
            }
            if (object.name == focused) {
                focusedRootVertex = objVertexes[object.name];
            }
        }

        layout.execute(focusedObjectsContainer);
        /* position other objects container right of focused object container*/
        otherObjectsContainer.geometry.x=focusedObjectsContainer.geometry.x + focusedObjectsContainer.geometry.width + 120

        for (let relationEdge of relationEdges) {
            graph.insertEdge(parent, null, '', relationEdge.fromObject, relationEdge.to, 'virtual');
        }

        othersLayout.execute(otherObjectsContainer);

        for (let relationEdge of relationEdges) {
            graph.insertEdge(parent, null, '', relationEdge.from, relationEdge.to, relationEdge.style);
        }

        /* make virtual containers invisible */
        focusedObjectsContainer.geometry.width = 0
        focusedObjectsContainer.geometry.height = 0
        otherObjectsContainer.geometry.width = 0
        otherObjectsContainer.geometry.height = 0

    } else {
        // Executes the layout
        layout.execute(parent);
    }
}

function drawObject(graph, parent, focusedObjectsContainer, otherObjectsContainer, object, objMap, objVertexes, objStyle, titleStyle, relationEdges, rootOfFocus, withAssociations, isOther) {
    let isInPackage = objMap[object.name] !== undefined;
    if (isOther) {
        objStyle = 'otherObject';
        titleStyle = 'otherTitle';
    }
    if (!isInPackage) {
        objStyle = 'exObject';
        titleStyle = 'exTitle';
    }

    const objectName = object.name
    const objectLabel = ''+objectName+''
    const objectLabelWidth = mxUtils.getSizeForString(object.name).width;
    let maxWidth = 80;
    if (objectLabelWidth+22 > maxWidth) {
        maxWidth = objectLabelWidth+22
    }
    let fieldInfos = [];
    if (object.fields !== undefined) {

        for (let field of object.fields) {
            let fieldInfo = {};
            let fieldName = field.name
            fieldInfo.fieldName = fieldName
            if (field.key) {
                fieldName = ''+fieldName+''
            }
            if (field.composition) {
                fieldName = ''+fieldName+''
            }

            if (field.cardinality) {
                if (field.cardinality == '*' || field.cardinality.trim() == '1..1') {
                    fieldInfo.namePart = fieldName + '*'
                } else {
                    const cardinalitySeparatorIndex = field.cardinality.indexOf('..')
                    if (cardinalitySeparatorIndex > 0) {
                        const minPart = field.cardinality.substring(0, cardinalitySeparatorIndex)
                        if (minPart.length > 0 && !isNaN(minPart) && Number(minPart) > 0) {
                            const remainingPart =  field.cardinality.substring(cardinalitySeparatorIndex)
                            fieldInfo.namePart = fieldName + '[' + minPart +''+ remainingPart + ']'
                        } else {
                            fieldInfo.namePart = fieldName + '[' + field.cardinality + ']'
                        }
                    } else {
                        fieldInfo.namePart = fieldName + '[' + field.cardinality + ']'
                    }
                }
            } else {
                if (field.key) {
                    fieldInfo.namePart = fieldName+ '*';
                } else {
                    fieldInfo.namePart = fieldName;
                }
            }

            if (field.type) {
                fieldInfo.typePart = field.type;
            } else if (field.composition) {
                fieldInfo.typePart = '' + field.composition +'';
                fieldInfo.association = true;
            } else if (field.aggregation) {
                fieldInfo.typePart = field.aggregation;
                fieldInfo.association = true;
                fieldInfo.reference = true;
            }

            if (withAssociations || fieldInfo.association !== true) {
                fieldInfo.namePart = fieldInfo.namePart + ':';
            } else {
                //fieldInfo.namePart = fieldInfo.namePart+' \u2192';
            }

            fieldInfo.nameWidth = mxUtils.getSizeForString(fieldInfo.namePart).width;
            fieldInfo.typeWidth = mxUtils.getSizeForString(fieldInfo.typePart).width;

            let totalWidth = 80;
            if (!withAssociations && fieldInfo.association === true) {
                fieldInfo.nameWidth = fieldInfo.nameWidth + 5;
                totalWidth = fieldInfo.nameWidth + fieldInfo.typeWidth + 40;
            } else {
                totalWidth = fieldInfo.nameWidth + fieldInfo.typeWidth + 20;
            }


            fieldInfos.push(fieldInfo);
            //let rect = mxUtils.getSizeForString(fieldInfo.label);
            if (maxWidth < totalWidth) {
                maxWidth = totalWidth;
            }
        }
    }

    let objWidth = maxWidth;

    let doc = mxUtils.createXmlDocument();
    let classNode = doc.createElement('x')
    classNode.setAttribute('label', '');
    classNode.setAttribute('name', object.name);
    classNode.setAttribute('isClass', 'true');
    classNode.setAttribute('rootOfFocus', rootOfFocus);
    const objParent = rootOfFocus ? focusedObjectsContainer : otherObjectsContainer
    if (rootOfFocus) {
        console.log("Put into focused objects container: " + object.name)
    }
    let vObj = graph.insertVertex(objParent, null, classNode, null, null, objWidth, 35 + fieldInfos.length * 22 + 10, objStyle);

    //console.log("Insert vertex for object " + object.name +': ' + rootOfFocus)

    let childVertexes = [];
    let titleNode = doc.createElement('info');
    titleNode.setAttribute('label', objectLabel);
    if (isInPackage) {
        titleNode.setAttribute('queryParameter', objectName);
    }

    let vTitle = graph.insertVertex(vObj, null, null, 0, 0, objWidth + 7, 28, titleStyle);
    let vTitleText = graph.insertVertex(vTitle, null, titleNode, (objWidth+7)/2, 14, 0, 0, titleStyle);

    childVertexes.push(vTitle);
    vTitle.geometry.offset = new mxPoint(0, 0);
    vTitle.geometry.relative = true;
    if (object.fields !== undefined) {
        let i = 0;
        for (let fieldInfo of fieldInfos) {
            let y1 = 35 + i * 20 + 7;
            let vField = graph.insertVertex(vObj, null, null, null, null, objWidth, 22, 'property');
            vField.geometry.offset = new mxPoint(8, 28 + i * 20 + 7);
            vField.geometry.height = 20;
            vField.geometry.relative = true;

            let vNamePart = graph.insertVertex(vField, null, fieldInfo.namePart, 0, 0, fieldInfo.nameWidth, 20, 'propertyDetail');
            // vNamePart.geometry.offset = new mxPoint(0, 0);
            // vNamePart.geometry.relative = true;
            childVertexes.push(vNamePart);

            let typeBegin = fieldInfo.nameWidth + 7;
            if (!withAssociations && fieldInfo.association === true) {
                typeBegin = typeBegin + 20;
            }

            let typeNode = doc.createElement('info');
            typeNode.setAttribute('label', fieldInfo.typePart);
            if (!withAssociations && fieldInfo.association === true) {
                typeNode.setAttribute('queryParameter', fieldInfo.typePart);
            }
            let vTypePart = graph.insertVertex(vField, null, typeNode, typeBegin, 0, objWidth - typeBegin, 20, 'propertyDetail');
            // vTypePart.geometry.offset = new mxPoint(50, 0);
            // vTypePart.geometry.relative = true;
            childVertexes.push(vTypePart);

            if (!withAssociations && fieldInfo.association === true) {

                if (fieldInfo.reference === true) {
                    let vArrow = graph.insertEdge(vObj, null, '', vNamePart, vTypePart, 'reference');
                    childVertexes.push(vArrow);
                } else {
                    let vArrow = graph.insertEdge(vObj, null, '', vNamePart, vTypePart, 'containment');
                    childVertexes.push(vArrow);
                }

                //let vArrow = graph.insertEdge(vObj, null, '', null, null,'reference');
                //  vArrow.geometry.spacing=10;

                // vArrow.geometry.setTerminalPoint(new mxPoint(fieldInfo.nameWidth+5, y), true);
                // vArrow.geometry.setTerminalPoint(new mxPoint(typeBegin+0, y ), false);
                // vArrow.geometry.relative = true;
            }

            childVertexes.push(vField);
            i++;
        }
        const bottomSpaceVertex = graph.insertVertex(vObj, null, '', 0, 28 + i * 20 + 14, 0, 0);
        childVertexes.push(bottomSpaceVertex);
    }
    vObj.geometry.size = new mxPoint(100, 200);
    graph.groupCells(vObj, 0, childVertexes);

    objVertexes[object.name] = vObj;
    drawBaseObject(graph, parent, focusedObjectsContainer, otherObjectsContainer, object, vObj, objMap, objVertexes, relationEdges, rootOfFocus, withAssociations, isOther);
    if (withAssociations && object.fields !== undefined) {
        drawRelatedObjects(graph, parent, focusedObjectsContainer, otherObjectsContainer, object, vObj, objMap, objVertexes, relationEdges, withAssociations, isOther);
    }
    return vObj
}

function drawBaseObject(graph, parent, focusedObjectsContainer, otherObjectsContainer, object, vObj, objMap, objVertexes, relationEdges, withAssociations, isOther) {
    if (object.extends !== undefined) {
        let vBase = objVertexes[object.extends];
        if (vBase === undefined) {
            let extObj = objMap[object.extends];
            if (extObj === undefined) {
                extObj = {};
                extObj.name = object.extends;
            }
            vBase = drawObject(graph, parent, focusedObjectsContainer, otherObjectsContainer, extObj, objMap, objVertexes, 'object', 'title', relationEdges, withAssociations, isOther);
        }
        if (vObj !== undefined && vBase !== undefined) {
            if (isOther) {
                graph.insertEdge(parent, null, '', vBase, vObj, 'otherSpecialize');
            } else {
                graph.insertEdge(parent, null, '', vBase, vObj, 'specialize');
            }
        }
    }
}

function drawRelatedObjects(graph, parent, focusedObjectsContainer, otherObjectsContainer, object, vObj, objMap, objVertexes, relationEdges, withAssociations, isOther) {
    let relatedObjects = new Set();
    let index = 0;
    for (let field of object.fields) {
        index = index + 1;

        let type = field.composition;
        if (type === undefined) {
            type = field.aggregation;
        }

        if (type !== undefined) {
            let vType = objVertexes[type];
            if (vType === undefined) {
                let otherObject = objMap[type];
                if (otherObject !== undefined) {
                    vType = drawObject(graph, parent, focusedObjectsContainer, otherObjectsContainer, otherObject, objMap, objVertexes, 'otherObject', 'otherTitle', relationEdges, false, true, true);
                }
            }
            if (vType !== undefined) {
                let relationInfo = {};
                relationInfo.vType = vType;
                relationInfo.index = index;
                relationInfo.reference = field.aggregation !== undefined;
                relationInfo.isOther = isOther;
                relatedObjects.add(relationInfo);
            }
        }
    }

    for (let relationInfo of relatedObjects) {

        let offset = 25 + relationInfo.index * 20;

        let v11 = graph.insertVertex(vObj, null, '', 1, 0, 0, 0);
        v11.geometry.offset = new mxPoint(0, offset);
        v11.geometry.relative = true;

        let relationStyle = 'composition';
        if (relationInfo.reference == true) {
            relationStyle = 'aggregation';
        }

        if (isOther) {
            relationStyle = 'other_' + relationStyle;
        }

        let relationEdge = {};
        relationEdge.fromObject = vObj;
        relationEdge.from = v11;
        relationEdge.to = relationInfo.vType;
        relationEdge.style = relationStyle;

        relationEdges.push(relationEdge);
    }
}

function downloadSVG(graph, fileName) {

    let background = '#ffffff';
    let scale = 1;
    let border = 1;

    let imgExport = new mxImageExport();
    let bounds = graph.getGraphBounds();
    let vs = graph.view.scale;

    // Prepares SVG document that holds the output
    let svgDoc = mxUtils.createXmlDocument();
    let root = (svgDoc.createElementNS != null) ?
        svgDoc.createElementNS(mxConstants.NS_SVG, 'svg') : svgDoc.createElement('svg');

    if (background != null) {
        if (root.style != null) {
            root.style.backgroundColor = background;
        } else {
            root.setAttribute('style', 'background-color:' + background);
        }
    }

    if (svgDoc.createElementNS == null) {
        root.setAttribute('xmlns', mxConstants.NS_SVG);
        root.setAttribute('xmlns:xlink', mxConstants.NS_XLINK);
    } else {
        // KNOWN: Ignored in IE9-11, adds namespace for each image element instead. No workaround.
        root.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xlink', mxConstants.NS_XLINK);
    }

    root.setAttribute('width', (Math.ceil(bounds.width * scale / vs) + 2 * border) + 'px');
    root.setAttribute('height', (Math.ceil(bounds.height * scale / vs) + 2 * border) + 'px');
    root.setAttribute('version', '1.1');

    // Adds group for anti-aliasing via transform
    let group = (svgDoc.createElementNS != null) ?
        svgDoc.createElementNS(mxConstants.NS_SVG, 'g') : svgDoc.createElement('g');
    group.setAttribute('transform', 'translate(0.5,0.5)');
    root.appendChild(group);
    svgDoc.appendChild(root);

    // Renders graph. Offset will be multiplied with state's scale when painting state.
    let svgCanvas = new mxSvgCanvas2D(group);
    svgCanvas.translate(Math.floor((border / scale - bounds.x) / vs), Math.floor((border / scale - bounds.y) / vs));
    svgCanvas.scale(scale / vs);

    // Displayed if a viewer does not support foreignObjects (which is needed to HTML output)
    svgCanvas.foAltText = '[Not supported by viewer]';
    imgExport.drawState(graph.getView().getState(graph.model.root), svgCanvas);

    save(fileName, mxUtils.getPrettyXml(root))
}

function save(filename, data) {
    const blob = new Blob([data], {type: 'image/svg'});
    if (window.navigator.msSaveOrOpenBlob) {
        window.navigator.msSaveBlob(blob, filename);
    } else {
        const elem = window.document.createElement('a');
        elem.href = window.URL.createObjectURL(blob, {oneTimeOnly: true});
        elem.download = filename;
        document.body.appendChild(elem);
        elem.click();
        document.body.removeChild(elem);
    }
}

function main(container) {
    // Checks if browser is supported
    if (!mxClient.isBrowserSupported()) {
        // Displays an error message if the browser is
        // not supported.
        mxUtils.error('Browser is not supported!', 200, false);
    } else {

        // Disables the built-in context menu
        mxEvent.disableContextMenu(container);

        mxConstants.VERTEX_SELECTION_COLOR = '#2e7570';
        mxConstants.VERTEX_SELECTION_STROKEWIDTH = 3;
        mxConstants.VERTEX_SELECTION_DASHED = false;

        mxGraph.prototype.isHtmlLabel = function (cell) {
            return true //this.isHtmlLabels();
        };

        mxGraph.prototype.addListener(mxEvent.CLICK, function (sender, evt) {
            let cell = evt.getProperty("cell");
            if (cell !== undefined) {
                let queryParameter = cell.getAttribute("queryParameter");
                if (queryParameter !== undefined) {
                    let currentLocation = window.location;
                    let locationPath = location.protocol + '//' + location.host + location.pathname;
                    let newLocation = locationPath + '?focused=' + queryParameter;
                    window.location.href = newLocation;
                    evt.consume();
                }
            }
        });

        mxGraph.prototype.getCursorForCell = function (cell) {
            if (cell !== undefined &&
                cell.getAttribute("queryParameter") != undefined) {
                return 'pointer';
            }
        };

        let getCellContainer = function (cell) {
            let parentCell = cell.parent;
            if (parentCell != null) {
                if (parentCell.getAttribute("isClass") !== undefined) {
                    return parentCell;
                } else {
                    return getCellContainer(parentCell);
                }
            }
            return null;
        };

        /**
         * Redirects start drag to parent.
         */
        let graphHandlerGetInitialCellForEvent = mxGraphHandler.prototype.getInitialCellForEvent;
        mxGraphHandler.prototype.getInitialCellForEvent = function (me) {
            let cell = graphHandlerGetInitialCellForEvent.apply(this, arguments);
            let container = getCellContainer(cell);
            if (container != null) {
                cell = container;
            }
            return cell;
        };


        // Creates the graph inside the given container
        let graph = new mxGraph(container);

        graph.foldingEnabled = false;
        //graph.recursiveResize = true;


        let hasQueryParameter = function (cell) {
            return cell != null &&
                cell.getAttribute("queryParameter") != undefined;
        };

        function updateStyle(state, hover) {
            if (hover) {
                state.style[mxConstants.STYLE_FONTCOLOR] = '#529aba';
            }
        }

        /* Update cell style on mouseover */
        graph.addMouseListener(
            {
                currentState: null,
                previousStyle: null,
                mouseDown: function (sender, me) {
                    if (this.currentState != null) {
                        this.dragLeave(me.getEvent(), this.currentState);
                        this.currentState = null;
                    }
                },
                mouseMove: function (sender, me) {
                    if (this.currentState != null && me.getState() == this.currentState) {
                        return;
                    }
                    let tmp = graph.view.getState(me.getCell());
                    // Ignores everything but vertices with query parameter
                    if (graph.isMouseDown || (tmp != null && (!
                        graph.getModel().isVertex(tmp.cell) || !hasQueryParameter(tmp.cell)))) {
                        tmp = null;
                    }
                    if (tmp != this.currentState) {
                        if (this.currentState != null) {
                            this.dragLeave(me.getEvent(), this.currentState);
                        }
                        this.currentState = tmp;
                        if (this.currentState != null) {
                            this.dragEnter(me.getEvent(), this.currentState);
                        }
                    }
                },
                mouseUp: function (sender, me) {
                },
                dragEnter: function (evt, state) {
                    if (state != null) {
                        this.previousStyle = state.style;
                        state.style = mxUtils.clone(state.style);
                        updateStyle(state, true);
                        state.shape.apply(state);
                        state.shape.redraw();
                        if (state.text != null) {
                            state.text.apply(state);
                            state.text.redraw();
                        }
                    }
                },
                dragLeave: function (evt, state) {
                    if (state != null) {
                        state.style = this.previousStyle;
                        updateStyle(state, false);
                        state.shape.apply(state);
                        state.shape.redraw();
                        if (state.text != null) {
                            state.text.apply(state);
                            state.text.redraw();
                        }
                    }
                }
            });


        graph.isPart = function (cell) {
            return getCellContainer(cell) != null;
        };

        graph.convertValueToString = function (cell) {
            let label = cell.getAttribute('label');
            if (label !== undefined) {
                return label;
            }
            return cell.value;
        };

        graph.selectCellForEvent = function (cell, evt) {
            let container = getCellContainer(cell);
            if (container != null) {
                cell = container;
            }
            mxGraph.prototype.selectCellForEvent.apply(this, arguments);
        };

        // Prevent moving certain cells
        graph.isCellMovable = function (cell) {
            return cell.getAttribute("isClass") !== undefined;
        };

        graph.border = 80;
        graph.getView().translate = new mxPoint(graph.border / 2, graph.border / 2);

        // Adds rubberband selection
        new mxRubberband(graph);

        // Changes the default vertex style in-place
        var style = graph.getStylesheet().getDefaultVertexStyle();
        style[mxConstants.STYLE_PERIMETER_SPACING] = 6;
        // style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter;
        // style[mxConstants.STYLE_GRADIENTCOLOR] = 'white';
        style[mxConstants.STYLE_STROKEWIDTH] = 0;
        style[mxConstants.STYLE_STROKECOLOR] = '#497f81';

        style[mxConstants.STYLE_RESIZABLE] = 0;
        // style[mxConstants.STYLE_ROUNDED] = true;
        //style[mxConstants.STYLE_SHADOW] = true;
        style[mxConstants.STYLE_FILLCOLOR] = 'none';
        style[mxConstants.STYLE_FOLDABLE] = 0;

        style = [];
        style[mxConstants.STYLE_STROKEWIDTH] = 2;
        style[mxConstants.STYLE_ROUNDED] = true;
        style[mxConstants.STYLE_ARCSIZE] = 1;
        style[mxConstants.STYLE_STROKECOLOR] = '#599a9d';
        graph.getStylesheet().putCellStyle('object', style);

        style = [];
        style[mxConstants.STYLE_STROKEWIDTH] = 1;
        style[mxConstants.STYLE_STROKECOLOR] = '#717171';
        graph.getStylesheet().putCellStyle('exObject', style);


        style = [];
        style[mxConstants.STYLE_STROKEWIDTH] = 2;
        style[mxConstants.STYLE_STROKECOLOR] = '#599a9d';
        style[mxConstants.STYLE_ROUNDED] = true;
        style[mxConstants.STYLE_ARCSIZE] = 1;
        graph.getStylesheet().putCellStyle('otherObject', style);


        style = [];
        style[mxConstants.STYLE_FONTCOLOR] = '#427375';
        style[mxConstants.STYLE_STROKEWIDTH] = 0;
        style[mxConstants.STYLE_STROKECOLOR] = '#599a9d';
        graph.getStylesheet().putCellStyle('title', style);


        style = [];
        style[mxConstants.STYLE_FONTCOLOR] = '#575757';
        style[mxConstants.STYLE_STROKE_OPACITY] = 0;
        //style[mxConstants.STYLE_FONTCOLOR] = '#808a99';
        graph.getStylesheet().putCellStyle('exTitle', style);

        style = [];
        style[mxConstants.STYLE_FONTCOLOR] = '#427375';
        style[mxConstants.STYLE_STROKEWIDTH] = 0;
        style[mxConstants.STYLE_STROKECOLOR] = '#599a9d';
        graph.getStylesheet().putCellStyle('otherTitle', style);

        style = [];
        style[mxConstants.STYLE_FONTCOLOR] = '#575757';
        style[mxConstants.STYLE_STROKEWIDTH] = 0;
        style[mxConstants.STYLE_STROKE_OPACITY] = 0;
        style[mxConstants.STYLE_ALIGN] = 'left';
        style[mxConstants.STYLE_PERIMETER_SPACING] = 1;
        graph.getStylesheet().putCellStyle('property', style);

        style = [];
        style[mxConstants.STYLE_FONTCOLOR] = '#575757';
        //style[mxConstants.STYLE_STROKEWIDTH] = 1;
        style[mxConstants.STYLE_STROKE_OPACITY] = 0;
        style[mxConstants.STYLE_ALIGN] = 'left';
        style[mxConstants.STYLE_PERIMETER_SPACING] = 1;
        //style[mxConstants.STYLE_STROKECOLOR] = 'rgb(81,108,180)';
        //style[mxConstants.STYLE_SPACING] = 0;
        graph.getStylesheet().putCellStyle('propertyDetail', style);


        /* Edge styles */

        style = graph.getStylesheet().getDefaultEdgeStyle();
        style[mxConstants.STYLE_STROKECOLOR] = 'rgb(81,108,180)';
        style[mxConstants.STYLE_ROUNDED] = true;


        style = [];
        style[mxConstants.STYLE_STROKE_OPACITY] = 100;
        style[mxConstants.STYLE_STROKEWIDTH] = 1;
        style[mxConstants.STYLE_SOURCE_PERIMETER_SPACING] = -5;
        style[mxConstants.STYLE_STARTFILL] = 0;
        style[mxConstants.STYLE_STARTSIZE] = 9;
        style[mxConstants.STYLE_ROUNDED] = true;
        style[mxConstants.STYLE_STARTARROW] = mxConstants.ARROW_BLOCK;
        style[mxConstants.STYLE_ENDARROW] = mxConstants.NONE;
        graph.getStylesheet().putCellStyle('specialize', style);

        style = [];
        style[mxConstants.STYLE_STROKE_OPACITY] = 100;
        style[mxConstants.STYLE_STROKEWIDTH] = 1;
        style[mxConstants.STYLE_SOURCE_PERIMETER_SPACING] = -5;
        style[mxConstants.STYLE_STARTFILL] = 0;
        style[mxConstants.STYLE_STARTSIZE] = 9;
        style[mxConstants.STYLE_ROUNDED] = true;
        style[mxConstants.STYLE_STARTARROW] = mxConstants.ARROW_BLOCK;
        style[mxConstants.STYLE_ENDARROW] = mxConstants.NONE;
        //style[mxConstants.STYLE_STROKECOLOR] = '#8c8c8c';
        graph.getStylesheet().putCellStyle('otherSpecialize', style);

        style = [];
        style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC;
        style[mxConstants.STYLE_STARTFILL] = 0;
        style[mxConstants.STYLE_STARTSIZE] = 4;
        style[mxConstants.STYLE_ENDSIZE] = 3;
        //style[mxConstants.STYLE_PERIMETER_SPACING] = 3;
        style[mxConstants.STYLE_TARGET_PERIMETER_SPACING] = 2;
        style[mxConstants.STYLE_SOURCE_PERIMETER_SPACING] = 0;
        style[mxConstants.STYLE_STARTARROW] = mxConstants.NONE;
        style[mxConstants.STYLE_STARTARROW] = mxConstants.ARROW_DIAMOND;
        graph.getStylesheet().putCellStyle('reference', style);

        style = [];
        style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC;
        style[mxConstants.STYLE_STARTFILL] = 1;
        style[mxConstants.STYLE_STARTSIZE] = 4;
        style[mxConstants.STYLE_ENDSIZE] = 3;
        //style[mxConstants.STYLE_PERIMETER_SPACING] = 3;
        style[mxConstants.STYLE_TARGET_PERIMETER_SPACING] = 2;
        style[mxConstants.STYLE_SOURCE_PERIMETER_SPACING] = 0;
        style[mxConstants.STYLE_STARTARROW] = mxConstants.NONE;
        style[mxConstants.STYLE_STARTARROW] = mxConstants.ARROW_DIAMOND;
        graph.getStylesheet().putCellStyle('containment', style);

        style = [];
        style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC;
        style[mxConstants.STYLE_STARTFILL] = 0;
        style[mxConstants.STYLE_STARTSIZE] = 7;
        style[mxConstants.STYLE_ENDSIZE] = 6;
        //style[mxConstants.STYLE_PERIMETER_SPACING] = 3;
        style[mxConstants.STYLE_TARGET_PERIMETER_SPACING] = 0;
        style[mxConstants.STYLE_SOURCE_PERIMETER_SPACING] = -7;
        style[mxConstants.STYLE_STARTARROW] = mxConstants.ARROW_DIAMOND;
        style[mxConstants.STYLE_EDGE] = mxEdgeStyle.EntityRelation;
        graph.getStylesheet().putCellStyle('aggregation', style);

        style = [];
        style[mxConstants.STYLE_STROKEWIDTH] = 0;
        style[mxConstants.STYLE_STROKE_OPACITY] = 0;
        style[mxConstants.STYLE_STARTARROW] = mxConstants.NONE;
        style[mxConstants.STYLE_ENDARROW] = mxConstants.NONE;
        style[mxConstants.STYLE_EDGE] = mxEdgeStyle.EntityRelation;
        graph.getStylesheet().putCellStyle('virtual', style);

        style = [];
        style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC;

        style[mxConstants.STYLE_STARTSIZE] = 7;
        style[mxConstants.STYLE_ENDSIZE] = 6;
        //style[mxConstants.STYLE_PERIMETER_SPACING] = 3;
        style[mxConstants.STYLE_TARGET_PERIMETER_SPACING] = 0;
        style[mxConstants.STYLE_SOURCE_PERIMETER_SPACING] = -7;
        style[mxConstants.STYLE_STARTARROW] = mxConstants.ARROW_DIAMOND;
        //style[mxConstants.STYLE_CURVED] = 1;
        style[mxConstants.STYLE_EDGE] = mxEdgeStyle.EntityRelation;
        graph.getStylesheet().putCellStyle('composition', style);

        style = [];
        style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC;
        style[mxConstants.STYLE_STARTFILL] = 0;
        style[mxConstants.STYLE_STARTSIZE] = 7;
        style[mxConstants.STYLE_ENDSIZE] = 6;
        //style[mxConstants.STYLE_PERIMETER_SPACING] = 3;
        style[mxConstants.STYLE_TARGET_PERIMETER_SPACING] = 0;
        style[mxConstants.STYLE_SOURCE_PERIMETER_SPACING] = -7;
        style[mxConstants.STYLE_STARTARROW] = mxConstants.ARROW_DIAMOND;
        style[mxConstants.STYLE_EDGE] = mxEdgeStyle.EntityRelation;
        //style[mxConstants.STYLE_STROKECOLOR] = '#8c8c8c';
        graph.getStylesheet().putCellStyle('other_aggregation', style);

        style = [];
        style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC;
        style[mxConstants.STYLE_STARTSIZE] = 7;
        style[mxConstants.STYLE_ENDSIZE] = 6;
        //style[mxConstants.STYLE_PERIMETER_SPACING] = 3;
        style[mxConstants.STYLE_TARGET_PERIMETER_SPACING] = 0;
        style[mxConstants.STYLE_SOURCE_PERIMETER_SPACING] = -7;
        style[mxConstants.STYLE_STARTARROW] = mxConstants.ARROW_DIAMOND;
        style[mxConstants.STYLE_EDGE] = mxEdgeStyle.EntityRelation;
        //style[mxConstants.STYLE_STROKECOLOR] = '#8c8c8c';
        graph.getStylesheet().putCellStyle('other_composition', style);


        /* Layout algorithm */

        let parent = graph.getDefaultParent();
        let focused = queryParameter('focused');

        const layout = new mxHierarchicalLayout(graph, mxConstants.DIRECTION_NORTH);
        layout.edgeStyle = 4;
        layout.intraCellSpacing = 100;
        layout.interHierarchySpacing = 100;
        layout.maintainParentLocation = true;
        layout.parent = parent

        //const othersLayout = new mxHierarchicalLayout(graph, mxConstants.DIRECTION_WEST, false);
        const othersLayout = new mxHierarchicalLayout(graph, mxConstants.DIRECTION_WEST);
        //const othersLayout = new mxFastOrganicLayout(graph);
        othersLayout.forceConstant = 230;
        othersLayout.maintainParentLocation = false;
        othersLayout.edgeRouting = true;
        //othersLayout.useBoundingBox = false
        //othersLayout.maxIterations = 200
        //othersLayout.edgeStyle = 4;
        //othersLayout.intraCellSpacing = 100;
        //othersLayout.interHierarchySpacing = 120;
        // othersLayout.parent = parent

        if (focused) {
            /* only move cells of inheritance tree for focused object and its base objects
            layout.isVertexIgnored = function(vertex) {
                const rootOfFocus = vertex.getAttribute('rootOfFocus')
                return rootOfFocus =='false'
            }
            layout.isVertexMoveable = function(vertex) {
                const rootOfFocus = vertex.getAttribute('rootOfFocus')
                //return rootOfFocus =='true'
                return true
            }

             */
            /* only layout cells of relations and ignore focused object and its base objects */
            othersLayout.isVertexMoveable = function(vertex) {
                const rootOfFocus = vertex.getAttribute('rootOfFocus')
                return rootOfFocus && rootOfFocus =='false'
            }
        }

        const data = createDiagramData();

        const titleLink = document.getElementById('titleLink')
        if (titleLink) {
            titleLink.onclick = function() {

                let fileName = data.namespace.toLowerCase()
                if (focused) {
                    fileName += '-' + focused
                }
                downloadSVG(graph, fileName + '.svg');
            };
        }
        const processesLink = document.getElementById('processesLink')
        if (processesLink) {
            processesLink.onclick = function() {
                window.location.href =data.applicationNamespace + "_" + data.applicationName.toLowerCase() + ".html";
            };
        }
        const componentsLink = document.getElementById('componentsLink')
        if (componentsLink) {
            componentsLink.onclick = function() {
                window.location.href = data.applicationNamespace + "_" + data.applicationName.toLowerCase() + "_components.html";
            };
        }

        graph.border = 30;

        // Load cells and layouts the graph
        graph.getModel().beginUpdate();
        try {
            // draw the diagram
            draw(graph, parent, data, layout, othersLayout, focused);
        } finally {
            // Updates the display
            graph.getModel().endUpdate();
        }

        if (mxClient.IS_QUIRKS) {
            document.body.style.overflow = 'hidden';
            new mxDivResizer(container);
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy