D3 Force Directed Graph的节点点击事件未触发

时间:2016-09-16 09:46:51

标签: d3.js onclick drag d3v4

我正在尝试通过单击节点本身来折叠节点。目前的图是具有可拖动节点的力导向图。

我面临的问题是,在附加节点点击事件后,我无法触发点击而是节点从其位置移开(就像在鼠标点击时拖动一样)。

var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height");

var color = d3.scaleOrdinal(d3.schemeCategory20);

var simulation = d3.forceSimulation()
    .force("link", d3.forceLink().id(function(d) { return d.id; }))
    .force("charge", d3.forceManyBody())
    .force("center", d3.forceCenter(width / 2, height / 2));

var graph = { "links" : [ { "relation" : "Relation 0",
        "source" : 0,
        "target" : 1
      },
      { "relation" : "Relation 1",
        "source" : 1,
        "target" : 3
      },
      { "relation" : "Relation 3",
        "source" : 1,
        "target" : 4
      },
      { "relation" : "Relation 4",
        "source" : 1,
        "target" : 5
      },
      { "relation" : "Relation 5",
        "source" : 0,
        "target" : 2
      },
      { "relation" : "Relation 6",
        "source" : 2,
        "target" : 6
      }
    ],
  "nodes" : [ { "collapsed" : false,
        "collapsing" : 0,
        "id" : 0,
        "name" : "Node 0"
      },
      { "collapsed" : false,
        "collapsing" : 0,
        "id" : 1,
        "name" : "Node 1"
      },
      { "collapsed" : false,
        "collapsing" : 0,
        "id" : 2,
        "name" : "Node 2"
      },
      { "collapsed" : false,
        "collapsing" : 0,
        "id" : 3,
        "name" : "Node 3"
      },
      { "collapsed" : false,
        "collapsing" : 0,
        "id" : 4,
        "name" : "Node 4"
      },
      { "collapsed" : false,
        "collapsing" : 0,
        "id" : 5,
        "name" : "Node 5"
      },
      { "collapsed" : false,
        "collapsing" : 0,
        "id" : 6,
        "name" : "Node 6"
      }
    ]
};
var edges = [];
graph.links.forEach(function(e) {
  var sourceNode = graph.nodes.filter(function(n) {
    return n.id === e.source;
  })[0],
      targetNode = graph.nodes.filter(function(n) {
        return n.id === e.target;
      })[0];

  edges.push({
    source: sourceNode,
    target: targetNode,
    relation: e.relation
  });
});

update();

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

  var node = svg.append("g")
      .attr("class", "nodes")
    .selectAll("circle")
    .data(graph.nodes)
    .enter().append("circle")
      .attr("r", 8)
      .attr("fill", function(d) { return color(d.group); })
      .on("click", togglenode)
      .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended));

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

  simulation
      .nodes(graph.nodes)
      .on("tick", ticked);

  simulation.force("link")
      .links(graph.links);

  function ticked() {
    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; });
  }
}

function dragstarted(d) {
  console.log('drag started');
  if (!d3.event.active) simulation.alphaTarget(0.3).restart();
  d.fx = d.x;
  d.fy = d.y;
}

function dragged(d) {
  console.log('dragged');
  d.fx = d3.event.x;
  d.fy = d3.event.y;
}

function dragended(d) {
  console.log('drag ended');
  if (!d3.event.active) simulation.alphaTarget(0);
  d.fx = null;
  d.fy = null;
}
function togglenode(d) {
  console.log('clicked node : '+d.id);
  if (!d3.event.defaultPrevented) {
    var inc = d.collapsed ? -1 : 1;
    recurse(d);

    function recurse(sourceNode){
      //check if link is from this node, and if so, collapse
      edges.forEach(function(l) {
        if (l.source.id === sourceNode.id){
          l.target.collapsing += inc;
          recurse(l.target);
        }
      });
    }

    d.collapsed = !d.collapsed;

    update();
  }
}
.links line {
  stroke: #999;
  stroke-opacity: 0.6;
}

.nodes circle {
  stroke: #fff;
  stroke-width: 4.5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.2.3/d3.js"></script>

<svg width="800" height="500"></svg>

0 个答案:

没有答案