2013-08-29 24 views
8

Kuvvet yönelimli bir grafik hazırladım ve "entity":"company" içeren veri için düğüm şeklinin şeklini değiştirmek istedim, böylece dikdörtgen şekline sahip olacaklardı, ve bu veri bölümü olmayan diğeri şu an olduğu gibi daireler olacaktı. Böyle düğümüne ben kod kısmında if else ifadesiyle dikdörtgenler eklemeye çalıştık http://jsfiddle.net/dzorz/uWtSk/D3 kuvvet yönelimli grafik, verilere ve verilere göre farklı şekil veriliyor mu?

Ben şekil ekleme:

Buradaki tek daire düğümlerle benim çalışma örnek görebilirsiniz

function(d) 
    { 
     if (d.entity == "company") 
     { 
      node.append("rect") 
       .attr("class", function(d){ return "node type"+d.type}) 
       .attr("width", 100) 
       .attr("height", 50) 
       .call(force.drag); 
     } 
     else 
     { 
     node.append("circle") 
      .attr("class", function(d){ return "node type"+d.type}) 
      .attr("r", function(d) { return radius(d.value) || 10 }) 
      //.style("fill", function(d) { return fill(d.type); }) 
      .call(force.drag); 
     } 
    } 

Ama sonra herhangi bir düğümde hiç bir şekil almadım.

Bunun için uygun bir yol nedir?

bütün kod şuna benzer: komut dosyası:

var data = {"nodes":[ 
         {"name":"Action 4", "type":5, "slug": "", "value":265000}, 
         {"name":"Action 5", "type":6, "slug": "", "value":23000}, 
         {"name":"Action 3", "type":4, "slug": "", "value":115000}, 
         {"name":"Yahoo", "type":1, "slug": "www.yahoo.com", "entity":"company"}, 
         {"name":"Google", "type":1, "slug": "www.google.com", "entity":"company"}, 
         {"name":"Action 1", "type":2, "slug": "",}, 
         {"name":"Action 2", "type":3, "slug": "",}, 
         {"name":"Bing", "type":1, "slug": "www.bing.com", "entity":"company"}, 
         {"name":"Yandex", "type":1, "slug": "www.yandex.com)", "entity":"company"} 
        ], 
      "links":[ 
         {"source":0,"target":3,"value":10}, 
         {"source":4,"target":3,"value":1}, 
         {"source":1,"target":7,"value":10}, 
         {"source":2,"target":4,"value":10}, 
         {"source":4,"target":7,"value":1}, 
         {"source":4,"target":5,"value":10}, 
         {"source":4,"target":6,"value":10}, 
         {"source":8,"target":4,"value":1} 
         ] 
       }  



    var w = 560, 
     h = 500, 
     radius = d3.scale.log().domain([0, 312000]).range(["10", "50"]); 

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

     vis.append("defs").append("marker") 
     .attr("id", "arrowhead") 
     .attr("refX", 17 + 3) /*must be smarter way to calculate shift*/ 
     .attr("refY", 2) 
     .attr("markerWidth", 6) 
     .attr("markerHeight", 4) 
     .attr("orient", "auto") 
     .append("path") 
      .attr("d", "M 0,0 V 4 L6,2 Z"); //this is actual shape for arrowhead 

    //d3.json(data, function(json) { 
     var force = self.force = d3.layout.force() 
      .nodes(data.nodes) 
      .links(data.links) 
      .distance(100) 
      .charge(-1000) 
      .size([w, h]) 
      .start(); 



     var link = vis.selectAll("line.link") 
      .data(data.links) 
      .enter().append("svg:line") 
      .attr("class", function (d) { return "link" + d.value +""; }) 
      .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; }) 
      .attr("marker-end", function(d) { 
               if (d.value == 1) {return "url(#arrowhead)"} 
               else { return " " } 
              ;}); 


     function openLink() { 
     return function(d) { 
      var url = ""; 
      if(d.slug != "") { 
       url = d.slug 
      } //else if(d.type == 2) { 
       //url = "clients/" + d.slug 
      //} else if(d.type == 3) { 
       //url = "agencies/" + d.slug 
      //} 
      window.open("//"+url) 
     } 
    } 




     var node = vis.selectAll("g.node") 
      .data(data.nodes) 
      .enter().append("svg:g") 
      .attr("class", "node") 
      .call(force.drag); 

     node.append("circle") 
      .attr("class", function(d){ return "node type"+d.type}) 
      .attr("r", function(d) { return radius(d.value) || 10 }) 
      //.style("fill", function(d) { return fill(d.type); }) 
      .call(force.drag); 

     node.append("svg:image") 
      .attr("class", "circle") 
      .attr("xlink:href", function(d){ return d.img_href}) 
      .attr("x", "-16px") 
      .attr("y", "-16px") 
      .attr("width", "32px") 
      .attr("height", "32px") 
      .on("click", openLink()); 

     node.append("svg:text") 
      .attr("class", "nodetext") 
      .attr("dx", 0) 
      .attr("dy", ".35em") 
      .attr("text-anchor", "middle") 
      .text(function(d) { return d.name }); 

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

