def linked_layers(edge_list:list,list_of_dicts:list,parent_name:str) -> None:
    """

    """
    use_case = AGraph(directed=True)
    use_case.clear()
    use_case.graph_attr.update(compound="true")
    # use_case.add_node("up",
    #                   label="up",
    #                   shape="rectangle",
    #                   color="blue",
    #                   href=parent_name+".svg")

    for edge_pair in edge_list:
        if task_has_children_in_list_of_dicts(edge_pair[0], list_of_dicts):
            sg = use_case.subgraph(name="cluster_"+parent_name+smush(edge_pair[0]),
                                   label=with_spaces(edge_pair[0]))
            sg.add_node(parent_name+smush(edge_pair[0]), style="invis")
            for sg_edge_pair in get_subgraph(edge_pair[0],list_of_dicts):
                if task_has_children_in_list_of_dicts(sg_edge_pair[0],list_of_dicts):
                    sg.add_node(parent_name+smush(edge_pair[0])+smush(sg_edge_pair[0]),
                                label=with_spaces(sg_edge_pair[0]),
                                shape="rectangle",
                                color="blue",
                                # name length is limited to 10 characters to
                                # avoid file names that exceed OS limits.
                                href=parent_name+"_"+smush(edge_pair[0])[:10]+".svg")
                    if not path.exists(parent_name+"_"+smush(edge_pair[0])[:10]+".svg"):
                        linked_layers(get_subgraph(edge_pair[0],list_of_dicts),
                                      list_of_dicts,
                                      parent_name+"_"+smush(edge_pair[0])[:10])
                else:
                    sg.add_node(parent_name+smush(edge_pair[0])+smush(sg_edge_pair[0]),
                                label=with_spaces(sg_edge_pair[0]))
                if sg_edge_pair[1] is not None:
                    if task_has_children_in_list_of_dicts(sg_edge_pair[1],list_of_dicts):
                        sg.add_node(parent_name+smush(edge_pair[0])+smush(sg_edge_pair[1]),
                                    label=with_spaces(sg_edge_pair[1]),
                                    shape="rectangle",
                                    color="blue",
                                    href=parent_name+"_"+smush(edge_pair[0])[:10]+".svg")
                        if not path.exists(parent_name+"_"+smush(edge_pair[0])[:10]+".svg"):
                            linked_layers(get_subgraph(edge_pair[0],list_of_dicts),
                                          list_of_dicts,
                                          parent_name+"_"+smush(edge_pair[0])[:10])
                    else:
                        sg.add_node(parent_name+smush(edge_pair[0])+smush(sg_edge_pair[1]),
                                    label=with_spaces(sg_edge_pair[1]))
                    sg.add_edge(parent_name+smush(edge_pair[0])+smush(sg_edge_pair[0]),
                                parent_name+smush(edge_pair[0])+smush(sg_edge_pair[1]))#,constraint=False)
        else: # node does not have children
            use_case.add_node(parent_name+smush(edge_pair[0]),
                              label=with_spaces(edge_pair[0]))
        if edge_pair[1] is not None:
            if task_has_children_in_list_of_dicts(edge_pair[1], list_of_dicts):
                sg = use_case.subgraph(name="cluster_"+parent_name+smush(edge_pair[1]),
                                       label=with_spaces(edge_pair[1]))
                sg.add_node(parent_name+smush(edge_pair[1]), style="invis")
                for sg_edge_pair in get_subgraph(edge_pair[1],list_of_dicts):
                    if task_has_children_in_list_of_dicts(sg_edge_pair[0], list_of_dicts):
                        sg.add_node(parent_name+smush(edge_pair[1])+smush(sg_edge_pair[0]),
                                    label=with_spaces(sg_edge_pair[0]),
                                    shape="rectangle",
                                    color="blue",
                                    href=parent_name+"_"+smush(edge_pair[1])[:10]+".svg")
                        if not path.exists(parent_name+"_"+smush(edge_pair[1])[:10]+".svg"):
                            linked_layers(get_subgraph(edge_pair[1],list_of_dicts),
                                          list_of_dicts,
                                          parent_name+"_"+smush(edge_pair[1])[:10])
                    else:
                        sg.add_node(parent_name+smush(edge_pair[1])+smush(sg_edge_pair[0]),
                                    label=with_spaces(sg_edge_pair[0]))
                    if sg_edge_pair[1] is not None:
                        if task_has_children_in_list_of_dicts(sg_edge_pair[1], list_of_dicts):
                            sg.add_node(parent_name+smush(edge_pair[1])+smush(sg_edge_pair[1]),
                                        label=with_spaces(sg_edge_pair[1]),
                                        shape="rectangle",
                                        color="blue",
                                        href=parent_name+"_"+smush(edge_pair[1])[:10]+".svg")
                            if not path.exists(parent_name+"_"+smush(edge_pair[1])[:10]+".svg"):
                                linked_layers(get_subgraph(edge_pair[1],list_of_dicts),
                                              list_of_dicts,
                                              parent_name+"_"+smush(edge_pair[1])[:10])
                        else:
                            sg.add_node(parent_name+smush(edge_pair[1])+smush(sg_edge_pair[1]),
                                        label=with_spaces(sg_edge_pair[1]))
                        sg.add_edge(parent_name+smush(edge_pair[1])+smush(sg_edge_pair[0]),
                                    parent_name+smush(edge_pair[1])+smush(sg_edge_pair[1]))#,constraint=False)
            else: # node does not have children
                use_case.add_node(parent_name+smush(edge_pair[1]),
                                  label=with_spaces(edge_pair[1]))
            use_case.add_edge(parent_name+smush(edge_pair[0]),
                              parent_name+smush(edge_pair[1]))
    print("parent name =",parent_name)
    use_case.write(parent_name+".dot")
    use_case.draw(parent_name+".svg", format="svg", prog="dot")

    return
