按ID获取节点

时间:2017-12-20 09:41:35

标签: javascript d3.js

我正在使用d3.js创建图表,其中mNode为节点,mLink为链接。 在以下代码中,otherLinksource& target个字段,指的是连接到此链接的节点。 otherLink.source只是一个包含节点数据的对象,例如:

{"id": 1,
 "index: 0,
 ...
}

如何在此节点上应用样式(请查看下面的// DOESN'T WORK行:

function Graph(elementId) {
  var svg;
  var simulation;
  var mNodesData = [];
  var mEdgesData = [];
  var mNode = null;
  var mLink = null;
  var elementId;
  var heightDelta = 100;
  var width = window.innerWidth;
  var height = window.innerHeight - heightDelta;

  return {
      init: function () {
          svg = d3.select('#' + elementId)
              .append("svg")
              .attr("width", width)
              .attr("height", height);

          simulation = d3.forceSimulation()
              .force(".edge", d3.forceLink())
              .force("charge", d3.forceManyBody().strength(-600))
              .force("center", d3.forceCenter(width / 2, height / 2));

          mLink = svg.selectAll(".edge")
              .attr("class", "edge")
              .style("stroke", LINK_DEFAULT_COLOR)
              .style("stroke-width", function (e) {
                  return 1
                  /* e.width*/
              });

          mNode = svg.selectAll(".node")
              .attr("class", "node");
      },
      draw: function () {
          mLink = svg.selectAll(".edge")
              .data(mEdgesData)
              .enter()
              .append("line")
              .attr("class", "edge")
              .style("stroke", LINK_DEFAULT_COLOR)
              .style("stroke-width", function (e) {
                  return 2
                  /* e.width*/
              }).merge(mLink).lower();

          mNode = svg.selectAll(".node")
              .data(mNodesData)
              .enter()
              .append("g")
              .attr("class", "node").merge(mNode);

          mNode.call(d3.drag()
              .on("start", dragstarted)
                  .on("drag", dragged)
                  .on("end", dragended));

          mNode.on('mouseover', function (currentNode) {
              mLink.filter(function (otherLink) {
                  if (currentNode !== otherLink.source) {
                      otherLink.source.style("opacity", BACKGROUND_OPACITY); // DOESN'T WORK
                  }
                  return (currentNode !== otherLink.source && currentNode !== otherLink.target);
              }).style("opacity", BACKGROUND_OPACITY);
              mLink.filter(function (otherLink) {
                  return (currentNode == otherLink.source || currentNode == otherLink.target);
              }).style("opacity", DEFAULT_OPACITY);
          });

          simulation.nodes(mNodesData);
          simulation.force(".edge").links(mEdgesData);
      }
  }
}

完整代码:here

1 个答案:

答案 0 :(得分:1)

首先,代码中的currentNodeotherLink.source是这些元素的数据。因此,要获取ID,您必须使用其属性。例如,在您的条件中:

if (currentNode.id !== otherLink.source.id)
//property here--^----------------------^

如果我正确理解了您的问题,您希望在mouseover时获取连接到给定节点的节点(或多个节点)的ID,然后更改该连接节点(或任何其他节点)的样式改变你想要的。)

这是一个可能的解决方案。首先,在mouseover上,我们获取当前节点的ID:

mNode.on('mouseover', function(currentNode) {
    var thisNodeID = currentNode.id;

然后,我们使用该ID来填充具有连接节点(或多个节点)的ID(或多个ID)的数组:

var connectedNodes = mEdgesData.filter(function(d){
    return d.source.id === thisNodeID || d.target.id === thisNodeID
}).map(function(d){
    return d.source.id === thisNodeID ? d.target.id : d.source.id
});

最后,我们使用indexOf来检查该列表中的节点:

mNode.filter(function(d){
  return connectedNodes.indexOf(d.id) > -1
}).style("opacity", DEFAULT_OPACITY);

总之,它将是:

mNode.on('mouseover', function(currentNode) {
    var thisNodeID = currentNode.id;
    var connectedNodes = mEdgesData.filter(function(d) {
        return d.source.id === thisNodeID || d.target.id === thisNodeID
    }).map(function(d) {
        return d.source.id === thisNodeID ? d.target.id : d.source.id
    });
    mNode.filter(function(d) {
        return connectedNodes.indexOf(d.id) > -1
    }).style("opacity", DEFAULT_OPACITY);
});

由于您没有提供正在运行的代码,以下是基于Mike Bostock的bl.ocks的mouseover代码段示例,我将连接的节点更改为红色:{{3} }