Esempio n. 1
0
def generateGraph(functionName, flow):
    g = Graph('G', filename=functionName, engine='dot')
    g.attr(rank='same')
    g.attr(rankdir='LR')
    g.graph_attr = {
        'fontname': 'MS Gothic',
        'fontsize': '10',
    }
    g.node_attr = {
        'shape': 'plaintext',
        'fontname': 'MS Gothic',
        'fontsize': '10',
        'fixedsize': 'true',
        'width': '2.165',  # inch
        'height': '0.472'
    }  # inch

    nodes = []
    node = {'level': None, 'index': None, 'shape': None, 'label': None}
    index = 0
    level = 1
    maxLvl = 1
    connectWith = None
    branches = []
    for element in flow:
        elementID = element['comment']
        if elementID == 'fc:end':
            # If fc:end is in flow, we have to return one level back. This element
            # is empty element, no node is needed.
            level -= 1
            connectWith = branches[-1]
            del (branches[-1])
            continue
        if elementID == 'fc:else':
            connectWith = branches[-1]
            continue
        element['level'] = level
        element['index'] = index
        shapePath = os.path.split(os.path.abspath(__file__))[0]
        shape = os.path.join(shapePath, SHAPES[elementID])
        element['shape'] = shape
        element['connectWith'] = connectWith
        connectWith = index

        if elementID == 'fc:ifBranch' or elementID == 'fc:forLoop':
            # For loop and if we create branch which means going into new level.
            level += 1
            branches.append(index)
        if level > maxLvl:
            maxLvl = level
        nodes.append(dict(element))
        index += 1

    # Create level structure
    for level in range(1, maxLvl + 1):
        g1 = Graph(str(level))
        for node in nodes:
            if node['level'] == level:
                index = str(node['index'])
                label = node['label']
                shape = node['shape']
                comment = node['comment']

                # Only startStop element is smaller. Others are bigger.
                if comment == 'fc:startStop':
                    g1.node(index,
                            label=label,
                            image=shape,
                            width="1.299",
                            height="0.394")
                else:
                    g1.node(index, label=label, image=shape)
        g.subgraph(g1)

    # Connect nodes
    branches = []
    label = ''
    for node in nodes:
        connectWith = node['connectWith']
        index = node['index']
        comment = node['comment']

        if connectWith == None:
            continue
        else:
            label = ''
            connectingNode = nodes[connectWith]
            if connectingNode['comment'] == 'fc:ifBranch':
                if index == connectWith + 1:
                    label = 'TRUE'
                else:
                    if node['level'] != connectingNode['level']:
                        label = 'FALSE'
            if (connectingNode['comment'] == 'fc:forLoop'
                    and node['level'] != connectingNode['level']):
                label = 'loop'

            g.edge(str(connectWith), str(index), label=label)

    if VIEW:
        g.view(directory=DEST)
    else:
        g.render(directory=DEST)