2017-11-19 3 views
2

私の目的は、クラスタの色に基づいてClustered Bubble Chartに凡例を追加することです。私のやり方は結果がありません。d3のバブルチャートの凡例を作成するにはどうすればよいですか?伝説が表示されない

私のCSVファイルには、5つの異なる色でクラスタ化されています。実際、名前と色で各クラスターを区別したいと思います。

コードにはエラーはありませんが、何も表示されません。誰かがそれを見て、何が間違っているかを教えてもらえますか?バブルチャートに凡例を追加する他の提案はありますか?あなたは.legendの選択でそれに参加するとき

<!DOCTYPE html> 
<meta charset="utf-8"> 
<style type="text/css"> 
text { 
    font: 10px sans-serif; 
} 
circle { 
    stroke: #565352; 
    stroke-width: 1; 
} 
</style> 
<body> 
<script src="https://d3js.org/d3.v3.min.js"></script> 
<script> 

var width = 1000, 
    height = 1000, 
    padding = 1.5, // separation between same-color nodes 
    clusterPadding = 6, // separation between different-color nodes 
    maxRadius = 65; 

var color = d3.scale.ordinal() 
     .range(["#5499C7", "#8E44AD", "#138D75", "#F1C40F", "#D35400"]); 

d3.text("word_groups.csv", function(error, text) { 

    var legendRectSize = 18; 
    var legendSpacing = 4; 
    if (error) throw error; 
    var colNames = "text,size,group\n" + text; 
    var data = d3.csv.parse(colNames); 

    data.forEach(function(d) { 
    d.size = +d.size; 
    }); 

//unique cluster/group id's 
var cs = []; 
data.forEach(function(d){ 
     if(!cs.contains(d.group)) { 
      cs.push(d.group); 
     } 
}); 

var n = data.length, // total number of nodes 
    m = cs.length; // number of distinct clusters 

//create clusters and nodes 
var clusters = new Array(m); 
var nodes = []; 
for (var i = 0; i<n; i++){ 
    nodes.push(create_nodes(data,i)); 
} 

var force = d3.layout.force() 
    .nodes(nodes) 
    .size([width, height]) 
    .gravity(.02) 
    .charge(0) 
    .on("tick", tick) 
    .start(); 

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

var node = svg.selectAll("circle") 
    .data(nodes) 
    .enter().append("g").call(force.drag); 

var legend = svg.selectAll('.legend') 
    .data(color.domain()) 
    .enter() 
    .append('g') 
    .attr('class', 'legend') 
    .attr('transform', function(d, i) { 
    var height = legendRectSize + legendSpacing; 
    var offset = height * color.domain().length/2; 
    var horz = -2 * legendRectSize; 
    var vert = i * height - offset; 
     return 'translate(' + horz + ',' + vert + ')'; 
    }); 

    legend.append('rect') 
    .attr('width', legendRectSize) 
    .attr('height', legendRectSize) 
    .style('fill', color) 
    .style('stroke', color); 

    legend.append('text') 
    .attr('x', legendRectSize + legendSpacing) 
    .attr('y', legendRectSize - legendSpacing) 
    .text(function(d) { return "Hans"; }); 

node.append("circle") 
    .style("fill", function (d) { 
    return color(d.cluster); 
    }) 
    .attr("r", function(d){return d.radius}) 


node.append("text") 
     .attr("dy", ".3em") 
     .style("text-anchor", "middle") 
     .text(function(d) { return d.text.substring(0, d.radius/3); }); 

function create_nodes(data,node_counter) { 
    var i = cs.indexOf(data[node_counter].group), 
     r = Math.sqrt((i + 1)/m * -Math.log(Math.random())) * maxRadius, 
     d = { 
     cluster: i, 
     radius: data[node_counter].size*1.5, 
     text: data[node_counter].text, 
     x: Math.cos(i/m * 2 * Math.PI) * 200 + width/2 + Math.random(), 
     y: Math.sin(i/m * 2 * Math.PI) * 200 + height/2 + Math.random() 
     }; 
    if (!clusters[i] || (r > clusters[i].radius)) clusters[i] = d; 
    return d; 
}; 

function tick(e) { 
    node.each(cluster(10 * e.alpha * e.alpha)) 
     .each(collide(.5)) 
    .attr("transform", function (d) { 
     var k = "translate(" + d.x + "," + d.y + ")"; 
     return k; 
    }) 

} 
// Move d to be adjacent to the cluster node. 
function cluster(alpha) { 
    return function (d) { 
     var cluster = clusters[d.cluster]; 
     if (cluster === d) return; 
     var x = d.x - cluster.x, 
      y = d.y - cluster.y, 
      l = Math.sqrt(x * x + y * y), 
      r = d.radius + cluster.radius; 
     if (l != r) { 
      l = (l - r)/l * alpha; 
      d.x -= x *= l; 
      d.y -= y *= l; 
      cluster.x += x; 
      cluster.y += y; 
     } 
    }; 
} 
// Resolves collisions between d and all other circles. 
function collide(alpha) { 
    var quadtree = d3.geom.quadtree(nodes); 
    return function (d) { 
     var r = d.radius + maxRadius + Math.max(padding, clusterPadding), 
      nx1 = d.x - r, 
      nx2 = d.x + r, 
      ny1 = d.y - r, 
      ny2 = d.y + r; 
     quadtree.visit(function (quad, x1, y1, x2, y2) { 
      if (quad.point && (quad.point !== d)) { 
       var x = d.x - quad.point.x, 
        y = d.y - quad.point.y, 
        l = Math.sqrt(x * x + y * y), 
        r = d.radius + quad.point.radius + (d.cluster === quad.point.cluster ? padding : clusterPadding); 
       if (l < r) { 
        l = (l - r)/l * alpha; 
        d.x -= x *= l; 
        d.y -= y *= l; 
        quad.point.x += x; 
        quad.point.y += y; 
       } 
      } 
      return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1; 
     }); 
    }; 
} 
}); 

