d3实现网络拓扑图可视化展示,动态修改数据

实现的功能

  • 节点信息图片展示
  • 连线信息展示
  • 连线动画效果
  • 节点拖拽
  • 缩放
  • 移入节点展示更多信息
  • 动态修改数据展示(包括添加和删除),修改vuedevtools试试看吧
    在这里插入图片描述
  • 因为公司内网的原因,不能照搬所有代码,只能实现部分。还有折叠高亮视图聚焦移动等,可以看看D3的示例。

感谢

巨人的肩膀。我是根据大佬的实现,进行了一些封装优化,我用的是最新的D3版本。

代码仓库

d3-topo

预览地址

d3-topo

一些功能的实现,详细请看源码

  • render函数
  render() {
    this.container = this.svg.append("g").attr("class", "graph");
    this.init();

	// 每次迭代必须调用修改节点和边的位置
    this.force.on("tick", () => {
      this.initLinksPosition();
      this.initNodesPosition();
    });
  }

  init() {
    this.initForce(); //初始化力模型
    this.initMarker(); //初始化连线箭头
    this.initLinks(); //连线需要在节点之前,否则会盖住
    this.initNodes(); //初始化节点
    this.initDrag(); //初始化节点拖拽
    this.initZoom(); //初始化缩放
    this.initNodeHover(); //初始化hover节点信息展示
  }
  • 初始化force
  initForce() {
    this.force = d3
      .forceSimulation(this.nodes)
      .alpha(this.alpha) //力迭代次数[0,1],越大布局越好
      .force(
        "charge",
        d3.forceManyBody().strength(this.strength).distanceMax(this.distanceMax)
      ) //strength节点之间引力,负值越大分的越开。distanceMax连线距离
      .force("link", d3.forceLink(this.links))
      .force("center", d3.forceCenter(this.width / 2, this.height / 2)); //布局中心点
  }
  • 边箭头
  initMarker() {
    this.svg
      .append("marker")
      .attr("id", "resolved")
      .attr("markerUnits", "userSpaceOnUse")
      .attr("viewBox", "0 -5 10 10") //坐标系的区域
      .attr("refX", 12) //箭头坐标
      .attr("refY", 0)
      .attr("markerWidth", 12) //标识的大小
      .attr("markerHeight", 12)
      .attr("orient", "auto") //绘制方向,可设定为:auto(自动确认方向)和 角度值
      .attr("stroke-width", 2) //箭头宽度
      .append("path")
      .attr("d", "M0,-5L10,0L0,5") //箭头的路径
      .attr("fill", "#6cbfed"); //箭头颜色
  }
  • 拖拽
  initDrag() {
    let _this = this;
    this.graphNodes.call(
      d3.drag().on("start", dragStart).on("drag", dragging).on("end", dragEnd)
    );
    function dragStart(d) {
      if (!d.active) _this.force.alphaTarget(0.2).restart();
    }
    function dragging(d) {
      d.subject.x = d.x;
      d.subject.y = d.y;
    }
    function dragEnd(d) {
      if (!d.active) _this.force.alphaTarget(0);
    }
  }
  • 缩放
  initZoom() {
    // scaleExtent缩放范围
    let _this = this;
    this.svg.call(getZoom()).on("dblclick.zoom", null);//禁止双击放大
    function getZoom() {
      return (_this.zoom = d3
        .zoom()
        .scaleExtent([0.05, 8])//缩放大小限制
        .on("zoom", (d) => {
          d3.select("g.graph").attr("transform", function () {
            return `translate(${d.transform.x},${d.transform.y}) scale(${d.transform.k})`;
          });
        }));
    }
  }
  • 更新 reRender函数。更新千万不要append,要用select,否则更新一次,节点多一倍
  reRender() {
    this.reInitLink();
    this.reInitNode();

    this.force.nodes(this.nodes);
    this.force.force("links", d3.forceLink(this.links));
    this.force.alpha(this.alpha).alphaDecay(this.alphaDecay).restart();
  }

扩展

我最后没有用D3去实现拓扑图可视化的展示。因为我们需要minimap展示,但是我写不出来😂。所以后面用到了另外一个框架–ANTV-G6。他封装了大量的操作和动画效果,还有minimap插件,上手比D3快的多。所以就采用了G6,完全可以实现一模一样的效果,并且是canvas绘制的。

G6实现拓扑图可视化展示

g6-topo

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用d3实现可视化峰峦图相比使用Matplotlib库,需要更多的代码和工作量,但是可以实现更加灵活的可视化效果。以下是一个使用d3绘制峰峦图的示例代码: ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Mountain Range</title> <script src="https://d3js.org/d3.v5.min.js"></script> <style> path { fill: none; stroke: #000; stroke-width: 1.5px; } </style> </head> <body> <svg width="960" height="500"></svg> <script> // 生成随机高程数据 var data = d3.range(100).map(function(d) { return [Math.random() * 10 - 5, Math.random() * 10 - 5, Math.random() * 3]; }); // 创建投影 var projection = d3.geoIdentity() .reflectY(true) .fitSize([960, 500], { type: "Sphere" }); // 创建路径生成器 var path = d3.geoPath() .projection(projection); // 创建颜色插值器 var color = d3.scaleLinear() .domain([0, 2]) .range(["#fff", "#69b3a2"]); // 创建SVG元素 var svg = d3.select("svg"); // 绘制山峦图 svg.selectAll("path") .data(data) .enter().append("path") .attr("d", function(d) { var x = d[0]; var y = d[1]; var h = d[2]; return path({ type: "LineString", coordinates: [[x, y], [x, y - h]] }); }) .attr("stroke", function(d) { return color(d[2]); }); </script> </body> </html> ``` 以上代码通过d3生成随机高程数据,然后使用投影和路径生成器绘制山峦图,并使用颜色插值器给不同高度的山峰着色。可以在浏览器中查看结果。如果需要更复杂的定制,可以在以上示例代码的基础上进行修改
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值