d3.js v4实现关系拓扑图

前言:因为最近公司业务需求,需要在App中实现关系拓扑图。由于自己之前学习了下Vue.js和一些前端知识和ThinkPHP。就自告奋勇把任务接下来了。后来才发现真的是too young too simple,后端数据接口和Android部分都还好说,但这个拓扑图真是让我欲哭无泪,后来了解了Vis.js和百度出品的echart,也都尝试着去实现自己想要的功能。却都因为可定制化差强人意,不能满足我的强迫症而放弃。这时,我的目光落在了d3.js上。比起上面两个框架,虽然d3.js可定制化能力强,但这也意味着学习成本更高,实现难度更大。而最巧的是d3.js从v3版本升级到了v4版本,其中的接口都发生了很大的变化,网上的相关的资料并不多,而且官方文档又是英文比较“简洁”。对新手来说真的十分不友好,我只好看着文档和网上仅有的资料不断抹着眼泪,不断尝试。自己接的任务,跪着也要写完。

以下是核心代码:

主要分为三块:html代码和js代码、css代码,这里css用的预编译器是stylus

<template>
  <div id="app" class="container">
    <button type="button" class="exit" @click="jsBack" ref="exit" v-if="isPc">退出</button>
  </div>
</template>

<script type="text/ecmascript-6">
  //  import vis from 'vis'
  import * as d3 from 'd3'

  export default {
    name: 'app',
    data () {
      return {
        relation: {},
        cname: '',
        isPc: false
      }
    },
    methods: {
      jsBack () {
//        返回按钮
        var u = navigator.userAgent
        var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1
        var isiOS = u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/) //ios终端
        if (isAndroid) {
//          Android端
          window.android.back()
        } else if (isiOS) {
//          ios端
        }
      },
      showd3 () {
//        获取body高度和宽度
        let height = document.body.clientHeight
        let width = document.body.clientWidth

        //移动端设备横竖屏重新加载页面
        function change () {
          window.location.reload()
        }

        window.addEventListener('onorientationchange' in window ? 'orientationchange' : 'resize', change, false)
//        节点大小(圆圈大小)
        const nodeSize = 35
//        初始化时连接线的距离长度
        const linkDistance = 130
//        赋值数据集
        var nodes = this.relation.nodes
        var links = this.relation.links
//      设置画布,获取id为app的对象,添加svg,这里的图像用了svg,意为可缩放矢量图形,它与其他图片格式相比较,svg更加小,因为是矢量图,放大不会失帧。具体可以自行百度svg相关知识
        var svg = d3.select('#app').append('svg')
          .attr('xmlns', 'http://www.w3.org/2000/svg')
          .attr('version', '2.0')
          .attr('class', 'svg')//给svg设置了一个class样式,主要作用是长宽设置为100%
//        设置力布局,使用d3 v4版本的力导向布局
        var force = d3.forceSimulation()
          .force('center', d3.forceCenter(width / 2, height / 2))//设置力导向布局的中心点,创建一个力中心,设置为画布长宽的一半,所以拓扑图会在画布的中心点
          .force('charce', d3.forceManyBody().strength(-70))//节点间的作用力,如果不设置.strength(-60)的话,默认是-30
          .force('collide', d3.forceCollide())//使用默认的半径创建一个碰撞作用力。radius默认所有的节点都为1

//        设置缩放
//        svg下嵌套g标签,缩放都在g标签上进行
        var g = svg.append('g')
//        d3.zoom是设置缩放,pc端是滚轮进行缩放,在移动端可以通过两指进行缩放
        var zoomObj = d3.zoom()
          .scaleExtent([0.5, 1.2]) // 设置缩放范围
          .on('zoom', () => {
            //监听zoom事件,zoom发生时,调用该方法
            const transform = d3.event.transform //获取缩放和偏移的数据,不懂得同学可以自行通过console.log(d3.event.transform)滑动滚轮查看数据变化
            g.attr('transform', transform)   // 设置缩放和偏移量 transform对象自带toString()方法
          })
          .on('end', () => {
//            该方法在缩放时间结束后回调
            // code
          })
        svg.call(zoomObj)
//        绘制箭头
        //箭头
        // eslint-disable-next-line no-unused-vars
        var markerBlue =
          g.append('marker')
            .attr('id', 'resolvedBlue')
            //.attr("markerUnits","strokeWidth")//设置为strokeWidth箭头
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值