Пример #1
0
  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))
}