搜索d3强制有向图

时间:2017-03-10 12:26:42

标签: d3.js

我已经创建了一个强制布局,其中图像为节点,鼠标悬停在文本上。

但是,现在我尝试使用文本框和搜索按钮添加搜索特定节点的功能。当用户搜索文本时,我想选择匹配的节点及其连接。匹配的节点和连接将改变颜色。我的代码如下,但我的搜索功能没有按预期工作。如何更改此代码以获得所需的行为?

     <!DOCTYPE html>

      <meta charset="utf-8">
     <style>

     .link {
     stroke: #777;
     stroke-opacity: 0.3;
      stroke-width: 1.5px;
     }

      .node circle {
      fill: #ccc;
      stroke: #000;
      stroke-width: 1.5px;
      }

      .node text {
         fill: red;
      display: none;
      font: 10px sans-serif;
      }

     .node:hover circle {
     fill: #000; 
     }

    .node:hover text {
    display: inline;
    }

    .cell {
    fill: none;
    pointer-events: all;
    }

     </style>
    <body>
    <script src="https://d3js.org/d3.v3.min.js"></script>
    <div>
    <input id="targetNode" name="targetNode" type="text" value="Enter the text" />
    <button onclick="search()">Search</button>
    </div>
    <script>

    var width =1500,
    height = 650

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

    var force = d3.layout.force()
    .gravity(0.1)
    .charge(-500)
    .linkDistance(100)
    .size([width, height]);

    d3.json("miserables1.json", function(error, json) {
     if (error) throw error;
    force
    .nodes(json.nodes)
    .links(json.links)
    .start();

    var link = svg.selectAll(".link")
    .data(json.links)
    .enter().append("line")
    .attr("class", "link");

    var node = svg.selectAll(".node")
    .data(json.nodes)
    .enter().append("g")
    .attr("class", "node")
     .call(force.drag);

    node.append("svg:image")
    .attr("xlink:href", function(d) {

    return d.imagen;

     })
    .attr("x", function(d) {
     return -25;
     })
     .attr("y", function(d) {
      return -25;
     })
    .attr("height", 50)
    .attr("width", 50)
    .append("title")
    .text(function(d){ return d.name });


    function search() {

    var userInput = document.getElementById("targetNode"); 
    var theNode = d3.select("#c"+userInput.value);
    return theNode;

    }

    function linkToNodes() {
    force.links().forEach(function(link) {
    linkedByIndex[link.source.index + "," + link.target.index] = 1;
    });
    }

    function neighboring(a, b) {
    return linkedByIndex[a.index + "," + b.index] || linkedByIndex[b.index + "," + a.index]    || a.index == b.index;
    }



    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("transform", function(d) {
    return "translate(" + d.x + "," + d.y + ")";
    });

    });
    });

    </script>

1 个答案:

答案 0 :(得分:0)

当用户点击搜索时,我不太确定您打算做什么。您的搜索功能会尝试选择var node = svg.selectAll(".node") .data(nodes) .enter().append("g") .attr("id", d => "c" + d.name) // setting ID here .attr("class", "node") .call(force.drag); ,但我在页面上看不到任何ID。如果您的数据具有您希望其可搜索的名称字段,则可以使用以下内容将每个节点的ID设置为该名称:

function search() {
    var userInput = document.getElementById("targetNode"); 
    var theNode = d3.select("#c"+userInput.value);

    theNode.style("color", "red");
}

这将允许你的搜索功能获得对节点的引用,但是当前它只是返回它,并且调用函数不会对该引用做任何事情,如果你想强调那个节点是选择你应该在这里放一些代码来做到这一点,例如:

{{1}}