我应该如何使用搜索按钮从大型JSON文件访问特定数据?

时间:2017-08-22 14:41:51

标签: javascript json node.js d3.js force-layout

我的最终目标是使用d3创建一个强制布局,我的搜索ui-widget与此类似:

<div class="ui-widget">
    <input id="search">
    <button type="button" onclick="searchNode()">Search</button>
</div>

我想使用ui-widget搜索节点,当它找到它时,我想只显示链接到它的所有链接和节点的节点。 问题是我在链接的大JSON文件中有多组节点和链接。我不知道如何加载所有这些内容。以下是我的一些选择:

  1. 以某种方式创建一个带有键/值的hashmap - &gt;命名/ JSON的所有内容并将其推送到数组中。当我使用该搜索按钮进行搜索时,我将只查找该键并显示该值。
  2. 重新格式化JSON以拥有所有节点,并且在所有链接之后,在2个大块中,不像我现在拥有节点/链接,节点,链接。
  3. 我有这个包含许多JSON的大型JSON

    JSON.json

    {
      "nodes": [
        {"id": "Source","label":"source","group": 0},
        {"id": "Parent_1","label":"name6","group": 1},
        {"id": "Parent_2","label":"name5","group": 1},
        {"id": "Parent_3","label":"name4","group": 1},
        {"id": "Child_1","label":"name3","group": 2},
        {"id": "Child_2","label":"name2","group": 2},
        {"id": "Child_3","label":"name1","group": 2},
        {"id": "Child_4","label":"name0", "group": 3}
      ],
      "links": [
        { "source": "Source","target": "Parent_1"},
        { "source": "Source","target": "Parent_2"},
        { "source": "Source","target": "Parent_3"},
        { "source": "Source","target": "Child_1"},
        { "source": "Source","target": "Child_2"},
        { "source": "Source","target": "Child_3"},
        { "source": "Child_2","target": "Child_4"}
      ]
    }
    {
      "nodes": [
        {"id": "Source","label":"source","group": 0},
        {"id": "Parent_12","label":"name6","group": 1},
        {"id": "Parent_22","label":"name5","group": 1},
        {"id": "Parent_32","label":"name4","group": 1},
        {"id": "Child_12","label":"name3","group": 2},
        {"id": "Child_22","label":"name2","group": 2},
        {"id": "Child_32","label":"name1","group": 2},
        {"id": "Child_42","label":"name0", "group": 3}
      ],
      "links": [
        { "source": "Source","target": "Parent_12"},
        { "source": "Source","target": "Parent_22"},
        { "source": "Source","target": "Parent_32"},
        { "source": "Source","target": "Child_12"},
        { "source": "Source","target": "Child_22"},
        { "source": "Source","target": "Child_32"},
        { "source": "Child_22","target": "Child_42"}
      ]
    }
    

    的index.html

    <!DOCTYPE html>
    <meta charset="utf-8">
    <style>
    
    .links line {
      stroke: #999;
      stroke-opacity: 0.6;
    }
    
    .nodes circle {
      stroke: #fff;
      stroke-width: 1.5px;
    }
    .node text {
      font: 9px helvetica;
    }
    
    </style>
    <svg width="960" height="600"></svg>
    <script src="https://d3js.org/d3.v4.min.js"></script>
    <script>
    
    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));
    
    d3.json("JSON.json", function(error, graph) {
      if (error) throw error;
    
      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", 5)
          .attr("fill", function(d) { return color(d.group); })
          .call(d3.drag()
              .on("start", dragstarted)
              .on("drag", dragged)
              .on("end", dragended));
    
    node.append("text")
          .attr("dx", 10)
          .attr("dy", ".35em")
          .text(function(d) { return d.label })
          .style("stroke", "gray");
      node.on("click", function() {
          alert(function(d){return d.Statement})
          d3.event.stopPropagation();
      });
    
     node.on('mouseover', function(d){
        var nodeSelection = d3.select(this).style({opacity:'0.8'});
        nodeSelection.select("text").style({opacity:'1.0'});
    })
    
    
      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) {
      if (!d3.event.active) simulation.alphaTarget(0.3).restart();
      d.fx = d.x;
      d.fy = d.y;
    }
    
    function dragged(d) {
      d.fx = d3.event.x;
      d.fy = d3.event.y;
    }
    
    function dragended(d) {
      if (!d3.event.active) simulation.alphaTarget(0);
      d.fx = null;
      d.fy = null;
    }
    
    </script>
    

    我想要的是与此相似,除了我的所有节点都保存在不同的文件中:http://jsfiddle.net/simonraper/Bf5nM/?utm_source=website&utm_medium=embed&utm_campaign=Bf5nM

    如果问题不清楚请告诉我,我可以编辑,谢谢。

    我解析了多个文件,结果是一个大的JSON文件。在那个JSON文件中,我有一组节点和链接,你可以看到,我想一次代表一个组。

1 个答案:

答案 0 :(得分:0)

如果要单独搜索它们,则无需将它们全部放入一个数组中。我不熟悉d3,但不会像这样简单的for循环做伎俩;其中currentObject是您要搜索的JSON块:

var searchedId = document.getElementById("search").value;
for (var i=0; i<currentObject.nodes.length; i++) {
    var node = currentObject.nodes[i];
    if (node.id == searchedId) {
        // display node
    }
}