css:

.link10 { stroke: #ccc; stroke-width: 3px; stroke-dasharray: 3, 3; } 
.link1 { stroke: #000; stroke-width: 3px;} 
.nodetext { pointer-events: none; font: 10px sans-serif; } 

.node.type1 { 
    fill:brown; 
} 
.node.type2 { 
    fill:#337147; 
} 
.node.type3 { 
    fill:blue; 
} 
.node.type4 { 
    fill:red; 
} 

.node.type5 { 
    fill:#1BC9E0; 
} 

.node.type6 { 
    fill:#E01B98; 
} 

image.circle { 
    cursor:pointer; 
} 

Sen benim jsfiddle yazının başında üzerinde bağlantılı Düzenleyebileceğiniz ...

+0

Jsfiddle'unuzdaki şekilleri değiştirmek için kodu kullanıyor gibi görünmüyorsunuz. Sorunu gösteren bir mesaj gönderebilir misiniz lütfen? –

+0

Yukarıdaki özel durum ifadesi ile sorunlu kodu gönderdim (kodun ilk bloğuna bakın) ... jsfiddle Bu ifadeyi sildim, böylece sadece daire şekillerini görebilirsiniz – dzordz

+0

Gerçekten bu kodu koydunuz önemli ve nasıl diyorsun? –

cevap

6

Çözüm burada ... Ben var sorunu çözmek için bana yardımcı belki benim çözüm bakmak ve: http://jsfiddle.net/Bull/4btFx/1/

Bunu çalışmak lazım Her düğüme bir sınıf ekleyerek, şekiller eklemek için her sınıf için "selectAll" öğesini kullanın. Aşağıdaki kodda, "node" ve "rect" veya "ellipse" olan JSON (d.type) tarafından döndürülen bir sınıf ekliyorum.

var node = container.append("g") 
    .attr("class", "nodes") 
    .selectAll(".node") 
    .data(graph.nodes) 
    .enter().append("g") 
    .attr("class", function(d) { 
    return d.type + " node"; 
    }) 
    .call(drag); 

Sonra her sınıfın tüm elemanları şekil ekleyebilirsiniz:

d3.selectAll(".rect").append("rect") 
    .attr("width", window.nodeWidth) 
    .attr("height", window.nodeHeight) 
    .attr("class", function(d) { 
    return "color_" + d.class 
    }); 

    d3.selectAll(".ellipse").append("rect") 
    .attr("rx", window.nodeWidth*0.5) 
    .attr("ry", window.nodeHeight*0.5) 
    .attr("width", window.nodeWidth) 
    .attr("height", window.nodeHeight) 
    .attr("class", function(d) { 
    return "color_" + d.class 
    }); 

Yukarıdaki örnekte, ben onlara aynı şekilde merkezleri beri üç nokta çizmek için yarıçapı dikdörtgenler kullanılan dikdörtgenler. Ama başka şekillerde de çalışır. Bağladığım jsfiddle'da, merkezleme kapalı, ancak şekiller doğru.

0

Bu davranışı, Filtering in d3.js on bl.ocks.org'dan düzelttiğim filter yöntemini kullanarak uyguladım. Benim kod nispeten büyük ve refactored çünkü

initGraphNodeShapes() { 
    let t = this; 

    let graphNodeCircles = 
    t.graphNodesEnter 
     .filter(d => d.shape === "circle") 
     .append("circle") 
     .attr("r", 15) 
     .attr("fill", "green"); 

    let graphNodeRects = 
    t.graphNodesEnter 
     .filter(d => d.shape === "rect") 
     .append("rect") 
     .attr("width", 20) 
     .attr("height", 10) 
     .attr("x", -10) // -1/2 * width 
     .attr("y", -5) // -1/2 * height 
     .attr("fill", "blue"); 

    return graphNodeCircles.merge(graphNodeRects); 
} 

Ben initGraphNodeShapes aramanın bu içini var. t.graphNodesEnter, veri başka bir yerde arama enter() çağrı katıldıktan sonra veri seçimine bir referanstır. Daha fazla içeriğe ihtiyacınız varsa pes edin. Ayrıca, d => ... sürümünü kullanıyorum çünkü lambdaları etkinleştiren ES6 kullanıyorum. ES6 öncesi kullanıyorsanız, bunu function(d)... formuna değiştirmeniz gerekir.

İlgili konular