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

diagram.lib.scenario.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 composeOpenApiUrl(componentNamespace, componentName, controllerTag, operation) {
    const tag = controllerTag ? controllerTag : 'default'
    return '../../api/' + componentNamespace + '_' + componentName.toLowerCase() +'.html#/'+tag+'/'+operation.operationId
}

function determineComponentPath(data) {
   if (window.location.href.includes("diagram/processes/")) {
    return "../" + data.applicationName.toLowerCase() + ".html";
   } else {
    return "../../" + data.applicationName.toLowerCase() + ".html";
   }
}

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

    let actorVertexes = {};
    let componentVertexes1 = {};

    let sizing = {
        currentX: 0,
        currentY: 0
    }

    let objMap = {}
    let interactionMap = {}


    let interactions = data.interactions

    let componentMap = {}
    let components = data.components
    if (components) {
        for (let component of components) {
            componentMap[component.name] = component;
        }
    }

    let infoHeight = 30
    if (data.interfaceType == 'REST') {

        let doc = mxUtils.createXmlDocument()
        let infoNode = doc.createElement('info')

        /* OpenApi */
        const operation = {
            operationId: data.operationId
        }
        const operationLabel = '' +data.verb + ' ' + data.path
        const operationUrl = composeOpenApiUrl(data.componentNamespace, data.componentName, data.controllerTag, operation)
        const operationLink = ""+operationLabel+""

        /* controller */
        const lastDotIndex = data.controller.lastIndexOf('.')
        const controllerShort = lastDotIndex > 0 ? data.controller.substring(lastDotIndex + 1 ) : data.controller
        const controllerUrl = composeControllerUrl(data.componentNamespace, data.componentName, data.controller)
        const controllerLink = "" + controllerShort + ""

        let infoHtml = operationLink + '
' + controllerLink let htmlSize = mxUtils.getSizeForString(infoHtml, null, null,900) infoNode.setAttribute('label', infoHtml) let vInfo = graph.insertVertex(parent, null, infoNode, 0, 0, 900, htmlSize.height, 'infoStyle'); vInfo.geometry.offset = new mxPoint(-20, -25); sizing.currentY = htmlSize.height + 25 } let actors = data.actors if (actors) { for (let actor of actors) { drawActor(graph, parent, sizing, actor, objMap, actorVertexes, 'actor'); sizing.currentX = sizing.currentX + 150; } sizing.currentX = sizing.currentX + 50; } const componentsPath = determineComponentPath(data) if (components) { for (let component of components) { drawComponent(graph, parent, parent, sizing, componentsPath, component, objMap, null, 'actor'); } } let allComponents = [] collectComponentsRecursive(allComponents, components) for (let id in objMap) { let obj = objMap[id] if (obj.vertex.geometry.offset) { obj.top = obj.vertex.geometry.offset.y } } let allInteractions = [] collectInteractionsRecursive(allInteractions, interactions) for (let interaction of allInteractions) { let fromId = interaction.from let fromInfo = objMap[fromId] let maxTextWidth = 295 if (interaction.reference || interaction.note) { maxTextWidth = 400 } if (interaction.note) { maxTextWidth = null } if (interaction.execution) { maxTextWidth = 230 } let interactionLabel = interaction.name if (!interaction.hasLabel && interaction.verb && interaction.path) { interactionLabel = ''+interaction.verb +' '+interaction.path } let calculatedLabelSize = mxUtils.getSizeForString(interactionLabel, null, null,maxTextWidth) if (calculatedLabelSize.width > 500) { calculatedLabelSize = mxUtils.getSizeForString(interactionLabel, null, null,500) } const nestedLevels = determineNestedLevels(interaction) const interactionInfo = { name: interactionLabel, interaction: interaction, labelSize: calculatedLabelSize, nestedLevels: nestedLevels } if (interaction.result) { interactionInfo.resultLabelSize = mxUtils.getSizeForString(interaction.result, null, null,maxTextWidth) } else { interactionInfo.resultLabelSize = new mxRectangle(0, 0, 0, 0) } if (fromInfo) { fromInfo.interactions.push(interactionInfo) } interactionMap[interaction.id] = interactionInfo } let interactionSizing = { index: 0, top: sizing.currentY + 70, currentTop: sizing.currentY + 70, distance: 15, executionBoxSpace: 12, selfHeight: 25, selfWidth: 80 } if (interactions) { let allParticipants = new Set(); for (let participantId in objMap) { const participantInfo = objMap[participantId] allParticipants.add(participantInfo) } const ctx = { children: allParticipants, leftParticipant: determineLeftParticipant(allParticipants), rightParticipant: determineRightParticipant(allParticipants) } let i=-1 for (const interaction in allInteractions) { i++ const interaction = allInteractions[i] let interactionInfo = interactionMap[interaction.id] if (interactionInfo.interaction.condition && !interactionInfo.interaction.else) { let maxNestedLevels = interactionInfo.nestedLevels let elseBranchInfos = [] let childParticipants = new Set(); determineChildParticipants(childParticipants, interactionInfo.interaction, objMap) let prevInteractionInfo = interactionInfo let current = interactionInfo.interaction while (current && current.nextInteraction) { if (current.nextInteraction.condition && current.nextInteraction.else) { current = current.nextInteraction let nextInteractionInfo = interactionMap[current.id] if (nextInteractionInfo.interaction.else) { let nestedLevels = nextInteractionInfo.nestedLevels if (nestedLevels > maxNestedLevels) { maxNestedLevels = nestedLevels } determineChildParticipants(childParticipants, nextInteractionInfo.interaction, objMap) prevInteractionInfo.followingElse = nextInteractionInfo elseBranchInfos.push(nextInteractionInfo) } else { break } } else { current = undefined } } /* determine left and right participants */ const leftParticipant= determineLeftParticipant(childParticipants) const rightParticipant= determineRightParticipant(childParticipants) /* set most left and right participants in if-branch */ interactionInfo.mostLeftParticipant = leftParticipant interactionInfo.mostRightParticipant = rightParticipant interactionInfo.nestedLevels = maxNestedLevels /* set most left and right participants in else-branches */ for (const elseBranchInfo of elseBranchInfos) { elseBranchInfo.mostLeftParticipant = leftParticipant elseBranchInfo.mostRightParticipant = rightParticipant elseBranchInfo.nestedLevels = maxNestedLevels } } } for (let interaction of interactions) { let interactionInfo = interactionMap[interaction.id] let currentParticipantInfo = interaction.participant ? objMap[interaction.participant] : null drawInteraction(graph, ctx, parent, parent, currentParticipantInfo, interactionSizing, interactionInfo, interactionMap, objMap); } } for (let component of allComponents) { let componentVertex = objMap[component.id].vertex; let componentHeight = interactionSizing.currentTop + interactionSizing.distance - componentVertex.geometry.offset.y let geometry = componentVertex.geometry geometry.height = componentHeight if (component.lineBottom) { component.lineBottom.geometry.offset.y=componentHeight } } if (actors) { for (let actorObj of actors) { let actorHeight = interactionSizing.currentTop + interactionSizing.distance let actorVertex = actorVertexes[actorObj] let geometry = actorVertex.geometry geometry.height = actorHeight if (actorObj.lineBottom) { actorObj.lineBottom.geometry.offset.y = actorHeight } } } for (let interaction of allInteractions) { let interactionInfo = interactionMap[interaction.id] if (interactionInfo.selfVertex) { interactionInfo.selfVertex.geometry.width = interactionInfo.selfVertex.geometry.width } } // Executes the layout layout.execute(parent); } function determineNestedLevels(interaction) { let maxNestedLevels = 0 if (interaction.interactions) { for (const subInteraction of interaction.interactions) { let nestedLevels = 0 if (subInteraction.condition) { nestedLevels = 1 } nestedLevels += determineNestedLevels(subInteraction) if (maxNestedLevels < nestedLevels) { maxNestedLevels = nestedLevels } } } return maxNestedLevels } function collectInteractionsRecursive(allInteractions, interactions) { if (interactions) { let previousInteraction = undefined for (let interaction of interactions) { if (previousInteraction) { previousInteraction.nextInteraction = interaction } previousInteraction = interaction allInteractions.push(interaction) if (interaction.interactions) { collectInteractionsRecursive(allInteractions, interaction.interactions) } } } } function collectComponentsRecursive(allComponents, components) { if (components) { for (let component of components) { allComponents.push(component) if (component.components) { collectInteractionsRecursive(allComponents, component.components) } } } } function createVertexInfo(label, description) { let doc = mxUtils.createXmlDocument(); let node = doc.createElement('info') if (label) { node.setAttribute('label', label); } if (description) { node.setAttribute('description', description); } return node } function drawActor(graph, parent, sizing, actorObj, objMap, actorVertexes, objStyle) { let maxWidth = 130; let childVertexes = []; let objWidth = maxWidth; let actorName = actorObj.name let doc = mxUtils.createXmlDocument(); let actorNode = doc.createElement('x') actorNode.setAttribute('label', ''); let vObj = graph.insertVertex(parent, null, actorNode, null, null, objWidth, 800, objStyle); childVertexes.push(vObj); let titleNode = doc.createElement(actorName); titleNode.setAttribute('label', actorName); let halfWidth = (objWidth+5)/2 let vImage = graph.insertVertex(vObj, null, null, 0, 0, objWidth + 5, 40, 'actorImage'); vImage.geometry.offset = new mxPoint(0, 10); vImage.geometry.relative = true; childVertexes.push(vImage); let vTitle = graph.insertVertex(vObj, null, null, 0, 0, objWidth + 5, 20, 'actorTitle', true); let vTitleText = graph.insertVertex(vTitle, null, titleNode, halfWidth, 15, 0, 0, 'actorTitle'); childVertexes.push(vTitle); childVertexes.push(vTitleText); vTitle.geometry.offset = new mxPoint(0, 45); vTitle.geometry.relative = true; let vLineBottom = drawParticipantLine(graph, parent, vObj, childVertexes, halfWidth, 65, 880, 'actorLine') vObj.geometry.offset = new mxPoint(sizing.currentX, 0); vObj.geometry.relative = true; let participantInfo = { type: 'actor', name: actorName, participant: actorObj, vertex: vObj, left: vObj.geometry.offset.x, top: vObj.geometry.offset.y, xOffset: vObj.geometry.offset.x, interactions: [] } objMap[actorObj.id] = participantInfo; actorObj.lineBottom = vLineBottom graph.groupCells(null, 0, childVertexes) actorVertexes[actorObj] = vObj; return vObj } function drawParticipantLine(graph, rootParent, vObj, childVertexes, x, top, bottom, lineStyle) { let vTop = graph.insertVertex(vObj, null, null, 0, 0, 0, 0) vTop.geometry.offset = new mxPoint(x, top); vTop.geometry.relative = true; let vBottom = graph.insertVertex(vObj, null, null, 0, 0, 0, 0) vBottom.geometry.offset = new mxPoint(x, bottom); vBottom.geometry.relative = true; let eMiddle = graph.insertEdge(rootParent, null, '', vTop, vBottom, lineStyle); childVertexes.push(vTop); childVertexes.push(vBottom); childVertexes.push(eMiddle); return vBottom } function addComponentFillColor(style, component) { if (component) { if (component.color) { return style + ';fillColor=' + component.color } if (component.stereotype == 'storage') { return style + ';fillColor=#f58e29' } else if (component.stereotype == 'ux') { return style + ';fillColor=#5aa9f1' } else if (component.stereotype == 'extern') { return style + ';fillColor=#a8a8a8' } } return style } function addComponentLineColor(style, component) { if (component) { if (component.stereotype == 'storage') { return style + ';strokeColor=#835b36' } else if (component.stereotype == 'ux') { return style + ';strokeColor=#4376b7' } else if (component.stereotype == 'extern') { return style + ';strokeColor=#707070' } } return style } function drawComponent(graph, rootParent, parent, sizing, componentsPath, component, objMap, parentComponentInfo, objStyle) { let objWidth = 250 let doc = mxUtils.createXmlDocument() let actorNode = doc.createElement('x') actorNode.setAttribute('label', ''); let isGroup = component.components let componentWidth = isGroup ? component.components.length * (objWidth +35): objWidth let componentStyle = isGroup ? 'groupStyle' : objStyle let titleStyle = isGroup ? 'groupTitle' : 'componentTitle' let childVertexes = []; titleStyle = addComponentFillColor(titleStyle, component) let vObj = graph.insertVertex(parent, null, actorNode, null, null, componentWidth, 800, componentStyle); if (component.color) { let style=graph.getModel().getStyle(vObj); let newStyle=mxUtils.setStyle(style,mxConstants.STYLE_FILLCOLOR,component.color); let cs= new Array(); cs[0]=vObj; graph.setCellStyle(newStyle,cs); } childVertexes.push(vObj) const componentUrl = componentsPath + "?focused=" + qualifiedComponentName(component) const labelText = ""+escapeString(component.label)+"" let titleNode = doc.createElement('info'); titleNode.setAttribute('label', labelText); let titleTop = isGroup ? 17 : 25 let vTitle = graph.insertVertex(vObj, null, null, 0, 0, componentWidth - 40, titleTop, titleStyle); let vTitleText = graph.insertVertex(vTitle, null, titleNode, (componentWidth-40)/2, titleTop-13, 0, 0, titleStyle); childVertexes.push(vTitle) childVertexes.push(vTitleText) vTitle.geometry.offset = new mxPoint(20, 10); vTitle.geometry.relative = true if (!isGroup) { const participantLineStyle = addComponentLineColor('componentLine', component) let vLineBottom = drawParticipantLine(graph, parent, vObj, childVertexes, (objWidth)/2,35,880, participantLineStyle) component.lineBottom = vLineBottom } vObj.geometry.offset = new mxPoint(sizing.currentX, sizing.currentY); vObj.geometry.relative = true; let participantInfo = { type: 'component', name: component.name, label: component.label, participant: component, parent: parentComponentInfo, vertex: vObj, left: vObj.geometry.offset.x, xOffset: parentComponentInfo ? parentComponentInfo.xOffset + vObj.geometry.offset.x : vObj.geometry.offset.x, top: vObj.geometry.offset.y, interactions: [] } if (parentComponentInfo) { participantInfo.top += parentComponentInfo.top } objMap[component.id] = participantInfo; if (isGroup) { let subSizing = { currentX: 20, currentY: sizing.currentY + 20 } for (let subComponent of component.components) { let vSubObj = drawComponent(graph, rootParent, vObj, subSizing, componentsPath, subComponent, objMap, participantInfo, 'actor', 'title'); childVertexes.push(vSubObj); } sizing.currentX = sizing.currentX + subSizing.currentX + 40 } else { sizing.currentX = sizing.currentX + objWidth + 25 } let group = graph.groupCells(null, 0, childVertexes); return group } function qualifiedComponentName(component) { return component.namespace + '.' + component.name } function drawInteraction(graph, ctx, rootParent, parent, currentParticipantInfo, interactionSizing, interactionInfo, interactionMap, objMap) { let interaction = interactionInfo.interaction let maxWidth = 250; let objWidth = maxWidth; let doc = mxUtils.createXmlDocument(); let actorNode = doc.createElement('x') actorNode.setAttribute('label', ''); let interactionBottom = interactionSizing.currentTop; let childVertexes = []; let interactWithOtherParticipant = interaction.to && interaction.from !== interaction.to if (!interactWithOtherParticipant && !interaction.participant) { if (interaction.execution) { interactionInfo.selfVertex = drawSelfExecution(graph, ctx, rootParent, parent, currentParticipantInfo, interactionSizing, interactionInfo, objMap) // interactionSizing.currentTop +=interactionInfo.labelSize.height } else if (interaction.condition) { drawCondition(graph, rootParent, parent, currentParticipantInfo, interactionSizing, interactionInfo, interactionMap, objMap) } else if (interaction.reference) { drawReference(graph, ctx, rootParent, parent, currentParticipantInfo, interactionSizing, interactionInfo, interactionMap, objMap) } else if (interaction.note) { interactionInfo.selfVertex = drawNote(graph, ctx, rootParent, parent, currentParticipantInfo, interactionSizing, interactionInfo, interactionMap, objMap) } else if (interaction.participant) { /* root interaction in scenario */ console.log("draw participant") } else if (currentParticipantInfo) { drawSelfInvokation(graph, rootParent, parent, currentParticipantInfo, interactionSizing, interactionInfo, objMap) } interactionBottom = interactionSizing.currentTop } else { let isStartingInteraction = interaction.participant !== undefined let fromParticipantInfo = objMap[interaction.from] let fromVertx = fromParticipantInfo.vertex let toParticipantInfo = objMap[interaction.to] let toVertx = toParticipantInfo.vertex let fromX = fromVertx.geometry.getCenterX() let toX = toVertx.geometry.getCenterX() let fromDurationOffset = 0 let toDurationOffset = 0 interactionSizing.index++ let rightSide = fromParticipantInfo.xOffset < toParticipantInfo.xOffset let absoluteFromX = fromParticipantInfo.xOffset + fromVertx.geometry.getCenterX() let absoluteToX = toParticipantInfo.xOffset + toVertx.geometry.getCenterX() let labelHeight = interactionInfo.labelSize.height if (isStartingInteraction) { labelHeight = 0 } else { interactionSizing.currentTop = interactionSizing.currentTop + interactionSizing.distance } let lineTop = interactionSizing.currentTop + labelHeight// - fromVertx.geometry.offset.y //let top = interactionSizing.top + interactionSizing.index*interactionSizing.distance if (!interaction.ignoreResponse) { if (rightSide) { if (!toParticipantInfo.currentOffset) { toParticipantInfo.currentOffset=1 } else { toParticipantInfo.currentOffset += 1 } toDurationOffset = toParticipantInfo.currentOffset * 5 + 1 toX -= toDurationOffset if (interaction.notifyOnly) { toX = toX + 6 // no duration in this case, therefore extend length of line } if (!fromParticipantInfo.currentOffset) { fromParticipantInfo.currentOffset = 0 } fromDurationOffset = fromParticipantInfo.currentOffset * 5 + 1 fromX += fromDurationOffset } else { if (!toParticipantInfo.currentOffset) { toParticipantInfo.currentOffset=1 } else { toParticipantInfo.currentOffset += 1 } toDurationOffset = toParticipantInfo.currentOffset * 5 + 1 toX += toDurationOffset if (interaction.notifyOnly) { toX = toX - 6 // no duration in this case, therefore extend length of line } if (!fromParticipantInfo.currentOffset) { fromParticipantInfo.currentOffset = 0 } fromDurationOffset = fromParticipantInfo.currentOffset * 5 +1 fromX -= fromDurationOffset } } interactionBottom = lineTop if (!isStartingInteraction) { drawInteractionLine(graph, parent, childVertexes, fromVertx, toVertx, false, fromX, toX, lineTop) } if (!isStartingInteraction) { let labelTop = lineTop - interactionInfo.labelSize.height - 5 let vTitleText = createLabel(graph, rootParent, interactionInfo, true, absoluteFromX, rightSide, labelTop) } interactionSizing.currentTop = lineTop let vDuration = null if (!interaction.ignoreResponse && !interaction.notifyOnly) { let childVertexes = []; vDuration = graph.insertVertex(rootParent, null, null, 0,0, 12, 50, 'durationStyle') if (rightSide) { vDuration.geometry.offset = new mxPoint(absoluteToX - toDurationOffset, lineTop); } else { vDuration.geometry.offset = new mxPoint(absoluteToX + toDurationOffset - 12, lineTop); } vDuration.geometry.relative = true; } let subInteractionBottom = drawSubInteractions(graph, ctx, rootParent, toVertx, toParticipantInfo, interaction, interactionInfo, interactionSizing, interactionMap, objMap) if (!interaction.ignoreResponse && !interaction.notifyOnly) { let backLineTop = interactionSizing.currentTop + interactionInfo.resultLabelSize.height + interactionSizing.distance// - fromVertx.geometry.offset.y let labelHeight = interactionInfo.resultLabelSize.height let backLabelTop = backLineTop - interactionInfo.resultLabelSize.height - 5 let backTop = interactionSizing.currentTop + interactionSizing.distance + interactionSizing.currentTop vDuration.geometry.height = subInteractionBottom - lineTop //+ interactionSizing.distance if (fromParticipantInfo.type !== 'actor' && !interaction.triggerOnly) { if (!isStartingInteraction) { drawInteractionLine(graph, parent, childVertexes, toVertx, fromVertx, true, toX, fromX, backLineTop) } interactionBottom = backLineTop } if (interaction.result) { createLabel(graph, rootParent, interactionInfo, false, absoluteFromX, rightSide, backLabelTop) // interactionSizing.currentTop = interactionSizing.currentTop + labelHeight } else { // interactionSizing.currentTop = interactionSizing.currentTop + interactionSizing.distance + 100 } interactionSizing.currentTop = backLineTop //+ interactionSizing.distance toParticipantInfo.currentOffset -= 1 } else { let backLineTop = interactionSizing.currentTop //+ interactionSizing.distance interactionSizing.currentTop = backLineTop // + interactionSizing.distance toParticipantInfo.currentOffset -= 1 } //interactionSizing.currentTop = interactionSizing.currentTop+ interactionSizing.distance } return interactionBottom; } function hasResponse(interaction, objMap) { let fromParticipantInfo = objMap[interaction.from] if (fromParticipantInfo) { return fromParticipantInfo.type !== 'actor' && !interaction.triggerOnly } return false } function drawSubInteractions(graph, ctx, rootParent, toVertx, toParticipantInfo, interaction, interactionInfo, interactionSizing, interactionMap, objMap) { let durationBottom = interactionSizing.currentTop if (interaction.interactions) { durationBottom = interactionSizing.currentTop + interactionSizing.distance let lastSubInteraction = undefined let lastBottom = durationBottom for (let subInteraction of interaction.interactions) { lastSubInteraction = subInteraction let subInteractionInfo = interactionMap[subInteraction.id] //interactionSizing.currentTop = interactionSizing.currentTop+ interactionSizing.distance durationBottom = lastBottom; let bottom = drawInteraction(graph, ctx, rootParent, toVertx, toParticipantInfo, interactionSizing, subInteractionInfo, interactionMap, objMap); lastBottom = bottom + interactionSizing.distance //if (hasResponse(subInteraction, objMap)) { if (!subInteraction.ignoreResponse ) { durationBottom = bottom if (subInteraction.result) { // durationBottom += subInteractionInfo.resultLabelSize.height } } if (lastSubInteraction.execution) { durationBottom = bottom } } if (lastSubInteraction.execution) { let lastSubInteractionInfo = interactionMap[lastSubInteraction.id] // durationBottom += lastSubInteractionInfo.labelSize.height + interactionSizing.executionBoxSpace; } } if (hasResponse(interaction, objMap)) { if (interaction.result) { durationBottom += interactionInfo.resultLabelSize.height + interactionSizing.distance } else { durationBottom += interactionSizing.distance } } else if (!interaction.interactions) { // empty (no interactions and no response) -> show short dummy box durationBottom += interactionSizing.distance } return durationBottom } function drawSelfInvokation(graph, rootParent, parent, currentParticipantInfo, interactionSizing, interactionInfo, objMap) { let currentVertex = currentParticipantInfo.vertex let interaction = interactionInfo.interaction let labelHeight = interactionInfo.labelSize.height let top = interactionSizing.currentTop + interactionSizing.distance// - currentVertex.geometry.offset.y let lineTop = top + labelHeight - currentVertex.geometry.offset.y let left = currentVertex.geometry.getCenterX() + (currentParticipantInfo.currentOffset * 6) let absoluteFromX = currentParticipantInfo.xOffset + currentVertex.geometry.getCenterX() let childVertexes = []; let vStart = graph.insertVertex(currentVertex, null, null, 0,0, 0, 0) vStart.geometry.offset = new mxPoint(left, lineTop); vStart.geometry.relative = true; let vTopRight = graph.insertVertex(currentVertex, null, null, 0,0, 0, 0) vTopRight.geometry.offset = new mxPoint(left + interactionSizing.selfWidth, lineTop); vTopRight.geometry.relative = true; let vBottomRight = graph.insertVertex(currentVertex, null, null, 0,0, 0, 0) vBottomRight.geometry.offset = new mxPoint(left + interactionSizing.selfWidth, lineTop + interactionSizing.selfHeight); vBottomRight.geometry.relative = true; let vEnd = graph.insertVertex(currentVertex, null, null, 0,0, 0, 0) vEnd.geometry.offset = new mxPoint(left, lineTop + interactionSizing.selfHeight); vEnd.geometry.relative = true; childVertexes.push(vStart); childVertexes.push(vTopRight); childVertexes.push(vBottomRight); childVertexes.push(vEnd); let eMiddle = graph.insertEdge(currentVertex, null, '', vStart, vTopRight, 'simpleLine'); let eLine2 = graph.insertEdge(currentVertex, null, '', vTopRight, vBottomRight, 'simpleLine'); let eLine3 = graph.insertEdge(currentVertex, null, '', vBottomRight, vEnd, 'interactionLine'); childVertexes.push(eMiddle); childVertexes.push(eLine2); childVertexes.push(eLine3); let vTitleText = createLabel(graph, rootParent, interactionInfo, true, absoluteFromX, true, top -5) interactionSizing.currentTop = lineTop + interactionSizing.selfHeight + interactionSizing.distance childVertexes.push(vTitleText); } function determineLeftParticipant(interactionInfo, objMap) { let childInteractions = new Set(); determineChildParticipants(childInteractions, interactionInfo.interaction, objMap) if (childInteractions.size > 0) { return childInteractions.values().next() } else { return null } } function determineLeftParticipant(participants) { if (participants.size > 0) { let leftParticipant = null let minOffset = 0 for (let participant of participants) { let xOffset = participant.vertex.geometry.offset.x if (leftParticipant === null || xOffset < minOffset) { minOffset = xOffset leftParticipant = participant } } return leftParticipant } else { return null } } function determineRightParticipant(participants) { if (participants.size > 0) { let rightParticipant = null let maxOffset = 0 for (let participant of participants) { let xOffset = participant.vertex.geometry.offset.x if (rightParticipant === null || xOffset > maxOffset) { maxOffset = xOffset rightParticipant = participant } } return rightParticipant } else { return null } } function determineChildParticipants(childInteractions, interaction, objMap) { if (interaction.from) { let fromParticipantInfo = objMap[interaction.from] if (fromParticipantInfo) { childInteractions.add(fromParticipantInfo) } } if (interaction.to) { let toParticipantInfo = objMap[interaction.to] if (toParticipantInfo) { childInteractions.add(toParticipantInfo) } } if (interaction.interactions) { for (let subInteraction of interaction.interactions) { determineChildParticipants(childInteractions, subInteraction, objMap) } } } function determineParticipants(childInteractions, components, objMap) { if (components) { for (let component of components) { let participantInfo = objMap[component] childInteractions.add(participantInfo) } } } function drawReference(graph, ctx, rootParent, parent, currentParticipantInfo, interactionSizing, interactionInfo, interactionMap, objMap, componentVertexes) { let topBefore = interactionSizing.currentTop if (ctx.leftParticipant && ctx.rightParticipant) { let interaction = interactionInfo.interaction let labelHeight = interactionInfo.labelSize.height let labelWidth = interactionInfo.labelSize.width let lineTop = interactionSizing.currentTop + interactionSizing.distance let top = lineTop let absoluteFromX = ctx.leftParticipant.xOffset + 40 let absoluteToX = ctx.rightParticipant.xOffset + ctx.rightParticipant.vertex.geometry.width - 40 let width = absoluteToX - absoluteFromX let labelRect = interactionInfo.labelSize let labelText = interactionInfo.interaction.name if (interactionInfo.interaction.href) { labelText = ""+labelText+"" } let processInfo = createVertexInfo(labelText, interaction.description) let childVertexes = []; let vStart = graph.insertVertex(rootParent, null, processInfo, null, null, width, 10, 'subProcessStyle') vStart.geometry.offset = new mxPoint(absoluteFromX, top); vStart.geometry.relative = true; //graph.addListener(vStart, "click", function () { console.log("event...")} ); //drawSubInteractions(graph, ctx, rootParent, vStart, null, interaction, interactionSizing, interactionMap, objMap) //interactionSizing.currentTop = interactionSizing.currentTop + interactionSizing.distance + labelHeight let loopHeight = labelHeight + 25 vStart.geometry.height = loopHeight interactionSizing.currentTop = interactionSizing.currentTop + loopHeight + interactionSizing.distance return vStart } else { return null } } function determineInteractionHref(interactionInfo) { if (window.location.href.includes("diagram/processes/")) { return interactionInfo.interaction.href } else { return "../../" + interactionInfo.interaction.href } } function drawCondition(graph, rootParent, parent, currentParticipantInfo, interactionSizing, interactionInfo, interactionMap, objMap, componentVertexes) { let topBefore = interactionSizing.currentTop let childParticipants = new Set(); determineChildParticipants(childParticipants, interactionInfo.interaction, objMap) const leftParticipant= determineLeftParticipant(childParticipants) const rightParticipant= determineRightParticipant(childParticipants) const ctx = { children: childParticipants, leftParticipant: leftParticipant, rightParticipant: rightParticipant, mostLeftParticipant: interactionInfo.mostLeftParticipant, mostRightParticipant: interactionInfo.mostRightParticipant } if (ctx.children.size === 0) { ctx.leftParticipant = currentParticipantInfo ctx.rightParticipant = currentParticipantInfo if (!ctx.mostLeftParticipant) { ctx.mostLeftParticipant = currentParticipantInfo } if (!ctx.mostRightParticipant) { ctx.mostRightParticipant = currentParticipantInfo } } if (ctx.leftParticipant && ctx.mostRightParticipant) { let interaction = interactionInfo.interaction let topDistance= interactionInfo.interaction.else ? 0 : interactionSizing.distance let lineTop = interactionSizing.currentTop + topDistance //- ctx.leftParticipant.top interactionSizing.currentTop = lineTop let top = lineTop let absoluteFromX = ctx.mostLeftParticipant.xOffset - 10 let absoluteToX = ctx.mostRightParticipant.xOffset + ctx.mostRightParticipant.vertex.geometry.width + 10 if (interactionInfo.nestedLevels) { absoluteFromX -= (10 * interactionInfo.nestedLevels) absoluteToX += (10 * interactionInfo.nestedLevels) } let width = absoluteToX - absoluteFromX interactionInfo.labelSize = mxUtils.getSizeForString(interactionInfo.interaction.name, null, null,width - 20) let labelHeight = interactionInfo.labelSize.height let labelWidth = interactionInfo.labelSize.width let labelRect = interactionInfo.labelSize let style = '' if (interaction.condition) { if (interaction.else) { style='elseStyle' } else { style='ifStyle' } } else { style='loopStyle' } let childVertexes = []; let vStart = graph.insertVertex(rootParent, null, '', null, null, width, 100, style) vStart.geometry.offset = new mxPoint(absoluteFromX, lineTop); vStart.geometry.relative = true; const categoryBoxHeight = 17 /* 'border'-lines */ if (interaction.condition && !interaction.else) { graph.insertEdge(vStart, null, '', vStart, vStart, 'altBorderStyle;exitX=1;entryDx='+(70+6)+';entryX=0;exitDx=-6;exitY=0;exitDy=6;exitPerimeter=0;entryY=0;entryDy=6;entryPerimeter=0;'); graph.insertEdge(vStart, null, '', vStart, vStart, 'altBorderStyle;exitX=0;exitDx=6;entryX=0;entryDx=6;exitY=1;exitDy=-6;exitPerimeter=0;entryY=0;entryDy='+(categoryBoxHeight + 6)+';entryPerimeter=0;'); } else if (interaction.condition && interaction.else){ graph.insertEdge(vStart, null, '', vStart, vStart, 'altSeparatorStyle;exitX=1;exitDx=-6;entryX=0;entryDx=6;exitY=0;exitDy=6;exitPerimeter=0;entryY=0;entryDy=6;entryPerimeter=0;'); graph.insertEdge(vStart, null, '', vStart, vStart, 'altBorderStyle;exitX=0;exitDx=6;entryX=0;entryDx=6;exitY=1;exitDy=-6;exitPerimeter=0;entryY=0;entryDy=6;entryPerimeter=0;'); } graph.insertEdge(vStart, null, '', vStart, vStart, 'altBorderStyle;exitX=1;exitDx=-6;entryX=1;entryDx=-6;exitY=1;exitDy=-6;exitPerimeter=0;entryY=0;entryDy=6;entryPerimeter=0;'); if (!interaction.nextInteraction || !interaction.nextInteraction.else) { graph.insertEdge(vStart, null, '', vStart, vStart, 'altBorderStyle;exitX=1;exitDx=-6;entryX=0;entryDx=6;exitY=1;exitDy=-6;exitPerimeter=0;entryY=1;entryDy=-6;entryPerimeter=0;'); } /* condition and loop labels */ let labelY = 5; if (interaction.condition && !interaction.else) { let conditionCategory = interaction.loop ? 'loop' : 'alt' let vCondition = graph.insertVertex(vStart, null, conditionCategory, null, null, 70, categoryBoxHeight, 'conditionStyle') vCondition.geometry.offset = new mxPoint(0, 0); vCondition.geometry.relative = true; labelY = 20 } let vConditionText = graph.insertVertex(vStart, null, escapeString(interactionInfo.interaction.name), 0,0, width-20, labelHeight + 5, 'conditionTextStyle') vConditionText.geometry.offset = new mxPoint(15, labelY); vConditionText.geometry.relative = true; /* current top for sub interactions */ if (interaction.condition && !interaction.else) { interactionSizing.currentTop = lineTop + labelHeight + 20 } else { interactionSizing.currentTop = lineTop + labelHeight } drawSubInteractions(graph, ctx, rootParent, vStart, currentParticipantInfo, interaction, interactionInfo, interactionSizing, interactionMap, objMap) let loopHeight = interactionSizing.currentTop - lineTop + topDistance if (interactionInfo.interaction.else) { loopHeight += interactionSizing.distance } vStart.geometry.height = loopHeight interactionSizing.currentTop = interactionSizing.currentTop + interactionSizing.distance return vStart } else { return null } } function drawNote(graph, ctx, rootParent, parent, currentParticipantInfo, interactionSizing, interactionInfo, interactionMap, objMap, componentVertexes) { let currentVertex = currentParticipantInfo? currentParticipantInfo.vertex : null let interaction = interactionInfo.interaction let labelHeight = interactionInfo.labelSize.height let yOffset = currentVertex ? currentVertex.geometry.offset.y : 0 let lineTop = interactionSizing.currentTop + interactionSizing.distance// - yOffset let top = lineTop let centerX = currentParticipantInfo ? currentParticipantInfo.xOffset + currentVertex.geometry.getCenterX() : ctx.leftParticipant.xOffset + 30 if (currentParticipantInfo) { centerX += (currentParticipantInfo.currentOffset * 6) } let absoluteFromX = centerX + 10 let labelRect = interactionInfo.labelSize let noteWidth = currentParticipantInfo ? labelRect.width+20 : (ctx.rightParticipant.xOffset + ctx.rightParticipant.vertex.geometry.width - 40) - centerX let vStart = graph.insertVertex(rootParent, null, interactionInfo.interaction.name, 0,0, noteWidth+10, labelRect.height+12, 'noteStyle') vStart.geometry.offset = new mxPoint(absoluteFromX, top); vStart.geometry.relative = true; if (currentParticipantInfo) { let p1 = graph.insertVertex(rootParent, null, '', null, null, 0,0, 'noteStyle') p1.geometry.offset = new mxPoint(centerX, top+10); p1.geometry.relative = true; let p2 = graph.insertVertex(rootParent, null, '', null, null, 0,0, 'noteStyle') p2.geometry.offset = new mxPoint(absoluteFromX, top+10); p2.geometry.relative = true; graph.insertEdge(rootParent, null, '', p1, p2, 'noteLineStyle'); } let p3 = graph.insertVertex(rootParent, null, '', null, null, 0,0, 'noteStyle') p3.geometry.offset = new mxPoint(absoluteFromX, top); p3.geometry.relative = true; let p4 = graph.insertVertex(rootParent, null, '', null, null, 0,0, 'noteStyle') p4.geometry.offset = new mxPoint(absoluteFromX, top+vStart.geometry.height); p4.geometry.relative = true; //graph.insertEdge(rootParent, null, '', p3, p4, 'noteLeftLineStyle'); interactionSizing.currentTop = top+vStart.geometry.height return vStart } function drawSelfExecution(graph, ctx, rootParent, parent, currentParticipantInfo, interactionSizing, interactionInfo, objMap, componentVertexes) { if (currentParticipantInfo) { let currentVertex = currentParticipantInfo.vertex let interaction = interactionInfo.interaction let labelHeight = interactionInfo.labelSize.height let lineTop = interactionSizing.currentTop + interactionSizing.distance// + labelHeight// - currentVertex.geometry.offset.y let left = currentVertex.geometry.getCenterX() let top = lineTop let absoluteFromX = currentParticipantInfo.xOffset + currentVertex.geometry.getCenterX() let labelRect = interactionInfo.labelSize let executionHeight = labelRect.height+interactionSizing.executionBoxSpace let childVertexes = []; let vStart = graph.insertVertex(rootParent, null, interactionInfo.interaction.name, 0,0, labelRect.width+12, executionHeight, 'executionStyle') vStart.geometry.offset = new mxPoint(absoluteFromX - labelRect.width/2, top); vStart.geometry.relative = true; interactionSizing.currentTop = interactionSizing.currentTop + executionHeight + interactionSizing.distance //childVertexes.push(vStart); return vStart } else { /* current participant info missing, probably (direct or indirect) child of actor invocation */ let currentVertex = parent let interaction = interactionInfo.interaction let labelHeight = interactionInfo.labelSize.height let lineTop = interactionSizing.currentTop + interactionSizing.distance// + labelHeight// - currentVertex.geometry.offset.y let left = currentVertex.geometry.getCenterX() let top = lineTop let absoluteFromX = ctx.leftParticipant.xOffset + 40 let labelRect = interactionInfo.labelSize let executionHeight = labelRect.height+interactionSizing.executionBoxSpace let childVertexes = []; let vStart = graph.insertVertex(rootParent, null, interactionInfo.interaction.name, 0,0, labelRect.width+12, executionHeight, 'executionStyle') vStart.geometry.offset = new mxPoint(absoluteFromX, top); vStart.geometry.relative = true; interactionSizing.currentTop = interactionSizing.currentTop + executionHeight + interactionSizing.distance //childVertexes.push(vStart); return vStart } } function createLabel(graph, parent, interactionInfo, isName, x, rightSide, top) { let text = isName ? interactionInfo.name : interactionInfo.interaction.result let labelRect = isName ? interactionInfo.labelSize : interactionInfo.resultLabelSize let doc = mxUtils.createXmlDocument(); let titleNode = doc.createElement('info'); titleNode.setAttribute('label', escapeString(text)); let labelWidth = labelRect.width; let left = rightSide ? x + 15 : x-labelWidth-15 let labelStyle = rightSide ? 'leftLabel' : 'rightLabel' let vertex = graph.insertVertex(parent, null, titleNode, 0, 0, 0, 0,labelStyle) vertex.geometry.offset = new mxPoint(left, top); vertex.geometry.width = labelRect.width vertex.geometry.height = labelRect.height vertex.geometry.relative = true; //vertex.geometry.alternateBounds=new mxRectangle(left, top, labelRect.width, labelRect.height); return vertex } function escapeString(str) { if (str) { /* & & ' ' < < > > " " Ä Ä Ö Ö Ü Ü ä ä ö ö ü ü ß ß */ let escaped = str.replace("ö","ö") escaped = escaped.replace("ü","ü") escaped = escaped.replace("ä","ä") escaped = escaped.replace("ß","ß") escaped = escaped.replace('"',""") escaped = escaped.replace('Ä',"Ä") escaped = escaped.replace('Ö',"Ö") escaped = escaped.replace('Ü',"ß") return escaped } return str } function drawInteractionLine(graph, vObj, childVertexes, fromVertx, toVertx, isResponse, left, right, top) { let vTop = graph.insertVertex(fromVertx, null, null, 0,0, 0, 0) vTop.geometry.offset = new mxPoint(left, top - fromVertx.geometry.offset.y); vTop.geometry.relative = true; let vBottom = graph.insertVertex(toVertx, null, null, 0,0, 0, 0) vBottom.geometry.offset = new mxPoint(right, top - toVertx.geometry.offset.y); vBottom.geometry.relative = true; childVertexes.push(vTop); childVertexes.push(vBottom); let style = isResponse ? 'interactionResponseLine' : 'interactionLine'; let eMiddle = graph.insertEdge(vObj, null, '', vTop, vBottom, style); childVertexes.push(eMiddle); } 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, titleLink, diagramName) { // 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 = '#15808c'; mxConstants.VERTEX_SELECTION_STROKEWIDTH = 2; mxConstants.VERTEX_SELECTION_DASHED = true; mxGraph.prototype.isHtmlLabel = function (cell) { return true; // return this.isHtmlLabels(); }; //mxGraph.prototype.ordered = false; // Creates the graph inside the given container let graph = new mxGraph(container); titleLink.onclick = function() { downloadSVG(graph, diagramName + ".svg"); }; graph.foldingEnabled = false; //graph.recursiveResize = true; let hasQueryParameter = function (cell) { return cell != null && cell.getAttribute("queryParameter") != undefined; }; graph.convertValueToString = function (cell) { let label = cell.getAttribute('label'); if (label !== undefined) { return label; } return cell.value; }; // Prevent moving certain cells graph.isCellMovable = function (cell) { return cell.getAttribute("isClass") !== undefined; }; graph.isCellSelectable = function (cell) { return false } graph.border = 80; graph.getView().translate = new mxPoint(graph.border / 2, graph.border / 2); function CollateShape() { mxEllipse.call(this); }; mxUtils.extend(CollateShape, mxEllipse); CollateShape.prototype.paintVertexShape = function(c, x, y, w, h) { c.begin(); c.moveTo(x, y); c.lineTo(x, y+h); c.lineTo(x + w - 8 , y+h); c.lineTo(x + w , y+h - 8); c.lineTo(x + w , y); c.close(); c.fillAndStroke(); }; mxCellRenderer.registerShape('collate', CollateShape); // Adds rubberband selection new mxRubberband(graph); // Installs a custom global tooltip graph.setTooltips(true); graph.getTooltip = function (state) { let cell = state.cell; let model = this.getModel(); if (model.isEdge(cell)) { // TODO } else { if (mxUtils.isNode(cell.value)) { let description = cell.getAttribute('description', null) if (description) { return description } } return null; } }; // 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] = 'rgb(81,108,180)'; 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] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 0; graph.getStylesheet().putCellStyle('actor', style); style = []; style[mxConstants.STYLE_STROKEWIDTH] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 100; style[mxConstants.STYLE_FILL_OPACITY] = 100; style[mxConstants.STYLE_FILLCOLOR] = 'rgb(244,248,255)'; style[mxConstants.STYLE_STROKECOLOR] = 'rgb(169,189,231)'; style[mxConstants.STYLE_OPACITY] = 100; graph.getStylesheet().putCellStyle('durationStyle', style); style = []; style[mxConstants.STYLE_STROKEWIDTH] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 0; style[mxConstants.STYLE_FONTCOLOR] = '#eea52b'; graph.getStylesheet().putCellStyle('actorTitle', style); style = []; style[mxConstants.STYLE_STROKEWIDTH] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 0; style[mxConstants.STYLE_FONTCOLOR] = '#4e9c9f'; graph.getStylesheet().putCellStyle('groupTitle', style); style = []; style[mxConstants.STYLE_STROKEWIDTH] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 0; style[mxConstants.STYLE_FONTCOLOR] = 'rgb(58,93,157)'; style[mxConstants.STYLE_ALIGN] = 'left'; graph.getStylesheet().putCellStyle('leftLabel', style); style = []; style[mxConstants.STYLE_STROKEWIDTH] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 0; style[mxConstants.STYLE_FONTCOLOR] = 'rgb(58,93,157)'; style[mxConstants.STYLE_ALIGN] = 'right'; graph.getStylesheet().putCellStyle('rightLabel', style); style = []; style[mxConstants.STYLE_FONTCOLOR] = 'rgb(58,93,157)'; style[mxConstants.STYLE_FILLCOLOR] = 'rgb(206,221,253)'; //style[mxConstants.STYLE_FILLCOLOR] = 'rgb(238,247,255)'; style[mxConstants.STYLE_STROKECOLOR] = 'rgb(185,199,238)'; style[mxConstants.STYLE_STROKE_OPACITY] = 0; style[mxConstants.STYLE_OPACITY] = 100; style[mxConstants.STYLE_FILL_OPACITY] = 100; style[mxConstants.STYLE_ROUNDED] = true; style[mxConstants.STYLE_ARCSIZE] = 10; style[mxConstants.STYLE_ABSOLUTE_ARCSIZE] = 1; graph.getStylesheet().putCellStyle('executionStyle', style); style = []; style[mxConstants.STYLE_FONTCOLOR] = 'rgb(79,108,91)'; //style[mxConstants.STYLE_ALIGN] = 'right'; style[mxConstants.STYLE_FILLCOLOR] = 'rgb(179,232,201)'; style[mxConstants.STYLE_OPACITY] = 100; style[mxConstants.STYLE_FILL_OPACITY] = 100; style[mxConstants.STYLE_STROKE_OPACITY] = 0; style[mxConstants.STYLE_ALIGN] = 'left'; style[mxConstants.STYLE_SPACING] = 10; style[mxConstants.STYLE_ROUNDED] = true; style[mxConstants.STYLE_ARCSIZE] = 4; style[mxConstants.STYLE_ABSOLUTE_ARCSIZE] = 1; graph.getStylesheet().putCellStyle('noteStyle', style); style = []; style[mxConstants.STYLE_STROKECOLOR] = 'rgb(79,108,91)'; style[mxConstants.STYLE_OPACITY] = 100; style[mxConstants.STYLE_FILL_OPACITY] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 100; style[mxConstants.STYLE_ENDARROW] = mxConstants.NONE; style[mxConstants.STYLE_PERIMETER_SPACING] = -6; graph.getStylesheet().putCellStyle('noteLineStyle', style); style = []; style[mxConstants.STYLE_STROKECOLOR] = 'rgb(210,161,75)'; style[mxConstants.STYLE_OPACITY] = 100; style[mxConstants.STYLE_STROKEWIDTH] = 3; style[mxConstants.STYLE_FILL_OPACITY] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 100; style[mxConstants.STYLE_ENDARROW] = mxConstants.NONE; style[mxConstants.STYLE_PERIMETER_SPACING] = -6; graph.getStylesheet().putCellStyle('noteLeftLineStyle', style); style = []; style[mxConstants.STYLE_STROKECOLOR] = '#b9a0b0'; style[mxConstants.STYLE_OPACITY] = 100; style[mxConstants.STYLE_STROKEWIDTH] = 1; style[mxConstants.STYLE_FILL_OPACITY] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 100; style[mxConstants.STYLE_ENDARROW] = mxConstants.NONE; style[mxConstants.STYLE_PERIMETER_SPACING] = -6; graph.getStylesheet().putCellStyle('altBorderStyle', style); style = []; style[mxConstants.STYLE_STROKECOLOR] = '#b9a0b0'; style[mxConstants.STYLE_DASHED] = 1; style[mxConstants.STYLE_DASH_PATTERN] = '3'; style[mxConstants.STYLE_OPACITY] = 100; style[mxConstants.STYLE_STROKEWIDTH] = 1; style[mxConstants.STYLE_FILL_OPACITY] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 100; style[mxConstants.STYLE_ENDARROW] = mxConstants.NONE; style[mxConstants.STYLE_PERIMETER_SPACING] = -6; graph.getStylesheet().putCellStyle('altSeparatorStyle', style); style = []; //style[mxConstants.STYLE_FONTCOLOR] = 'rgb(84,121,187)'; //style[mxConstants.STYLE_ALIGN] = 'right'; style[mxConstants.STYLE_FILLCOLOR] = 'rgb(255,255,255)'; style[mxConstants.STYLE_STROKECOLOR] = '#7F0055'; style[mxConstants.STYLE_FONTCOLOR] = '#7F0055'; style[mxConstants.STYLE_OPACITY] = 100; style[mxConstants.STYLE_FILL_OPACITY] = 45; style[mxConstants.STYLE_STROKE_OPACITY] = 100; style[mxConstants.STYLE_SHAPE] = 'collate'; graph.getStylesheet().putCellStyle('conditionStyle', style); style = []; style[mxConstants.STYLE_FONTCOLOR] = '#804b6a'; style[mxConstants.STYLE_ALIGN] = 'left'; style[mxConstants.STYLE_STROKEWIDTH] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 0; style[mxConstants.STYLE_OPACITY] = 100; style[mxConstants.STYLE_FILL_OPACITY] = 100; style[mxConstants.STYLE_SHAPE] = 'collate'; graph.getStylesheet().putCellStyle('conditionTextStyle', style); style = []; //style[mxConstants.STYLE_FONTCOLOR] = 'rgb(84,121,187)'; //style[mxConstants.STYLE_ALIGN] = 'right'; style[mxConstants.STYLE_STROKEWIDTH] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 0; style[mxConstants.STYLE_FILLCOLOR] = 'rgb(140,140,140)'; style[mxConstants.STYLE_FILL_OPACITY] = 7; graph.getStylesheet().putCellStyle('ifStyle', style); style = []; //style[mxConstants.STYLE_FONTCOLOR] = 'rgb(84,121,187)'; //style[mxConstants.STYLE_ALIGN] = 'right'; style[mxConstants.STYLE_FILLCOLOR] = 'rgb(140,140,140)'; style[mxConstants.STYLE_FILL_OPACITY] = 10; style[mxConstants.STYLE_STROKEWIDTH] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 0; graph.getStylesheet().putCellStyle('elseStyle', style); style = []; //style[mxConstants.STYLE_FONTCOLOR] = 'rgb(84,121,187)'; //style[mxConstants.STYLE_ALIGN] = 'right'; style[mxConstants.STYLE_FILLCOLOR] = 'rgb(140,140,140)'; style[mxConstants.STYLE_STROKECOLOR] = 'rgb(194,164,162)'; style[mxConstants.STYLE_FILL_OPACITY] = 10; style[mxConstants.STYLE_STROKE_OPACITY] = 100; graph.getStylesheet().putCellStyle('loopStyle', style); style = []; style[mxConstants.STYLE_STROKEWIDTH] = 0; style[mxConstants.STYLE_FONTCOLOR] = 'rgb(255,255,255)'; //style[mxConstants.STYLE_ALIGN] = 'right'; style[mxConstants.STYLE_FILLCOLOR] = 'rgb(133,139,248)'; style[mxConstants.STYLE_FILL_OPACITY] = 100; style[mxConstants.STYLE_STROKE_OPACITY] = 0; style[mxConstants.STYLE_ROUNDED] = true; style[mxConstants.STYLE_ARCSIZE] = 6; graph.getStylesheet().putCellStyle('subProcessStyle', style); style = []; style[mxConstants.STYLE_STROKEWIDTH] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 0; style[mxConstants.STYLE_STROKECOLOR] = '#497f81'; style[mxConstants.STYLE_FONTCOLOR] = '#ffffff'; style[mxConstants.STYLE_FILLCOLOR] = '#5bbac7'; style[mxConstants.STYLE_ROUNDED] = true; style[mxConstants.STYLE_ARCSIZE] = 6; style[mxConstants.STYLE_ABSOLUTE_ARCSIZE] = 1; graph.getStylesheet().putCellStyle('componentTitle', style); style = []; style[mxConstants.STYLE_STROKEWIDTH] = 0; style[mxConstants.STYLE_SPACING] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 0; style[mxConstants.STYLE_ALIGN] = 'left'; // style[mxConstants.STYLE_STROKECOLOR] = '#497f81'; style[mxConstants.STYLE_FONTCOLOR] = 'rgb(58,93,157)'; // style[mxConstants.STYLE_FILLCOLOR] = '#5bbac7'; // style[mxConstants.STYLE_ROUNDED] = true; // style[mxConstants.STYLE_ARCSIZE] = 6; // style[mxConstants.STYLE_ABSOLUTE_ARCSIZE] = 1; graph.getStylesheet().putCellStyle('infoStyle', style); style = []; style[mxConstants.STYLE_STROKEWIDTH] = 0; style[mxConstants.STYLE_STROKE_OPACITY] = 0; style[mxConstants.STYLE_FILLCOLOR] = '#f5fafa'; style[mxConstants.STYLE_ROUNDED] = true; style[mxConstants.STYLE_ARCSIZE] = 2; style[mxConstants.STYLE_ABSOLUTE_ARCSIZE] = 1; graph.getStylesheet().putCellStyle('groupStyle', style); style = []; style[mxConstants.STYLE_STROKEWIDTH] = 2; 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] = '#8c8c8c'; graph.getStylesheet().putCellStyle('otherObject', style); style = []; style[mxConstants.STYLE_FONTCOLOR] = '#575757'; style[mxConstants.STYLE_STROKEWIDTH] = 0; 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] = '#575757'; style[mxConstants.STYLE_STROKEWIDTH] = 0; style[mxConstants.STYLE_STROKECOLOR] = '#8c8c8c'; 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_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.NONE; style[mxConstants.STYLE_STROKECOLOR] = '#4bb0b2'; style[mxConstants.STYLE_DASHED] = 1; style[mxConstants.STYLE_DASH_PATTERN] = '6'; //style[mxConstants.STYLE_PERIMETER_SPACING] = 3; style[mxConstants.STYLE_TARGET_PERIMETER_SPACING] = 0; style[mxConstants.STYLE_SOURCE_PERIMETER_SPACING] = 0; style[mxConstants.STYLE_STARTARROW] = mxConstants.NONE; graph.getStylesheet().putCellStyle('componentLine', style); style = []; style[mxConstants.STYLE_ENDARROW] = mxConstants.NONE; style[mxConstants.STYLE_STROKECOLOR] = '#eea52b'; style[mxConstants.STYLE_DASHED] = 1; style[mxConstants.STYLE_DASH_PATTERN] = '6'; //style[mxConstants.STYLE_PERIMETER_SPACING] = 3; style[mxConstants.STYLE_TARGET_PERIMETER_SPACING] = 0; style[mxConstants.STYLE_SOURCE_PERIMETER_SPACING] = 0; style[mxConstants.STYLE_STARTARROW] = mxConstants.NONE; graph.getStylesheet().putCellStyle('actorLine', style); style = []; style[mxConstants.STYLE_PERIMETER_SPACING] = -6; style[mxConstants.STYLE_PERIMETER] = 0; style[mxConstants.STYLE_STARTARROW] = mxConstants.NONE; style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC; graph.getStylesheet().putCellStyle('interactionLine', style); style = []; style[mxConstants.STYLE_PERIMETER_SPACING] = -6; style[mxConstants.STYLE_DASHED] = 1; style[mxConstants.STYLE_DASH_PATTERN] = '4'; style[mxConstants.STYLE_PERIMETER] = 0; style[mxConstants.STYLE_STARTARROW] = mxConstants.NONE; style[mxConstants.STYLE_ENDARROW] = mxConstants.ARROW_CLASSIC; graph.getStylesheet().putCellStyle('interactionResponseLine', style); style = []; style[mxConstants.STYLE_PERIMETER_SPACING] = -6; style[mxConstants.STYLE_PERIMETER] = 0; style[mxConstants.STYLE_STARTARROW] = mxConstants.NONE; style[mxConstants.STYLE_ENDARROW] = mxConstants.NONE; graph.getStylesheet().putCellStyle('simpleLine', style); // image string encoded with: https://jgraph.github.io/drawio-tools/tools/base64.html referenced in: https://stackoverflow.com/questions/51039801/how-to-add-a-svg-image-to-mxgraph let actorImageBase64 = "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+Cjxzdmcgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEyMiAyMjkiIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgeG1sbnM6c2VyaWY9Imh0dHA6Ly93d3cuc2VyaWYuY29tLyIgc3R5bGU9ImZpbGwtcnVsZTpldmVub2RkO2NsaXAtcnVsZTpldmVub2RkO3N0cm9rZS1saW5lY2FwOnJvdW5kO3N0cm9rZS1saW5lam9pbjpyb3VuZDtzdHJva2UtbWl0ZXJsaW1pdDoxLjU7Ij4KICAgIDxnIHRyYW5zZm9ybT0ibWF0cml4KDEuMTI5MDQsMCwwLDEuMjQwNzUsLTk3LjA3MDIsLTExNy4yMSkiPgogICAgICAgIDxlbGxpcHNlIGN4PSIxNDAuMDI0IiBjeT0iMTIzLjE2OCIgcng9IjI2LjE1MyIgcnk9IjIzLjc5OCIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6cmdiKDIyNCwxNDksMCk7c3Ryb2tlLXdpZHRoOjcuODdweDsiLz4KICAgIDwvZz4KICAgIDxnIHRyYW5zZm9ybT0ibWF0cml4KDAuOTk3OTkzLDAuMDUwODM1MywtMC4wNjMzMTczLDAuODAxMjU2LC0yNC41NDksLTgxLjY2NjEpIj4KICAgICAgICA8cGF0aCBkPSJNOTYuNjYxLDE3Mi4wODdMMTAzLjI5MywyNzYuNjExIiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTpyZ2IoMjI0LDE0OSwwKTtzdHJva2Utd2lkdGg6MTAuNDRweDtzdHJva2UtbGluZWNhcDpidXR0OyIvPgogICAgPC9nPgogICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoLTAuMDYwNjMzOSwwLjk5Nzk5MywtMC45NTU2OTgsLTAuMDYzMzE3MywyODEuNzg4LDYuOTkzMDgpIj4KICAgICAgICA8cGF0aCBkPSJNOTYuNjYxLDE3Mi4wODdMMTAzLjI5MywyNzYuNjExIiBzdHlsZT0iZmlsbDpub25lO3N0cm9rZTpyZ2IoMjI0LDE0OSwwKTtzdHJva2Utd2lkdGg6OS41NnB4OyIvPgogICAgPC9nPgogICAgPGcgdHJhbnNmb3JtPSJtYXRyaXgoLTAuNzgyNTA3LDAuNDk3MjA0LC0wLjQ3MjE4NywtMC43NTIyMDEsMjcyLjQ2MiwzMDEuOTMxKSI+CiAgICAgICAgPHBhdGggZD0iTTk2LjY2MSwxNzIuMDg3TDEwMy4yOTMsMjc2LjYxMSIgc3R5bGU9ImZpbGw6bm9uZTtzdHJva2U6cmdiKDIyNCwxNDksMCk7c3Ryb2tlLXdpZHRoOjEwLjMxcHg7Ii8+CiAgICA8L2c+CiAgICA8ZyB0cmFuc2Zvcm09Im1hdHJpeCgwLjc4MjUwNywwLjQ5NzIwNCwwLjQ3MjE4NywtMC43NTIyMDEsLTE1MC41MzQsMzAxLjkzMSkiPgogICAgICAgIDxwYXRoIGQ9Ik05Ni42NjEsMTcyLjA4N0wxMDMuMjkzLDI3Ni42MTEiIHN0eWxlPSJmaWxsOm5vbmU7c3Ryb2tlOnJnYigyMjQsMTQ5LDApO3N0cm9rZS13aWR0aDoxMC4zMXB4OyIvPgogICAgPC9nPgo8L3N2Zz4K" style = []; style[mxConstants.STYLE_SHAPE] = mxConstants.SHAPE_IMAGE; style[mxConstants.STYLE_PERIMETER] = mxPerimeter.RectanglePerimeter; style[mxConstants.STYLE_IMAGE] = actorImageBase64; //style[mxConstants.STYLE_IMAGE] = 'img/actor.svg'; style[mxConstants.STYLE_FONTCOLOR] = '#FFFFFF'; graph.getStylesheet().putCellStyle('actorImage', style); // name style /* Layout algorithm */ //let layout = new mxCompactTreeLayout(graph); let layout = new mxHierarchicalLayout(graph, mxConstants.DIRECTION_WEST); layout.edgeStyle = 4; layout.intraCellSpacing = 100; layout.interHierarchySpacing = 100; let parent = graph.getDefaultParent(); graph.border = 30; graph.isWrapping = function(cell) { return true }; const data = createDiagramData(); const processesLink = document.getElementById('processesLink') if (processesLink) { processesLink.onclick = function() { if (window.location.href.includes("diagram/processes/")) { window.location.href = data.applicationName.toLowerCase() + "_processes.html"; } else { window.location.href = "../../processes/" + data.applicationName.toLowerCase() + "_processes.html"; } }; } const componentsLink = document.getElementById('componentsLink') if (componentsLink) { componentsLink.onclick = function() { window.location.href = determineComponentPath(data); }; } // Load cells and layouts the graph graph.getModel().beginUpdate(); try { // draw the diagram draw(graph, parent, layout, data); } 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