Array.prototype.contains = function(v) { 
    for(var i = 0; i < this.length; i++) { 
     if(this[i] === v) return true; 
    } 
    return false; 
}; 

</script> 
+0

word_groups.csvファイルに含まれる内容を詳しく説明できますか?問題を再現するためにjsfiddleを作りたかったので:https://jsfiddle.net/7eda9rt4/ –

+1

@ N.Schipper ここには[link](http://www.sharecsv.com/s/)があります。 11b17d52f1d7a7fc01ea93e4f9b724af/word_groups.csv) – Prstoo

答えて

2

color.domain配列は空なので、何の「G」の要素が追加されていません。

ノードの選択に円を追加すると、color.domain配列のコードの後半に値が設定されます。

ご注文を切り替える場合は、凡例項目が作成されます。

var node = svg 
    .selectAll('circle') 
    .data(nodes) 
    .enter() 
    .append('g') 
     .call(force.drag) 

////MOVED BEFORE THE LEGEND CODE 
node 
    .append('circle') 
    .style('fill', function (d) { 
    return color(d.cluster) 
    }) 
    .attr('r', function (d) { 
    return d.radius 
    }) 

var legend = svg 
    .selectAll('.legend') 
    .data(color.domain()) 
    .enter() 
    .append('g') 
    .attr('class', 'legend') 
    .attr('transform', function (d, i) { 
    var height = legendRectSize + legendSpacing 
    var offset = height * color.domain().length/2 
    var horz = -2 * legendRectSize 
    var vert = i * height - offset 
    return 'translate(' + horz + ',' + vert + ')' 
    }) 

legend 
    .append('rect') 
    .attr('width', legendRectSize) 
    .attr('height', legendRectSize) 
    .style('fill', color) 
    .style('stroke', color) 

legend 
    .append('text') 
    .attr('x', legendRectSize + legendSpacing) 
    .attr('y', legendRectSize - legendSpacing) 
    .text(function (d) { 
    return 'Hans' 
    }) 

PS:あなたのhorzvert変数を見て必要があるので、凡例項目のいくつかは、現在、SVGビューをオフに翻訳されていますが。

関連する問題