d3.js中的一个函数,用于从不同大小的JSON源创建开始和结束节点以及节点和链接文本

时间:2016-10-25 19:02:29

标签: javascript jquery d3.js

我的JSON数据如下所示:

var IDData = JSON.stringify([["node/105173", "node/38180995", "Agent", "Customer", "1379644.0", 1, 264.0, "1374903"], ["node/1061", "node/21373542", "Agent", "Customer", "530848.0", 1, 3000.0, "529502"]....]

数组数组的长度各不相同,但元素内部的位置始终相同。

我有以下jquery函数可以迭代这些数据:

$(document ).ready(function() {
   console.log(IDData);
   var galData = JSON.parse(IDData);
   var startnodes = [];
   var endnodes = [];
   var startnodetype = [];
   var endnodetype = [];
   var PayTime = [];
   var TXN_COUNT = [];
   var Total_Amt = [];
   var SendTime = [];

galData.map(function(e,i){
   startnodes.push(e[0]);
   endnodes.push(e[1]);
   startnodetype.push(e[2]);
   endnodetype.push(e[3]);
   PayTime.push(e[4]);
   TXN_COUNT.push(e[5]);
   Total_Amt.push(e[6]);
   SendTime.push(e[7]);
 });

var final_data =createNodes(startnodes,endnodes,startnodetype,endnodetype,PayTime,TXN_COUNT,Total_Amount,SendTime);                           
 makeGraph("#Network_graph",final_data)

  });

然后将数据传递给创建节点函数,如下所示:

  function createNodes (start_nodes, end_nodes,startnodetype,endnodetype,PayTime,TXN_COUNT,Total_Amount,SendTime) {
      var node_set = d3.set(); 
      var links = [];
      var nodetype = d3.set();
      var link_Paytime  = [];
      var link_TXN_COUNT = [];
      var link_Amt = [];
      var link_SendTime = [];

    start_nodes.forEach(function(src, i){
         var tgt = end_nodes[i];
         node_set.add(src);
         node_set.add(tgt);
         links.push({source: src, target: tgt, value: 1});
      });

     startnodetype.forEach(function(src,i){
          var tgt_type = endnodetype[i];
          nodetype.add(src);
          nodetype.add(tgt_type);

  });         
    var d3GraphData = {
       nodes: node_set.values().map(function(d){ return {id: d, group: 1}}),
       links: links,
       nodetype: nodetype.values().map(function(d){return {id:d, group:1} })        
       link_Paytime: ?,
       link_TXN_COUNT: ??,
       link_Amt: ??,
       link_SendTime: ??,
            }
         return d3GraphData;
         };
  function makeGraph (selector, d3GraphData) {
      var svg = d3.select(selector),
      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 link = svg.append("g")
    .attr("class", "links")
    .selectAll("line")
    .data(d3GraphData.links)
    .enter()
    .append("line")
    .attr("stroke-width", function(d) { return Math.sqrt(d.value); })
    .on("mouseout",function() {div.html("Hover over the link");})
    .on("mouseover",mouse_link);  // calling mouseover function for links

 var node = svg.append("g")
      .attr("class", "nodes")
      .selectAll("circle")
      .data(d3GraphData.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)
    )
     .on("mouseout",function() {div.html("Hover over the node");})
     .on("mouseover",mouse_node);   //calling the mouseover function for nodes

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

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

   simulation.force("link")
       .links(d3GraphData.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;
}

   function mouse_node(d){
         div.html{"Node text is" + d.nodetype
          .
   function mouse_link(d){
            div.html("Link text is " + d.link_PayTime,d.link_TXN_COUNT,d.link_Amt,d.link_SendTime);
                            } 
};

下面应该是HTML:

    <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
    <script src="http://d3js.org/d3.v4.min.js"></script>
    <div id="graph"></div>
    <div id="text">Hover over the link</div>
    <div id= "text">Hover over the node</div>

使用此d3图库作为参考:      makeGraph代码中的http://bl.ocks.org/mbostock/4062045; 我可以添加起始节点和结束节点并形成链接,如上所示。我也能够从它们渲染图形。但我还需要一种填充

的方法
    nodetype,link_Paytime, link_TXN_COUNT,link_Amt, link_SendTime 

并在d3GraphData中使用它们,后来将用作&#34; text&#34;在节点和链接上。这是我在d3.js上的第一个项目。

2 个答案:

答案 0 :(得分:1)

下面的

代码是在将鼠标悬停在节点和链接上时显示文本的代码:

https://jsfiddle.net/vishy1988/t6ycuoyo/21/

     var tooltip = d3.select("body")
  .append("div")
  .attr("class", "tooltip")
  .style("opacity", 0);

   var link = svg.append("g")
    .attr("class", "links")
    .selectAll("line")
    .data(d3GraphData.links)
    .enter().append("line")
    .attr("stroke-width", function(d) {
      return Math.sqrt(d.value);
      .on('mouseover', function(d) {
          tooltip.transition()
            .duration(300)
            .style("opacity", .8);
          tooltip.html("<p/>Paytime:" + d.paytime + "<p/>Txn_count:" + d.txn_count + "<p/>Amount:" + d.Total_Amt + "<p/>SendTime:" + d.SendTime)

          .style("left", (d3.event.pageX) + "px")
            .style("top", (d3.event.pageY + 10) + "px");
        })
        .on("mouseout", function() {
          tooltip.transition()
            .duration(100)
            .style("opacity", 0);
        })
        .on("mousemove", function() {
          tooltip.style("left", (d3.event.pageX) + "px")
            .style("top", (d3.event.pageY + 10) + "px");
        });
    });

  var node = svg.append("g")
    .attr("class", "nodes")
    .selectAll("circle")
    .data(d3GraphData.nodes)
    .enter().append("circle")
    .attr("r", 5)
    .attr("fill", function(d) {
      return color(d.group);
    })
    .on('mouseover', function(d) {
      tooltip.transition()
        .duration(300)
        .style("opacity", .8);
      tooltip.html(d.id + "<p/>type:" + d.type)
        .style("left", (d3.event.pageX) + "px")
        .style("top", (d3.event.pageY + 10) + "px");
    })
    .on("mouseout", function() {
      tooltip.transition()
        .duration(100)
        .style("opacity", 0);
    })
    .on("mousemove", function() {
      tooltip.style("left", (d3.event.pageX) + "px")
        .style("top", (d3.event.pageY + 10) + "px");
    })

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

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

  simulation.force("link")
    .links(d3GraphData.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;
  }

}

答案 1 :(得分:0)

因此,如果我正确理解您的问题,您的程序部分有效,但您想在节点和链接上添加一些数据(nodetype,link_Paytime,link_TXN_COUNT,link_Amt和link_SendTime)作为文本?您(也)尝试初始化d3GraphData并想要替换问号(通过数组中的正确项目)?

您是否有一个现有的示例 - 可能来自D3 gallery - 澄清您要添加的内容(节点和链接上的文本)?

有一个关于你正在构建的完整工作示例会很有帮助,例如这个html文件(这不起作用):

<!DOCTYPE html>
<meta charset="utf-8">

<svg width="960" height="600"></svg>

<script src="https://d3js.org/d3.v4.min.js"></script>

<script
    src="http://code.jquery.com/jquery-3.1.1.min.js"
    integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
    crossorigin="anonymous">
</script>

<script>

var IDData = JSON.stringify([
        ["node/105173", "node/38180995", "Agent", "Customer", "1379644.0", 1, 264.0, "1374903"],
        ["node/1061", "node/21373542", "Agent", "Customer", "530848.0", 1, 3000.0, "529502"]
    ]);

$(document).ready(function() {
    console.log(IDData);

    var galData = JSON.parse(IDData);
    var startnodes = [];
    var endnodes = [];
    var startnodetype = [];
    var endnodetype = [];
    var PayTime = [];
    var TXN_COUNT = [];
    var Total_Amt = [];
    var SendTime = [];

    galData.map(function(e, i) {
        startnodes.push(e[0]);
        endnodes.push(e[1]);
        startnodetype.push(e[2]);
        endnodetype.push(e[3]);
        PayTime.push(e[4]);
        TXN_COUNT.push(e[5]);
        Total_Amt.push(e[6]);
        SendTime.push(e[7]);
    });

    var final_data = createNodes(startnodes, endnodes, startnodetype, endnodetype, PayTime, TXN_COUNT, Total_Amt, SendTime);

    makeGraph("#Network_graph", final_data);
});

function createNodes (start_nodes, end_nodes,startnodetype,endnodetype,PayTime,TXN_COUNT,Total_Amount,SendTime) {
      var node_set = d3.set(); 
      var links = [];
      var nodetype = d3.set();
      var link_Paytime  = [];
      var link_TXN_COUNT = [];
      var link_Amt = [];
      var link_SendTime = [];

    start_nodes.forEach(function(src, i){
         var tgt = end_nodes[i];
         node_set.add(src);
         node_set.add(tgt);
         links.push({source: src, target: tgt, value: 1});
      });

     startnodetype.forEach(function(src,i){
          var tgt_type = endnodetype[i];
          nodetype.add(src);
          nodetype.add(tgt_type);
     });

    var d3GraphData = {
       nodes: node_set.values().map(function(d){ return {id: d, group: 1}}),
       links: links,
       nodetype: nodetype.values().map(function(d){return {id:d, group:1} }),
       link_Paytime: 1,
       link_TXN_COUNT: 2,
       link_Amt: 3,
       link_SendTime: 4,
    };

    return d3GraphData;
}

function makeGraph (selector, d3GraphData) {
         //graph code that already works
}

</script>