如何使用鼠标拖动在d3中添加多选功能

时间:2013-11-25 14:12:33

标签: javascript d3.js multi-select force-layout

directed graph我有一个应用程序,我使用D3.js制作有向图。该图完全解决了我的目的,它是一个有向图形,形成一个类似于网格的结构。现在我想用鼠标拖动选择这个应用程序的多个节点,并且还希望它们的值在控制台中打印。这是我的应用程序..

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.link {
fill: none;
stroke: #666;
stroke-width: 1.5px; 
}

  #licensing {
 fill: green;
 }

  .link.licensing {
  stroke: green;
  }

 .link.resolved {
 stroke-dasharray: 0, 2 1; 
 }

  circle {
  fill: #ccc;
  stroke: #333;
  stroke-width: 1.5px;
  }

   text {
   font: 10px sans-serif;
   pointer-events: none;
   text-shadow: 0 1px 0 #fff, 1px 0 0 #fff, 0 -1px 0 #fff, -1px 0 0 #fff;
   }
  </style>
  <body>
  <script src="http://d3js.org/d3.v3.min.js"></script>
 <script>
// http://blog.thomsonreuters.com/index.php/mobile-patent-suits-graphic-of-the-day/

/*Here licensing type is making the green arrow
 *Here resolved type is making the solid arrow
 *Here suit type is making the dotted arrow
 *
 *
 **/

var links = [ {
    source : "Microsoft",
    target : "Amazon",
    type : "licensing"
}, {
    source : "Microsoft",
    target : "HTC",
    type : "licensing"
}, {
    source : "Samsung",
    target : "Apple",
    type : "suit"
}, {
    source : "Motorola",
    target : "Apple",
    type : "suit"
}, {
    source : "Nokia",
    target : "Apple",
    type : "resolved"
}, {
    source : "HTC",
    target : "Apple",
    type : "suit"
}, {
    source : "Kodak",
    target : "Apple",
    type : "suit"
}, {
    source : "Microsoft",
    target : "Barnes & Noble",
    type : "suit"
}, {
    source : "Microsoft",
    target : "Foxconn",
    type : "suit"
}, {
    source : "Apple",
    target : "HTC",
    type : "suit"
}, {
    source : "Microsoft",
    target : "Inventec",
    type : "suit"
}, {
    source : "Samsung",
    target : "Kodak",
    type : "resolved"
}, {
    source : "LG",
    target : "Kodak",
    type : "resolved"
}, {
    source : "RIM",
    target : "Kodak",
    type : "suit"
}, {
    source : "Sony",
    target : "LG",
    type : "suit"
}, {
    source : "Kodak",
    target : "LG",
    type : "resolved"
}, {
    source : "Apple",
    target : "Nokia",
    type : "resolved"
}, {
    source : "Qualcomm",
    target : "Nokia",
    type : "resolved"
}, {
    source : "Kodak",
    target : "Samsung",
    type : "resolved"
}, {
    source : "Apple",
    target : "Samsung",
    type : "suit"
}, {
    source : "Kodak",
    target : "RIM",
    type : "licensing"
}, {
    source : "Kodak",
    target : "Qualcomm",
    type : "licensing"
} ];

var nodes = {};

// Compute the distinct nodes from the links.
links.forEach(function(link) {
    link.source = nodes[link.source] || (nodes[link.source] = {
        name : link.source
    });
    link.target = nodes[link.target] || (nodes[link.target] = {
        name : link.target
    });
});

var width = 960, height = 500;

var force = d3.layout.force().nodes(d3.values(nodes)).links(links)
        .size([ width, height ]).linkDistance(60).charge(-300).on(
                "tick", tick).start();

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

// Per-type markers, as they don't inherit styles.
svg.append("defs").selectAll("marker").data(
        [ "suit", "licensing", "resolved" ]).enter().append("marker")
        .attr("id", function(d) {
            return d;
        }).attr("viewBox", "0 -5 10 10").attr("refX", 15).attr("refY",
                -1.5).attr("markerWidth", 6).attr("markerHeight", 6)
        .attr("orient", "auto").append("path").attr("d",
                "M0,-5L10,0L0,5");

var path = svg.append("g").selectAll("path").data(force.links())
        .enter().append("path").attr("class", function(d) {
            return "link " + d.type;
        }).attr("marker-end", function(d) {
            return "url(#" + d.type + ")";
        });




var circle = svg.append("g").selectAll("circle").data(force.nodes())
        .enter().append("circle").attr("r", 6).call(force.drag);

var text = svg.append("g").selectAll("text").data(force.nodes())
        .enter().append("text").attr("x", 8).attr("y", ".31em").text(
                function(d) {
                    return d.name;
                });

   //selection is happening 
var selected = circle.filter(function(d) {
    return d.name;
});
//here i am getting all the nodes and sending to the console here i need a selector by which i will select a couple of nodes by mouse drag and then send them to the console 
selected.each(function(d) {
      // d contains the data for the node and this is the circle element
      console.log(d.name);
    });

// Use elliptical arc path segments to doubly-encode directionality.
function tick() {
    path.attr("d", linkArc);
    circle.attr("transform", transform);
    text.attr("transform", transform);
}

function linkArc(d) {
    var dx = d.target.x - d.source.x, dy = d.target.y - d.source.y, dr = Math
            .sqrt(dx * dx + dy * dy);
    return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr
            + " 0 0,1 " + d.target.x + "," + d.target.y;
}

function transform(d) {
        return "translate(" + d.x + "," + d.y + ")";
    }

</script>

这里当我运行脚本时,所有节点都会进入控制台。但我想在这里选择一个,我希望我会通过鼠标拖动选择几个节点,这些值将进入控制台。

0 个答案:

没有答案