2016-10-06 109 views
0

我覺得我在這裏效率低下。我正在嘗試從數組中創建一個圖例,看起來我寫的東西太多了。有人能告訴我它是否可以優化嗎?使用d3.js創建圖例

http://jsbin.com/foqesivice/edit?js,console,output

var data = [ 
    {name: "AnotherLong"}, 
    {name: "BigData"}, 
    {name: "What"}, 
    {name: "Something"}, 
    {name: "Smalls"} 
]; 

var margin = {top: 10, right: 10, bottom: 10, left: 10}; 

var color = d3.scale.category20c(); 

var svg = d3.select("body").append("svg") 
    .attr("width", 400 - margin.left - margin.right) 
    .attr("height", 1000 - margin.top - margin.bottom) 

var g = svg.selectAll(".row") 
    .data(data) 
    .enter().append("svg:g") 

var rectangles = g.selectAll(".cell") 
    .data(data) 
    .enter().append("svg:rect") 
    .attr("width", 19) 
    .attr("height", 19) 
    .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }) 
    .style("fill", function(d, i){return color(i);}) 

var text = g.selectAll(".text") 
    .data(data) 
    .enter().append("svg:text") 
    .attr("x", 24) 
    .attr("y", 9) 
    .attr("dy", ".35em") 
    .attr("transform", function(d, i) { return "translate(0," + i * 20 + ")"; }) 
    .text(function(d){return d.name;}) 

編輯:

困擾我的另一件事。看起來我的造型由於某種原因而全部都是大膽的。我還沒有定義任何樣式。那是默認行爲嗎?

回答

1

@ MatthewWilcoxson的回答是不錯的,但這裏有一個更具體的d3重寫。從本質上講,沒有雙重綁定數據,保持g,綁定就可以了,即定位並添加recttext它:

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script data-require="[email protected]" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script> 
 
</head> 
 

 
<body> 
 
    <script> 
 
    var data = [{ 
 
     name: "AnotherLong" 
 
    }, { 
 
     name: "BigData" 
 
    }, { 
 
     name: "What" 
 
    }, { 
 
     name: "Something" 
 
    }, { 
 
     name: "Smalls" 
 
    }]; 
 

 
    var margin = { 
 
     top: 10, 
 
     right: 10, 
 
     bottom: 10, 
 
     left: 10 
 
    }; 
 

 
    var color = d3.scale.category20c(), 
 
     cellDim = 19; 
 

 
    var svg = d3.select("body").append("svg") 
 
     .attr("width", 400 - margin.left - margin.right) 
 
     .attr("height", 1000 - margin.top - margin.bottom); 
 

 
    var g = svg.selectAll(".row") 
 
     .data(data) 
 
     .enter().append("svg:g") 
 
     .attr("transform", function(d, i) { 
 
     return "translate(" + (0) + "," + ((cellDim + 1) * i) + ")" 
 
     }); 
 

 
    g.append("svg:rect") 
 
     .attr("width", cellDim) 
 
     .attr("height", cellDim) 
 
     .style("fill", function(d, i) { 
 
     return color(i); 
 
     }); 
 

 
    g.append("text") 
 
     .attr("dy", "1em") 
 
     .attr("dx", cellDim + 2) 
 
     .text(function(d) { 
 
     return d.name; 
 
     }); 
 
     
 
    </script> 
 
</body> 
 

 
</html>

+0

是的,你的回答對我來說似乎更好,看起來更像我一直在用d3工作的東西。謝謝! – konrad

2

首先,將所有的測量值,並在文件的頂部,並引用它們(這只是使事情變得更加可讀)

var legend_row_height = 50; 

你並不需要創建g元素。正義立場的矩形和文本與x,y屬性,而不是翻譯:

.attr("y", function(d,i){return legend_row_height * i;}) 

移動你的造型到CSS。這是最容易在對象上設置類實現:

.classed("squares", 1) 

然後加入CSS:

.squares { 
    stroke: white; 
} 
+0

事實上,先生,你是對所有賬戶。我擺脫了'g'的創作,並根據你的建議使用了'attr(「y」)''。另外,刪除'g'塊似乎已經修復了「大膽」的效果。 – konrad