2016-03-08 43 views
0

我有一個強制定向圖,它抓取一些php生成的json並顯示它。在這裏可以看到:http://www.testbed.medievalgeek.com/test_forcedirect.php強制指令圖中的圖例

我想一個傳奇添加到圖表,並試圖通過這裏修改的例子的尾位這樣做的:How to add a dynamic legend to a D3 force directed graph in Apex?

我的總的JavaScript是在這裏:

function nearest(value, min, max, steps) { 
    var zerone = Math.round((value - min) * steps/(max - min))/steps; // bring to 0-1 range 
    return zerone * (max - min) + min; 
} 

var clientHeight = document.getElementById('dropdown').clientHeight; 

var width = window.innerWidth - 10, 
    height = window.innerHeight - clientHeight; 

var svg = d3.select("body").append("svg") 
    .attr("width", width) 
    .attr("height", height) 
    .style("background-color", "black"); 

var force = d3.layout.force() 
    .gravity(0.8) 
    .distance(100) 
    .size([width, height]); 

var index = -1; 

force.charge(function (d) {return d.weight * -250;}); 

d3.json(<?php echo "\"" . $url_string . "\""?>, function(error, json) { 
    if (error) throw error; 

    force 
     .nodes(json.nodes) 
     .links(json.links) 
     .start(); 

    var link = svg.selectAll(".link") 
    .data(json.links) 
    .enter().append("line") 
    .attr("class", "link") 
    .attr('stroke', function(d) {return d.color; }) 
    .attr('stroke-width', 1)  
    .on("mouseover", function(d) { 
     d3.select(this).attr('stroke-width', 2);  
    }) 
    .on("mouseout", function(d) { 
     d3.select(this).attr('stroke-width',1); 
    }); 

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

node.append("circle") 
    .attr("r", function (d) {return nearest((Math.log(d.weight) *10), 1, 50, 10) || 10;}) 
    .style('fill', function(d) { return d.color; }) 
    .on("mouseover", function(d) { 
     link.style('stroke-width', function(l) { 
     if (d === l.target || d === l.source) 
     return 2; 
     }) 
     link.style('stroke', function(l) { 
     if (d === l.target || d === l.source) 
     return 'aqua'; 
     }) 
     .duration(150);  
    }) 
    .on("mouseout", function(d) { 
    link.style('stroke-width', 1) 
    link.style('stroke', function(d) {return d.color; }) 
    .duration(150); 
    }); 


node.append("text") 
    .attr("dx", function(d) {return (nearest((Math.log(d.weight) *10), 1, 50, 10) + 5);}) 
    .attr("dy", ".35em") 
    .text(function(d) {return d.name}) 
    .style('fill', 'lightcyan'); 

var legend = svg.selectAll(".legend") 
.data(color.domain()) 
.enter().append("g") 
.attr("class", "legend") 
.attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }); 

legend.append("circle") 
.attr("r", 10) 
.style("fill", function(d) { return d.color; }); 

legend.append("text") 
.attr("dx", 10) 
.attr("dy", ".35em") 
.style("text-anchor", "end") 
.text(function(d) { return d.name; }); 
.style('fill', 'lightcyan'); 

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



    }); 
}); 

然而,這會導致一個空白屏幕。如果我試圖通過改變圖例文本更緊密地複製例如:

legend.append("text") 
    .attr("x", width - 24) 
    .attr("y", 9) 
    .attr("dy", ".35em") 
    .style("text-anchor", "end") 
    .text(function(d) { return d; }); 

節點出現,但他們不再根據重量分配自己,而不是僅僅出現在左上角。似乎也沒有傳說。

什麼是最好的方式奠定傳說,仍然有力量導向的方面工作?大部分例子似乎都不適用於我已有的東西。

回答

1

這實際上很簡單,我很蠢提問。但如果有人想知道,你所要做的就是繪製每個項目。以下代碼可能是某人開始的基礎。 d.type和d.color是分別從json傳入的代表項目的值和由圖表表示的顏色。

var listTypes = d3.set(json.nodes.map(function(d){return d.type})).values(); 

    listColors = []; 

    listPositions = []; 

    lineWidths = []; 

    for(l = 0; l < listTypes.length; l++){ 
     for (var key in json.nodes){ 
      if (listTypes[l] === json.nodes[key].type) { 
      if (listColors.indexOf(json.nodes[key].color) > -1) 
      {} 
      else 
       { 
       lineWidths.push(json.nodes[key].type.length); 
       listColors.push(json.nodes[key].color); 
       var xlegend = (Math.floor(l/10) * 100); 
       var ycounter; 
       var ylegend; 
       var oldxlegend; 

       if (l===0) { 
        ycounter = 1; 
       } 

       if (ycounter < 10) { 
        listPositions.push(ycounter * 20); 
        ycounter++; 
       } 
       else 
       { 
        listPositions.push(ycounter * 20); 
        ycounter = 1;      
       } 

       } 
      } 
      else {} 
     } 
     } 

    console.log(listTypes); 
    console.log(listColors); 
    console.log(listPositions); 

    svg.append("rect") 
    .attr("class", "overlay") 
    .attr("x",5) 
    .attr("y", 10) 
    .attr("width", Math.max.apply(Math,lineWidths) * 10.6) 
    .attr("height", listTypes.length * 21.667) 
    .style ("fill", "aliceblue") 

    var legend = svg.selectAll(".legend") 
      .data(listTypes) 
     .enter().append("g") 
      .attr("class", "legend") 
      .attr("transform", function(d, i) { return "translate(" + (Math.floor(i/10) * 105) + ", " + listPositions[i] + ")"; }) 

     legend.append("rect") 
      .attr("x", 10) 
      .attr("width", 15) 
      .attr("height", 15) 
      .attr("fill", function(d,i) {return listColors[i];}); 

     legend.append("text") 
      .attr("x", 30) 
      .attr("y", 6) 
      .attr("dy", ".35em") 
      .text(function(d,i){ return titleCase(listTypes[i].replace(/_/g, " "))}); 

      svg.append("g") 
     .attr("class", "legend")