2011-12-29 14 views
22

में लिंक पर टेक्स्ट/लेबल जोड़ें मैं संशोधित बल निर्देशित ग्राफ पर काम कर रहा हूं और लिंक/लेबल को लिंक पर जोड़ने के साथ कुछ समस्याएं हैं जहां लिंक सही ढंग से नोड्स के साथ गठबंधन नहीं हैं। इसे कैसे जोड़ेंगे?डी 3 बल निर्देशित ग्राफ

और मैं एक एसवीजी पाठ तत्व में एक ईवेंट श्रोता कैसे जोड़ सकता हूं? .on("dblclick",function(d) {....} जोड़ना अभी काम नहीं करता है।

यहाँ कोड का टुकड़ा है:

<style type="text/css"> 
    .link { stroke: #ccc; } 
    .routertext { pointer-events: none; font: 10px sans-serif; fill: #000000; } 
    .routertext2 { pointer-events: none; font: 9px sans-serif; fill: #000000; } 
    .linktext { pointer-events: none; font: 9px sans-serif; fill: #000000; } 
</style> 

<div id="canvas"> 
</div> 

<script type="text/javascript" src="d3/d3.js"></script> 
<script type="text/javascript" src="d3/d3.layout.js"></script> 
<script type="text/javascript" src="d3/d3.geo"></script> 
<script type="text/javascript" src="d3/d3.geom.js"></script> 


<script type="text/javascript"> 

var w = 960, 
    h = 600, 
    size = [w, h]; // width height  
var vis = d3.select("#canvas").append("svg:svg") 
    .attr("width", w) 
    .attr("height", h) 
    .attr("transform", "translate(0,0) scale(1)") 
    .call(d3.behavior.zoom().on("zoom", redraw)) 
    .attr("idx", -1) 
    .attr("idsel", -1) 
    ; 

var routers = { 
    nodes: [ 
     {id:0, name:"ROUTER-1", group:1, ip: "123.123.123.111", 
      x:394.027, y:450.978,outif:"ge-0/1/0.0",inif:""}, 
     {id:1, name:"ROUTER-2", group:1, ip: "123.123.123.222", 
      x:385.584, y:351.513,outif:"xe-4/2/0.0",inif:"ge-5/0/3.0"}, 
     {id:2, name:"ROUTER-3", group:1, ip: "123.123.123.333", 
      x:473.457, y:252.27,outif:"ae1.0",inif:"xe-1/0/1.0"}, 
     {id:3, name:"ROUTER-4", group:2, ip: "123.123.123.444", 
      x:723.106, y:266.569,outif:"as0.0",inif:"ae1.0"}, 
     {id:4, name:"ROUTER-5", group:3, ip: "123.123.123.555", 
      x:728.14, y:125.287,outif:"so-4/0/2.0",inif:"as1.0"}, 
     {id:5, name:"ROUTER-6", group:3, ip: "123.123.123.666", 
      x:738.975, y:-151.772,outif:"",inif:"PO0/2/2/1" } 
    ], 
    links: [ 
     {source:0, target:1, value:3, name:'link-1',speed:"1000mbps", 
      outif:"ge-0/1/0.0",nextif:"ge-5/0/3.0"}, 
     {source:1, target:2, value:3, name:'link-2',speed:"10Gbps", 
      outif:"xe-4/2/0.0",nextif:"xe-1/0/1.0"}, 
     {source:2, target:3, value:3, name:'link-3',speed:"20Gbps", 
      outif:"ae1.0",nextif:"xe-1/2/1.0"}, 
     {source:3, target:4, value:3, name:'link-4',speed:"1Gbps", 
      outif:"as0.0",nextif:"as1.0"}, 
     {source:4, target:5, value:3, name:'link-5',speed:"OC3", 
      outif:"so-4/0/2.0",nextif:"PO0/2/2/1"} 
    ] 
}; 

var force = d3.layout.force() 
     .nodes(routers.nodes) 
     .links(routers.links) 
     .gravity(0) 
     .distance(100) 
     .charge(0) 
     .size([w, h]) 
     .start(); 

var link = vis.selectAll("g.link") 
     .data(routers.links) 
     .enter().append("svg:g"); 

    link.append("svg:line") 
     .attr("class", "link") 
     .attr("title", function(d) { return "From: "+d.outif+", To: "+d.nextif }) 
     .attr("style", "stroke:#00d1d6;stroke-width:4px") 
     .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; }); 

    link.append("svg:text") 
     .attr("class", "linktext") 
     .attr("dx", function(d) { return d.source.x; }) 
     .attr("dy", function(d) { return d.source.y; }) 
     .text("some text to add..."); 

    var node = vis.selectAll("g.node") 
     .data(routers.nodes) 
    .enter() 
     .append("svg:g") 
     .attr("id", function(d) { return d.id;}) 
     .attr("title", function(d) {return d.ip}) 
     .attr("class", "node") 
     .attr("x", function(d) { return d.x; }) 
     .attr("y", function(d) { return d.y; }) 
     .on("dblclick",function(d) { 
      alert('router double-clicked'); d3.event.stopPropagation(); 
     }) 
     .on("mousedown", function(d) { 
      if (d3.event.which==3) { 
       d3.event.stopPropagation(); 
       alert('Router right-clicked'); 
      } 
     }) 
     .call(force.drag); 

    node.append("svg:image") 
     .attr("class", "node") 
     .attr("xlink:href", "router.png") 
     .attr("x", -24) 
     .attr("y", -18) 
     .attr("width", 48) 
     .attr("height", 36); 

    node.append("svg:text") 
     .attr("class", "routertext") 
     .attr("dx", -30) 
     .attr("dy", 20) 
     .text(function(d) { return d.name }); 

    node.append("svg:text") 
     .attr("class", "routertext2") 
     .attr("dx", 0) 
     .attr("dy", -20) 
     .attr("title", "some title to show....") 
     .text(function(d) { return d.outif }) 
     .on("click", function(d,i) {alert("outif text clicked");}) 
     .call(force.drag); 

    node.append("svg:text") 
     .attr("class", "routertext2") 
     .attr("dx", -40) 
     .attr("dy", 30) 
     .text(function(d) { return d.inif }); 

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

    function redraw() { 
    vis.attr("transform", 
     "translate(" + d3.event.translate + ")" 
     + "scale(" + d3.event.scale + ")"); 
    }; 

</script> 

उत्तर

17

आप एक स्टैंडअलोन (सरल) उदाहरण में अलग से पाठ तत्वों बनाने के साथ प्रयोग किया है? यह आपको अलग-अलग गुणों को नियंत्रित करने की स्थिति के बारे में बेहतर महसूस कर सकता है। मूल (नीचे गठबंधन)

  • .35em के डीवाई खड़ी पाठ केन्द्रों पर

    • डिफ़ॉल्ट रूप से, पाठ के आधार रेखा है:

      लंबवत संरेखण के लिए, "डीवाई" विशेषता का उपयोग (शीर्ष गठबंधन)

    • .72em के डीवाई मूल पाठ की दिग्गज कंपनियां कीमतों स्थानों

    उन्हें इकाइयों का उपयोग करना अच्छा है, क्योंकि यह स्वचालित रूप से फ़ॉन्ट आकार के आधार पर पैमाने पर होगा। यदि आप इकाइयों को निर्दिष्ट नहीं करते हैं (जैसे आपके कोड में -20), तो यह पिक्सल पर डिफ़ॉल्ट होता है।

    क्षैतिज संरेखण के लिए, "पाठ लंगर" विशेषता का उपयोग करें:

    • डिफ़ॉल्ट "शुरू" (बाएं से दाएं भाषाओं के लिए बाईं ओर संरेखित) है
    • "मध्यम"
    • "अंत"

    "डीएक्स" विशेषता भी है, जो पैडिंग के लिए उपयोग करने के लिए मोहक है। हालांकि, मैं इसकी अनुशंसा नहीं करता क्योंकि फ़ायरफ़ॉक्स और ओपेरा में एक बग है जो टेक्स्ट-एंकर मध्य या अंत के संयोजन के साथ अपेक्षित काम नहीं करती है। पंक्ति के बाद कोड को

    .attr("text-anchor", "middle") 
    

    :

  • -1

    बस इस पंक्ति जोड़ें

    node.append("svg:text") 
    .attr("text-anchor", "middle") 
    ...... 
    
    +1

    इस के साथ इस लिंक पर बांधता है एक नोड के भीतर पाठ केंद्रित हो जाएगा, लेकिन मेरा मानना ​​है कि प्रश्न एक लिंक पर पाठ केंद्रित करने के लिए पूछ रहा है। – dchang

    5

    मैं एक के रूप में एक मेहराब उपयोग कर रहा हूँ:

    node.append("svg:text") 
    

    यह इस तरह दिखना चाहिए बीच में रखे लेबल लेबल वाले नोड्स के बीच लिंक करें। कोड स्निपेट है:

    var vis = d3.select("body") 
        .append("svg") 
        .attr("width", 600) 
        .attr("height", 400) 
        .append("g"); 
    
        var force = d3.layout.force() 
        .gravity(.05) 
        .distance(120) 
        .charge(-100) 
        .size([600, 400]); 
        var nodes = force.nodes(), links = force.links(); 
    
        // make an arch between nodes and a text label in the middle 
        var link = vis.selectAll("path.link").data(links, function(d) { 
         return d.source.node_id + "-" + d.target.node_id; }); 
        link.enter().append("path").attr("class", "link"); 
    
        var linktext = vis.selectAll("g.linklabelholder").data(links); 
        linktext.enter().append("g").attr("class", "linklabelholder") 
        .append("text") 
        .attr("class", "linklabel") 
        .attr("dx", 1) 
        .attr("dy", ".35em") 
        .attr("text-anchor", "middle") 
        .text(function(d) { return "my label" }); 
    
        // add your code for nodes .... 
    
        force.on("tick", tick); force.start(); 
    
        function tick() { 
        // curve 
        link.attr("d", function(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; 
        });  
        // link label 
        linktext.attr("transform", function(d) { 
         return "translate(" + (d.source.x + d.target.x)/2 + "," 
         + (d.source.y + d.target.y)/2 + ")"; }); 
        // nodes 
        node.attr("transform", function(d) { 
         return "translate(" + d.x + "," + d.y + ")"; }); 
        } 
    
    18

    enter image description here

    देखने के लिए कैसे एसवीजी सामान काम करता है डी 3 के बाहर एक छोटे उदाहरण का प्रयोग करें। फिर डी 3 और अपने कस्टम डेटा का उपयोग करके इस संरचना को पुनर्निर्माण करें।

    <html> 
        <body> 
    
    <svg width="600px" height="400px"> 
    
        <defs> 
         <!-- DEFINE AN ARROW THAT WE CAN PLACE AT THE END OF EDGES. --> 
         <!-- USE REFX TO MOVE THE ARROW'S TIP TO THE END OF THE PATH. --> 
         <marker 
          orient="auto" 
          markerHeight="12" 
          markerWidth="12" 
          refY="0" 
          refX="9" 
          viewBox="0 -5 10 10" 
          id="ARROW_ID" 
          style="fill: red; fill-opacity: 0.5;"> 
    
          <path d="M0, -5L10, 0L0, 5"></path> 
    
         </marker> 
        </defs> 
    
        <!-- DEFINE A PATH. SET ITS END MARKER TO THE ARROW'S ID. --> 
        <!-- SET FILL NONE TO DRAW A LINE INSTEAD OF A SHAPE. --> 
        <path 
         d="M100,100 A300,250 0 0,1 500,300" 
         style="fill:none; stroke:grey; stroke-width:2px;" 
         id="PATH_ID" 
         marker-end="url(#ARROW_ID)" /> 
    
        <!-- DEFINE A TEXT ELEMENT AND SET FONT PROPERTIES. --> 
        <!-- USE DY TO MOVE TEXT ABOVE THE PATH. --> 
        <text 
         style="text-anchor:middle; font: 16px sans-serif;" 
         dy="-12"> 
    
         <!-- DEFINE A TEXT PATH FOLLOWING THE PATH DEFINED ABOVE. --> 
         <!-- USE STARTOFFSET TO CENTER TEXT. --> 
         <textPath 
          xlink:href="#PATH_ID" 
          startOffset="50%">Centered edge label</textPath> 
        </text> 
    
    </svg> 
    
        </body> 
    </html> 
    
    +0

    'टेक्स्टपाथ' के साथ, एसवीजी केस-संवेदी (कम से कम क्रोम में) है, इसलिए विशेषता को 'स्टार्टऑफसेट' पढ़ना चाहिए। –

    +1

    इंगित करने के लिए धन्यवाद, मैंने अपना जवाब अपडेट किया। – Jack

    10

    डी 3 मजबूर लेआउट चार्ट में लिंक पर लेबल दिखाने के लिए निर्मित जे एस बेला उदाहरण

    जे एस फिडल में डेमो काम कर देखें: http://jsfiddle.net/bc4um7pc/

    की तरह ईद के दो अपने पथ पर

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

    उपरोक्त लिंक के साथ लेबल को जोड़ने के लिए एसवीजी टेक्स्टपाथ तत्व का उपयोग करके इसे निर्दिष्ट करके 'xlink: href' विशेषता अपने संबंधित लिंक/पथ को इंगित करने के लिए।

    var linktext = svg.append("svg:g").selectAll("g.linklabelholder").data(force.links()); 
        linktext.enter().append("g").attr("class", "linklabelholder") 
        .append("text") 
        .attr("class", "linklabel") 
        .style("font-size", "13px") 
        .attr("x", "50") 
        .attr("y", "-20") 
        .attr("text-anchor", "start") 
        .style("fill","#000") 
        .append("textPath") 
        .attr("xlink:href",function(d,i) { return "#linkId_" + i;}) 
        .text(function(d) { 
         return "my text"; //Can be dynamic via d object 
        }); 
    
    संबंधित मुद्दे