VueJS Hand-made Tree graph V2 (recursive)
by downedcrane
HTML
<script type="x-template" id="node-template">
<g class="node" transform="translate({{node.x - 50}}, {{node.y - 25}})">
<rect x="0" y="0" height="50" width="100"></rect>
<text x="5" y="15">{{node.label}}</text>
<text x="5" y="30">treePos: [{{node.level}}][{{node.index}}]</text>
<text x="5" y="45">weight: {{node.weight}}</text>
</g>
</script>
<script type="x-template" id="link-template">
<path id="{{link.id}}" class="link" v-bind:d="getPath(link)">
</script>
<div id="container">
<button v-on:click="insertRandomNode()">Insert random</button>
<svg v-bind:width="service.svgWidth" v-bind:height="service.svgHeight + 10">
<link-template v-for="link in getAllLinks(service.data)" v-bind:link="link"></link-template>
<node-template v-for="node in getAllNodes(service.data)" v-bind:node="node"></node-template>
</svg>
</div>
SCSS
.link {
fill: none;
stroke: #ccc;
stroke-width: 1px;
}
.node {
&:hover {
cursor: pointer;
rect {
fill: #49ACEE;
}
}
rect {
fill: #DFF3FF;
stroke: #49ACEE;
}
}
JavaScript
/*** COMPONENTS ***/
var nodeTemplate = {
template: '#node-template',
props: ['node']
};
var linkTemplate = {
template: '#link-template',
props: ['link'],
methods: {
getPath
}
};
/** DATA + SERVICE **/
var data = [
[{
level: 0,
index: 0,
label: 'root',
children: [{
level: 1,
index: 0
}, {
level: 1,
index: 1
}]
}],
[{
level: 1,
index: 0,
label: 'node1',
parents: [{
level: 0,
index: 0
}],
children: [{
level: 2,
index: 0
}]
}, {
level: 1,
index: 1,
label: 'node2',
parents: [{
level: 0,
index: 0
}],
children: [{
level: 2,
index: 0
}]
}],
[{
level: 2,
index: 0,
label: 'node3',
parents: [{
level: 1,
index: 0
}, {
level: 1,
index: 1
}],
}]
];
var treeService = {
data: data,
verticalSpacing: 50,
componentMargin: 25,
componentHeight: 50,
componentWidth: 100,
svgWidth: 0,
svgHeight: 0,
svgPadding: {
top: 50,
bottom: 0,
left: 0,
right: 0
}
};
/***** ALGO DRAW TREE *****/
/** START TOOLS FUNCTIONS **/
function hasParents(node) {
return node.parents && node.parents.length > 0;
}
function hasChildren(node) {
return node.children && node.children.length > 0;
}
function firstParent(node) {
var firstParent = node;
var savedX = treeService.svgWidth + treeService.svgPadding.left + treeService.svgPadding.right;
if (hasParents(node)) {
node.parents.forEach(function(parent) {
if (treeService.data[parent.level][parent.index].x < savedX) {
savedX = treeService.data[parent.level][parent.index].x;
firstParent = treeService.data[parent.level][parent.index];
}
});
}
return...