将dagre-d3与vue2

问题描述

我正在尝试使用Vue2使用dagre-d3建立非常简单的示例来呈现有向图。 不幸的是,即使有一个非常简单的例子,它也不起作用。在线其他地方找到的示例正在使用旧版本的d3。 当前,Vue2应用主要是认模板,带有以typescript为语言的路由器。 Diagram组件位于javascript中(由于我的代码中缺少d3dagre-d3的类型)。

运行下面提到的组件时,发生以下错误,并且<svg>块中未显示任何内容

Error in mounted hook: "TypeError: edge is undefined"

它发生在这一行

render(container,g);

我唯一能想到的是,我可能会缺少一些依赖项,或者所有组件都必须是打字稿。

帮助?

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",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链接here

解决方法

此组件有两个问题:

  1. 需要设置默认边缘标签

我错过了一个关于图表实例化的电话。应该是

const g = new dagreD3.graphlib.Graph()
    .setGraph({})
    .setDefaultEdgeLabel(function () { return {} })
  1. d3.select()选择并使用了错误的节点进行渲染。由于使用fontawesome,在router-link中,我正在使用以下
<router-link to="/about">
    <font-awesome-icon :icon="['fas','info-circle']" />
</router-link>

由于font-awesome-icon已渲染到<svg>元素,因此渲染正在该节点中进行,但是我只有在使用默认边缘修复后才注意到这一点。

如果有人遇到相同的问题,this就是帮助我确定已解释问题的示例