如何在D3强制布局中将上下文菜单放在画笔上

时间:2014-02-23 04:51:09

标签: javascript d3.js contextmenu force-layout brush

我正在使用D3移动父套件api,其中所有节点都用实线或虚线相互连接。我能够在api上添加画笔效果。现在我想在画笔中添加一个上下文菜单,这样当我使用画笔选择节点时,我可以右键单击画笔并添加一些选项,因为我必须对所选值执行某些操作。现在我能够在其他地方添加此上下文菜单,但在这里,我不能在这里粘贴我的完整代码,

<!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;
  }

 .brush .extent {
  fill-opacity: .1;
  stroke: #fff;
  shape-rendering: crispEdges;
  }
  </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 = [];
    var nodes = {};

    // Compute the distinct nodes from the links.

    var width = 960, height = 500;

    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");


           d3.json(
                    "directed.json",
                    function(error, directed) {

                         links=directed.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 force = d3.layout.force().nodes(
                                d3.values(nodes)).links(links).size(
                                [ width, height ]).linkDistance(60).charge(
                                -300).on("tick", tick).start();

                        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;
                        });

                        selected.each(function(d) {
                            // d contains the data for the node and this is the circle element

                            //console.log(d.name);
                        });

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

                        var clickfn = function(circle) {
                            alert(circle);
                        }

                        // 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 + ")";
                        }

        var brush = svg.append("g")
  .datum(function() { return {selected: false, previouslySelected: false}; })
  .attr("class", "brush")
  .call(d3.svg.brush()
    .x(d3.scale.identity().domain([0, width]))
    .y(d3.scale.identity().domain([0, height]))
    .on("brushend", function(d) {
        console.log(d3.selectAll("circle.selected")); 
    })
    .on("brush", function() {
      var extent = d3.event.target.extent();
      circle.classed("selected", function(d) {
        return d.selected = d.previouslySelected ^
            (extent[0][0] <= d.x && d.x < extent[1][0]
            && extent[0][1] <= d.y && d.y < extent[1][1]);

      });

    }));

    $(function() {
                        var selectedVal;
                        $.contextMenu({
                            selector : '.brushend',
                            callback : function(key, options) {
                                var row = options.$trigger;
                                var newUrl = key;

                                var actionUrl;
                                if (key === 'network_analysis.do') {
                                    var rows = row.find("td").eq(2).html();
                                    actionUrl = '?' + 'a_no='
                                            + rows.toLocaleString();
                                }


                                document.forms[0].action = newUrl
                                        + actionUrl;
                                document.forms[0].submit();
                            },
                            items : {

                                "network_analysis.do" : {
                                    name : "Network Analysis"
                                }
                            }


         });
    });


    });

</script>

这是我的json

{
        "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"
    } ]
 }

请看任何人可以提供帮助..

0 个答案:

没有答案