具有较少边缘的D3力定向图重绘

时间:2016-01-28 10:59:10

标签: javascript jquery d3.js graph

我正在尝试为力导向图添加一个阈值,其中我将仅包括高于我在地图中存储的某个阈值的顶点之间的边。我的滑块部分工作,边缘成功移除。 Before...

After...

但是,在删除边缘后,图形会停止动画,并且在调用force.start()时控制台中会出错。我真的需要添加独特的ID吗?在我链接的JSFiddle中,他没有这样做,他的滑块没有问题。

谢谢! Console Error StackOverflow上有类似问题的答案有多个,我用它们来修复我明显的错误(例如d3.js: "Cannot read property 'weight' of undefined" when manually defining both nodes and links for force layout),但我还是这个。我正在使用此示例:来自此网站的http://jsfiddle.net/simonraper/TdHgx/?utm_source=website&utm_medium=embed&utm_campaign=TdHgxhttp://www.coppelia.io/2014/07/an-a-to-z-of-extra-features-for-the-d3-force-layout/

我将发送相关的JS。

         function draw(occurence) {
        var ratio = window.devicePixelRatio || 1;

        var width = Math.min(700,0.8*$(window).width()), height = 700;
        var color = d3.scale.category20();
        var svg = d3.select("#" + occurence).append("svg")
            .attr("width", width)
            .attr("height", height)
            .attr("id", "#" + occurence + "svg");

        d3.json(occurence + ".json", function(error, graph) {
          if (error) throw error;

          var force = d3.layout.force()
            .charge(-120)
            .linkDistance(50)
            .size([width, height]);

          force
              .nodes(graph.nodes)
              .links(graph.links)
              .start();
          if (occurence == "occurrences3") {
            console.log(graph.nodes);
            console.log(graph.links);
          }

          var graphRec=JSON.parse(JSON.stringify(graph)); //Add this line

          var link = svg.selectAll(".link")
              .data(graph.links)
            .enter().append("line")
              .attr("class", "link")
              .style("stroke-width", function(d) { return Math.sqrt(d.value); });

          var node = svg.selectAll(".node")
              .data(graph.nodes)
            .enter().append("circle")
              .attr("class", "node")
              .attr("r", 5)
              .style("fill", function(d) { return color(d.group); })
              .call(force.drag);

          node.append("title")
              .text(function(d) { return d.name; });

          force.on("tick", function() {
            link.attr("x1", function(d) { return d.source.x; })
                .attr("y1", function(d) { return d.source.y; })
                .attr("x2", function(d) { return d.target.x; })
                .attr("y2", function(d) { return d.target.y; });

          node.attr("cx", function(d) { return d.x; })
              .attr("cy", function(d) { return d.y; });
          });

          node.on("dblclick", function(d) {
            $("#uncuratedGraphsModal").modal();
            var d = d3.select(this).node().__data__;
            var name = d.name;
            $("#uncuratedGraphsModalHeader").text("Node " + name);
            $("#uncuratedGraphsModalBody").empty();
            var edge_by_person = edge_by_person_per_threshold[occurence + "edge_by_person"];
            var edges = edge_by_person[name];
            edges.sort(function(a,b) {
                return a.dest - b.dest;
            });
            $.each(edges, function(edge) {
                var new_edge = $("<li>");
                new_edge.text("Neighbor: " + edges[edge].dest + ", Token: " + edges[edge].token);
                $("#uncuratedGraphsModalBody").append(new_edge);
            });
          });
          $("#" + occurence + "thresholdSlider").on('input', function(thresh) {
            threshold($("#" + occurence + "thresholdSlider").val());
          });
          //adjust threshold
          function threshold(thresh) {
              var edge_by_person = edge_by_person_per_threshold_unweighted[occurence + "edge_by_person_unweighted"];
              graph.links.splice(0, graph.links.length);
              for (var i = 0; i < graphRec.links.length; i++) {
                var source = graphRec.links[i].source.name;
                var dest = graphRec.links[i].target.name;
                var value = -1;
                var edges = edge_by_person[source];
                var found = false;
                for (var edge = 0; !found && edge < edges.length; edge++) {
                  if (dest == edges[edge].dest) {
                    value = edges[edge].token;
                    found = true;
                  }
                }
                if (value >= thresh) {
                  graph.links.push({
                    source: graphRec.links[i].source.name,
                    target: graphRec.links[i].target.name,
                    value: graphRec.links[i].value
                  });
                }
              }
              restart();
          }
          //Restart the visualisation after any node and link changes
          function restart() {
            link = link.data(graph.links);
            link.exit().remove();
            link.enter().insert("line", ".node").attr("class", "link")
            .style("stroke-width", function(d) { return Math.sqrt(d.value); });

            node = node.data(graph.nodes);
            node.enter().insert("circle", ".cursor").attr("class", "node")
              .attr("r", 5)
              .style("fill", function(d) { return color(d.group); })
              .call(force.drag);
            force
              .nodes(node)
              .links(link)
              .start();
          }
        });
      }

这是他从我链接的JsFiddle添加的JS:

JsAddition

这是我的理解:如果您有相同的节点,并且只是从graph.links中删除了一些边缘,那么您不能只执行force.start()吗?当我直接复制他的restart()函数时,所有链接都被破坏,并且没有重绘,即使执行console.log(graph.links)显示正确的重绘链接。

我认为此时它正在与错误的节点对话,可能是错误的SVG。我在同一页面上有多个SVG。

0 个答案:

没有答案