vue引入D3绘制流程图

1 篇文章 0 订阅
npm install d3
npm install dagre-d3

这样项目里面就可直接引入使用了 如过项目里面使用比较多 可以在main.js里面全局引入 不多的话就在vue文件里面引入即可

import dagreD3 from 'dagre-d3'
import * as d3 from 'd3'

需要注释我都标注在代码里面了

    // 设置节点和连线
    renderGagre() {
      let self = this
      this.tooltip = this.createTooltip()
      // 创建graph对象
      const g = new dagreD3.graphlib.Graph()
      // 设置图
      g.setGraph({
        rankdir: 'TB', // T:top B:bottom
        marginx: 60,
        marginy: 80,
        edgesep: 100,
        ranksep: 60,
      })
      // this.chartList.forEach((item) => {
      //   g.setNode(item.id, {
      //     // 节点标签
      //     label: item.label,
      //     // 节点形状
      //     shape: item.shape,
      //     // toolText: item.toolText,
      //     // 节点样式
      //     style: item.color ? item.color : "fill:#c0c1c3;stroke:transparent",// 根据后台数据来改变节点颜色
      //     labelStyle: "fill:#fff;",
      //     width: 83,
      //     height: 40
      //   });
      // });
      // this.linkList.forEach((item) => {
      //   g.setEdge(item.source, item.target, {
      //     // 边标签
      //     // label: item.label,
      //     arrowheadStyle: item.color ? item.color : "fill:#c0c1c3;", // 根据后台数据来改变连线箭头的颜色
      //     // 边样式
      //     style: item.color
      //       ? item.color
      //       : "fill:#ffffff;stroke:#c0c1c3;stroke-width:1.5px" // 根据后台数据来改变连线的颜色
      //   });
      // });
      //---------------------上面注释的是一种显示的办法 就是分别加流程图的节点和线
      this.states = []
      this.chartList.map((item) => {
        this.states.push(item.currentPoint)
      })  //  所有节点名称起点的数组
      this.chartList.map((item) => {
        this.states.push(item.absender)
      })  // 所有节点名称终点的数组
      this.states = [...new Set(this.states)]    // es6去重
      // Automatically label each of the nodes
      this.states.forEach(function (state) {
        g.setNode(state, { label: state })
      })
      this.chartList.forEach((item) => {
        g.setEdge(item.currentPoint, item.absender, { label: '' })
      })
      g.nodes().forEach(function (v) {
        var node = g.node(v)
        node.rx = node.ry = 5
      })
      if (this.states.length) {
        g.node(this.states[0]).style = 'fill: #f77'  //  第一个节点添加颜色
      }

      // 创建渲染器
      const render = new dagreD3.render()

      // 建立拖拽缩放
      let svg = d3.select('svg')
      // 选择svg并添加一个g元素作为绘图容器
      let svgGroup = svg.append('g')
      // const zoom = d3.zoom().on("zoom", () => {
      // svgGroup.attr("transform", d3.event.transform);
      // });
      var zoom = d3.behavior.zoom().on('zoom', function () {
        svgGroup.attr(
          'transform',
          'translate(' +
            d3.event.translate +
            ')' +
            'scale(' +
            d3.event.scale +
            ')',
        )
      })
      svg.call(zoom)

      // 在绘图容器上运行渲染器生成流程图
      render(svgGroup, g)
      // Center the graph
      var initialScale = 0.9  // 这个是图形缩小的倍数
      zoom
        .translate([
          (self.$refs.drawer.offsetHeight - g.graph().width * initialScale) / 2,
          20,
        ])
        .scale(initialScale)
        .event(svg)
      svg.attr('height', g.graph().height * initialScale + 10)
      // var xCenterOffset = (svg.attr('width') - g.graph().width) / 2
      // svgGroup.attr('transform', 'translate(' + xCenterOffset + ', 20)')
      // svg.attr('height', g.graph().height + 40)
      // 鼠标悬停显示隐藏tooptip
      svgGroup
        .selectAll('g.node')
        .on('mouseover', (v) => {
          // 假如当前toolText为"",则不展示
         //这里就是自定义tooltip的内容
          let filList = [],
            strList = []
          filList = self.chartList.filter((ii) => {
            return ii.currentPoint === g.node(v).label
          })
          if (!filList.length) {
            return
          }
          filList.map((k) => {
            strList.push(k.telegram)
          })
          self.tipVisible(strList.join('\n'))
        })
        .on('mouseout', () => {
          this.tipHidden()
        })

      svgGroup.selectAll('g.node').on('click', (e) => {
        //点击事件
        // code = this.list.nodeInfos.filter(item => {
        //     return item.id == e;
        // });
        // console.log(code);
        let pointObj = this.chartList.filter((item) => {
          return item.currentPoint === e
        })
        self.logShow = true
        self.currSpool = e
        setTimeout(() => {
          self.logLoading = true
        }, 60)
        self.logList = []
        self.getLogInfo(pointObj)
      })
    },
    // 创建提示框
    createTooltip() {
      return d3
        .select('body')
        .append('div')
        .classed('tooltip', true)
        .style('opacity', 0)
        .style('display', 'none')
    },
    // tooltip显示
    tipVisible(textContent) {
      this.tooltip
        .transition()
        .duration(400)
        .style('opacity', 0.9)
        .style('display', 'block')
      this.tooltip
        .html(textContent)
        .style('left', `${d3.event.pageX + 15}px`)
        .style('top', `${d3.event.pageY + 15}px`)
    },

    // tooltip隐藏
    tipHidden() {
      this.tooltip
        .transition()
        .duration(400)
        .style('opacity', 0)
        .style('display', 'none')
    },
.tooltip {
  z-index: 10000;
  position: absolute;
  font-size: 12px;
  text-align: left;
  background-color: white;
  border-radius: 3px;
  box-shadow: rgb(174, 174, 174) 0px 0px 10px;
  cursor: pointer;
  display: inline-block;
  padding: 6px;
  max-width: 300px;
  word-wrap: break-word;
  word-break: normal;
}

.tooltip > div {
  padding: 10px;
}
.node rect {
  stroke: #333;
  fill: #999;
}
.node {
  cursor: pointer;
}

.edgePath path {
  stroke: #333;
  fill: #333;
  stroke-width: 1.5px;
}

上面有借鉴大佬的 自己页根据需求改了些 代码有点乱 在这里记录下~

记录大佬的链接:https://blog.csdn.net/davidPan1234/article/details/82851392?utm_medium=distribute.pc_relevant.none-task-blog-OPENSEARCH-7.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-OPENSEARCH-7.control

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值