def this_layer_plus_one(list_of_task_dicts: list, list_of_subtasks: list,
                        output_filename: str, recursive_depth: int,
                        parent: str) -> None:
    """
    recursively create hyperlinked SVGs using GraphViz
    input data structure is a list of dicts
    """

    # need the filename prefix for both this file and the child files
    fnamel = "layer_plus_one_" + str(recursive_depth) + "_"
    fnamel1 = "layer_plus_one_" + str(recursive_depth + 1) + "_"

    # initialize a new graph for this layer
    use_case = AGraph(directed=True,
                      comment=output_filename)  #, compound=True)
    use_case.clear()
    use_case.graph_attr.update(compound="true")
    for task in list_of_subtasks:
        #print(task)
        for this_dict in list_of_task_dicts:
            if list(this_dict.keys())[0] == task:

                #unique_subgraph_name = task_without_spaces#+"_"+str(random.randint(1000,9999))
                if (task_has_children_in_list_of_task_dicts(
                        task, list_of_task_dicts)):
                    sg = use_case.subgraph(name="cluster_" + smush(task),
                                           label=with_spaces(task),
                                           href=fnamel1 + smush(task) + ".svg")
                else:  # no href to SVG because there are no child nodes
                    sg = use_case.subgraph(name="cluster_" + smush(task),
                                           label=with_spaces(task))

                sg.add_node(smush(task), style="invis")

                #print(task)
                #print(list(this_dict.keys())[0])
                subitem_list = list(this_dict.values())[0]
                #                print(subitem_list)

                if len(subitem_list) < 2:  # no edges to connect
                    if (task_has_children_in_list_of_task_dicts(
                            subitem_list[0], list_of_task_dicts)):
                        sg.add_node(smush(task) + smush(subitem_list[0]),
                                    label=with_spaces(subitem_list[0]),
                                    href=fnamel1 + smush(task) + ".svg",
                                    color="blue",
                                    shape="rectangle")
                    else:
                        sg.add_node(smush(task) + smush(subitem_list[0]),
                                    label=with_spaces(subitem_list[0]),
                                    shape="rectangle")
                    sg.add_edge(smush(task) + smush(subitem_list[0]),
                                smush(task),
                                style="invis")

                else:
                    for index, subitem in enumerate(subitem_list[1:]):
                        #print('   ',subitem)
                        if (task_has_children_in_list_of_task_dicts(
                                subitem_list[index], list_of_task_dicts)):
                            sg.add_node(smush(task) +
                                        smush(subitem_list[index]),
                                        label=with_spaces(subitem_list[index]),
                                        href=fnamel1 + smush(task) + ".svg",
                                        color="blue",
                                        shape="rectangle")
                        else:  # no children to link to
                            sg.add_node(smush(task) +
                                        smush(subitem_list[index]),
                                        label=with_spaces(subitem_list[index]),
                                        shape="rectangle")
                        if (task_has_children_in_list_of_task_dicts(
                                subitem, list_of_task_dicts)):
                            sg.add_node(smush(task) + smush(subitem),
                                        label=with_spaces(subitem),
                                        href=fnamel1 + smush(task) + ".svg",
                                        color="blue",
                                        shape="rectangle")
                        else:
                            sg.add_node(smush(task) + smush(subitem),
                                        label=with_spaces(subitem),
                                        shape="rectangle")

                        # every sequence of tasks is ordered, so link task with prior task
                        sg.add_edge(
                            smush(task) + smush(subitem_list[index]),
                            smush(task) + smush(subitem))
                        if index == len(
                                subitem_list
                        ):  # last item links to invisible node in order to force invisible node to bottom of subgraph
                            sg.add_edge(smush(task) +
                                        smush(subitem_list[index]),
                                        smush(task),
                                        style="invis")

    for index, task_tup in enumerate(list_of_subtasks[1:]):
        # use_case.add_node(smush(list_of_subtasks[index]),label=with_spaces(task_tup),shape="rectangle")
        # use_case.add_node(smush(task_tup),label=with_spaces(task_tup),shape="rectangle")
        use_case.add_edge(smush(list_of_subtasks[index]),
                          smush(task_tup),
                          ltail="cluster_" + smush(list_of_subtasks[index]),
                          lhead="cluster_" + smush(task_tup))

    if recursive_depth > 0:
        use_case.add_node("zoom out",
                          href=parent + ".svg",
                          color="red",
                          shape="triangle")
    #use_case.write()
    use_case.draw(fnamel + output_filename + ".svg", format="svg", prog="dot")
    #print("drew SVG for ", output_filename)

    for task_tuple in list_of_subtasks:
        for index, this_dict in enumerate(list_of_task_dicts):
            if task_tuple in this_dict.keys():
                this_layer_plus_one(list_of_task_dicts,
                                    list_of_task_dicts[index][task_tuple],
                                    smush(task_tuple), recursive_depth + 1,
                                    fnamel + output_filename)
    return