d3v4力图升级清理

时间:2020-05-31 11:17:54

标签: javascript d3.js force-layout

enter image description here

我有一些旧的关系类型-d3版本3中的力图。

我热衷于清理并减少代码库-减少对所有功能的依赖。我不得不重构数据集并创建节点。我已经开始尝试移植代码-但现在遇到升级错误-“ d3.force不是函数”

将此作为参考D3 forceSimulation and dragging, what is node.fx/node.fy?

  • 热衷于修复升级
  • 重构以使此图表的创建变得更容易,更简单-使用数据图吗?

//版本3 https://jsfiddle.net/695ocnv7/3/

//版本4 https://jsfiddle.net/r376fg0d/

  var forceChart = {
    buildDataStream: function(userData){
      var data = new Array();
        
      $.each(userData, function( index, value ) {
      
        var interestArray = new Array();
         $.each(value.interests, function( x, v ) {
          
           var localInterestObj = {
             "label": Object.keys(v)[0],
             "name": "--"+Object.keys(v)[0].toLowerCase(),
             "size": v[Object.keys(v)[0]],
             "group": "level1",
             "children": []
           };
           interestArray.push(localInterestObj);
         
         });
        
        var childrenArray = [
            {
              "label": "Interests",
              "name": "-interests"+"-"+index,
              "group": "level2",
              "children": interestArray
            }        
        ]
        
        var userObj = {
          "label": value.userName,
          "name": "+"+index+"-"+value.userName.toLowerCase(),
          "group": "User",
          "userID": index,
          "children": childrenArray
        }
            
        data.push(userObj);
      });
      
      return data;
    },
    addUserPatterns: function(patternsSvg, userData){

        /*
        I figured this out.

        The height and width on a pattern element seem to function sort of like a scale / percentage. So a width of "1" means it will fill the whole element it is set to. A width of ".25" means 25% of that element. Then, within the <pattern> you would specify the height and width of the image as the actual pixel value of the height and width of the circle they are filling, so in this case my code was changed to:
        */


      $.each(userData, function(index, value) {
        var defs = patternsSvg.append('svg:defs');
          defs.append('svg:pattern')
            .attr('id', "--"+index+"-"+value.userName.toLowerCase())
            .attr('width', 1)
            .attr('height', 1)
            .append('svg:image')
            .attr('image-rendering', "optimizeQuality")
            .attr('preserveAspectRatio', "xMidYMid meet")
            .attr('xlink:href', value.userImage)
            .attr('x', 0)
            .attr('y', 0)
            .attr('width', 100)
            .attr('height', 100);
      });
    },
    invoke: function(holder, userData){
      var data = this.buildDataStream(userData);

      var patternsSvg = d3.select(holder)
                .append('svg')
                .attr('class', 'patterns')
                .attr('width', 0)
                .attr('height', 0);
      
      this.addUserPatterns(patternsSvg, userData);
      
      return data;
    }
  };

  var nodeMaker = {
    recursiveNode: function(value, nodes, level){
      var that = this;
      
      var children = new Array();
      if(value.children.length > 0){
        for(var c=0;c<value.children.length;c++){
          children.push(value.children[c].name);
        }
      }
      
      var orbSizesArray = [100, 20, 3, 1];
      
      var count = orbSizesArray[level];
          
      var localNode = {
            "name": value.name,         
            "group": value.group,
            "label": value.label,
            "level": level,
            "count": count,
            "linkCount": value.children.length,
            "children": children
          };
      nodes.push(localNode);    

      if(value.children.length > 0){
        level++;
        for(var c=0;c<value.children.length;c++){
          that.recursiveNode(value.children[c], nodes, level);
        }
      }
    },
    createNode: function(data){
      var that = this;
      var nodes = new Array();

      $.each(data, function(index, value) { 
        var level = 0;    
        that.recursiveNode(value, nodes, level);
      });

      return that.discoverChildren(nodes);
    },
    findPosition: function(nodes, c){   
      var pos = 0;
      $.each(nodes, function(i, x) {
        if(x.name == c){
          pos = i;
          return false;
        }
      }); 
      
      return pos;
    },
    discoverChildren: function(nodes){
      var that = this;
      
      $.each(nodes, function( index, value ) {
        var childrenPositionArray = new Array();
        $.each(value.children, function(i, c) {
          childrenPositionArray.push(that.findPosition(nodes, c)); //positionOfChild
        });

        nodes[index]["childrenPositions"] = childrenPositionArray;
        nodes[index]["nodePosition"] = index;
      });

      return nodes;
    },
    createLinks: function(nodes){

      var links = new Array();

      $.each(nodes, function(i, val) {
        var source = val.nodePosition;
          
        if(val.childrenPositions.length > 0){
        
          for(var c=0;c<val.childrenPositions.length;c++){
            var target = val.childrenPositions[c];
              
             var localLink = {
                "source": source,
                "target": target,
                "depth": 1,
                "count": 1    
              };
            
            links.push(localLink);
          }
        }     
      });
          
      return links;
    }
  };
    

//////////

更新-2020年6月17日

这是最新的工作版本4-但需要集成模式和数据重构-https://jsfiddle.net/batv60je/1/

我创建了一个重构函数来获取输入数据并从中创建节点/链接-https://jsfiddle.net/batv60je/4/

//////////

2020年6月24日

图案中的图像没有正确地放置在圆圈中,尺寸错误或位移不正确?需要为商品使用可读标签,而不是ID。如果有人单击或悬停在节点上,我想更改电荷以引起连锁反应。热衷于稳定此图表,以使其不会脱离画布边缘。在http://jsfiddle.net/L9xodt1z

处输入图像描述

enter image description here

关系力图 我已经重构了旧图表-并进行了数据配置,以生成使此图表起作用的节点/链接。

-图案中的图像没有正确地放置在圆圈中,大小或位移是否正确?

-需要对商品使用可读标签,而不是ID。

-如果有人在节点上单击或悬停,我想更改电荷以引起连锁反应。

-渴望稳定此图表,以使其不会从画布的边缘浮出水面。


0 个答案:

没有答案