I'm trying to set up very simple example with Vue2
using dagre-d3
for rendering directed graphs.
Unfortunately, even with extremely simple example, it wont work. Examples found elsewhere online are using older version of d3
.
Currently, Vue2
app is mostly default template with a router with a typescript
as language. Diagram
component is in javascript
(due to missing types in my code for d3
and dagre-d3
).
When running the component mentioned below, following error happens and nothing is shown in the <svg>
block.
Error in mounted hook: "TypeError: edge is undefined"
And it happens on this line
render(container, g);
Only thing i can think off is that i might be missing some some dependencies or that all components must be typescript.
Help?
Diagram.vue:
<template>
<div class="myback">
<h1>This is a diagram component</h1>
<svg>
<g></g>
</svg>
</div>
</template>
<script>
import * as d3 from "d3";
import dagreD3 from "dagre-d3";
// let edges = {}
// let nodes = {}
// let g = new dagreD3.graphlib.Graph().setGraph({})
export default {
/*
data () {
return {
edges: {},
nodes: {}
}
},
*/
mounted() {
/* create graph itself */
const g = new dagreD3.graphlib.Graph().setGraph({});
g.setGraph({
nodesep: 70,
ranksep: 50,
rankdir: "LR",
marginx: 20,
marginy: 20,
});
console.log(g);
const render = new dagreD3.render(); // eslint-disable-line new-cap
console.log(render);
const svg = d3.select("svg");
const container = svg.select("g");
console.log(svg);
console.log(container);
/* define zoom behavior */
function zoomed(e) {
container.attr("transform", e.transform);
}
const zoom = d3.zoom().scaleExtent([1, 10]).on("zoom", zoomed);
g.setNode("kspacey", { label: "Kevin Spacey", width: 144, height: 100 });
g.setNode("blabla", { label: "blabla", width: 144, height: 100 });
g.setEdge("kspacey", "blabla");
svg.call(zoom);
render(container, g);
},
/*
methods: {
draw () {
}
}
*/
};
</script>
<style scoped>
section {
margin-bottom: 3em;
}
section p {
text-align: justify;
}
svg {
border: 1px solid #ccc;
overflow: hidden;
margin: 0 auto;
background: white;
width: 800px;
height: 600px;
}
text {
font-weight: 300;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serf;
font-size: 14px;
}
path.link {
fill: none;
stroke: #666;
stroke-width: 1.5px;
}
.node rect {
stroke: #333;
fill: #fff;
stroke-width: 1.5px;
}
.myback {
background: gray;
}
</style>
Codesanbox link is here
There were two problems with this component:
I was missing a call on the graph instantiation. It should have been
const g = new dagreD3.graphlib.Graph()
.setGraph({})
.setDefaultEdgeLabel(function () { return {} })
<router-link to="/about"> <font-awesome-icon :icon="['fas', 'info-circle']" /> </router-link>
Because the font-awesome-icon is rendered to <svg>
element, rendering was happening in that node, but i only noticed this after fix with the default edge.
If someone has the same issue, this example was the one that helped me identify explained issues