I have in python a dictionary that represents a tree style parent child relationship. I want to display the dictionary on the webpage. FYI: The dictionary will end up being all names and will very base on the person entering info.
Example dictionary from Python:
dict_ = {'A':['B', 'C'], 'B':['D','E'], 'C':['F', 'G', 'H'], 'E':['I', 'J']}
root = 'A'
The desired HTML output display would be.
A
├── B
│ ├── D
│ └── E
│ ├── I
│ └── J
└── C
├── F
├── G
└── H
I not sure how to get this type of display using flask, Jinja, of other options like javascript. Some guidance, partial, or full answers would be great. ( I did learn how to use treelib to display it in terminal but not html.)
In my solution, a helper function is used to create a tree consisting of dicts from the given dict with the lists it contains. Thus, the hierarchy is given to render a structure of nested list elements with a jinja macro.
def tree_find(e, t):
if e in t:
return t
for v in t.values():
r = tree_find(e, v)
if r:
return r
return None
@app.route('/')
def index():
dict_ = {'A':['B', 'C'], 'B':['D','E'], 'C':['F', 'G', 'H'], 'E':['I', 'J']}
tree = {}
for k,v in dict_.items():
n = tree_find(k, tree)
(tree if not n else n)[k] = {e:{} for e in v}
return render_template('index.html', **locals())
{% macro render_tree(d) -%}
<ul>
{% for k,v in d.items(): -%}
<li><span>{{k}}</span>
{% if v -%}
{{ render_tree(v) }}
{% endif -%}
</li>
{% endfor -%}
</ul>
{%- endmacro %}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Tree</title>
<style type="text/css">
ul, li {
position: relative;
}
ul {
list-style: none;
padding-left: 16px;
}
li::before, li::after {
content: "";
position: absolute;
left: -12px;
}
li::before {
border-top: 1px solid #000;
top: 9px;
width: 8px;
height: 0;
}
li::after {
border-left: 1px solid #000;
height: 100%;
width: 0px;
top: 2px;
}
ul > li:last-child::after {
height: 8px;
}
</style>
</head>
<body>
{{ render_tree(tree) }}
</body>
</html>