代码之家  ›  专栏  ›  技术社区  ›  ItayB

通过其ID获取节点

  •  1
  • ItayB  · 技术社区  · 8 年前

    我用的是d3。用于创建图形的js mNode 作为节点和 mLink 作为链接。 在以下代码中, otherLink 有 source & 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 回复  |  直到 8 年前
        1
  •  1
  •   Gerardo Furtado    8 年前

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

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

    如果我正确理解了您的问题,那么您希望在 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,我将连接的节点更改为红色: https://bl.ocks.org/anonymous/0db9b4307a1ff6724f89c932f55f6508/2a6cfa3a8bfb03cfa368033faa3804ae5601e403