const fn = function (svg, g) { preProcessGraph(g) svg.selectAll('*').remove() const outputGroup = createOrSelectGroup(svg, 'output') const clustersGroup = createOrSelectGroup(outputGroup, 'clusters') const edgePathsGroup = createOrSelectGroup(outputGroup, 'edgePaths') const edgeLabels = _createEdgeLabels(createOrSelectGroup(outputGroup, 'edgeLabels'), g) const nodes = _createNodes(createOrSelectGroup(outputGroup, 'nodes'), g, _shapes) dagre.layout(g) let minX = 1000 let minY = 1000 let maxX = -1000 let maxY = -1000 const graph = g graph.nodes().map(n => graph.node(n)).forEach(node => { minX = Math.min(minX, node.x - node.width / 2) minY = Math.min(minY, node.y - node.height / 2) maxX = Math.max(maxX, node.x + node.width / 2) maxY = Math.max(maxY, node.y + node.height / 2) }) graph.edges().forEach(e => { const edge = graph.edge(e) if (edge.label !== undefined && edge.x !== undefined && edge.y !== undefined) { minX = Math.min(minX, edge.x - edge.width / 2) minY = Math.min(minY, edge.y - edge.height / 2) maxX = Math.max(maxX, edge.x + edge.width / 2) maxY = Math.max(maxY, edge.y + edge.height / 2) } const points = edge.points.slice(1, edge.points.length - 1) // intersetion points don't matter for (let i = 0; i < points.length; i++) { const point = points[i] minX = Math.min(minX, point.x) minY = Math.min(minY, point.y) maxX = Math.max(maxX, point.x) maxY = Math.max(maxY, point.y) } }) graph.minX = minX graph.minY = minY graph.maxX = maxX graph.maxY = maxY positionNodes(nodes, g) positionEdgeLabels(edgeLabels, g) _createEdgePaths(edgePathsGroup, g, _arrows) const clusters = _createClusters(clustersGroup, g) positionClusters(clusters, g) postProcessGraph(g) }
export const draw = function (text, id) { parser.yy.clear() parser.parse(text) logger.info('Rendering diagram ' + text) /// / Fetch the default direction, use TD if none was found const diagram = d3.select(`[id="${id}"]`) insertMarkers(diagram) // Layout graph, Create a new directed graph const g = new graphlib.Graph({ multigraph: true }) // Set an object for the graph label g.setGraph({ isMultiGraph: true }) // Default to assigning a new object as a label for each new edge. g.setDefaultEdgeLabel(function () { return {} }) const classes = classDb.getClasses() const keys = Object.keys(classes) for (let i = 0; i < keys.length; i++) { const classDef = classes[keys[i]] const node = drawClass(diagram, classDef) // Add nodes to the graph. The first argument is the node id. The second is // metadata about the node. In this case we're going to add labels to each of // our nodes. g.setNode(node.id, node) logger.info('Org height: ' + node.height) } const relations = classDb.getRelations() relations.forEach(function (relation) { logger.info('tjoho' + getGraphId(relation.id1) + getGraphId(relation.id2) + JSON.stringify(relation)) g.setEdge(getGraphId(relation.id1), getGraphId(relation.id2), { relation: relation }) }) dagre.layout(g) g.nodes().forEach(function (v) { if (typeof v !== 'undefined') { logger.debug('Node ' + v + ': ' + JSON.stringify(g.node(v))) d3.select('#' + v).attr('transform', 'translate(' + (g.node(v).x - (g.node(v).width / 2)) + ',' + (g.node(v).y - (g.node(v).height / 2)) + ' )') } }) g.edges().forEach(function (e) { logger.debug('Edge ' + e.v + ' -> ' + e.w + ': ' + JSON.stringify(g.edge(e))) drawEdge(diagram, g.edge(e), g.edge(e).relation) }) diagram.attr('height', '100%') diagram.attr('width', '100%') diagram.attr('viewBox', '0 0 ' + (g.graph().width + 20) + ' ' + (g.graph().height + 20)) }