2012-02-09 30 views
7

tôi thêm các nút để một đồ thị bố trí lực lượng như thế này:Làm cách nào để thêm nút phức hợp trong bố cục lực D3?

var node = vis.selectAll("circle.node") 
    .data(nodes) 
    .enter() 
    .append("circle") 
    .attr("class", "node") 
    .attr("cx", function(d) { return d.x; }) 
    .attr("cy", function(d) { return d.y; }) 
    .attr("r", 5) 
    .style("fill", function(d) { return fill(d.group); }) 
    .call(force.drag); 

Có cách nào để thêm các yếu tố SVG hợp chất như các nút? I E. Tôi muốn thêm một siêu liên kết cho mỗi vòng tròn, vì vậy tôi sẽ cần một cái gì đó như thế này:

<a href="whatever.com"><circle ...></circle></a>

Trả lời

32

Tạo một yếu tố "chất" cũng đơn giản như phụ thêm một hoặc nhiều trẻ em đến yếu tố khác. Trong ví dụ của bạn, bạn muốn liên kết dữ liệu của mình với lựa chọn các thành phần <a> và cung cấp cho mỗi số <a> một đơn <circle> con.

Trước hết, bạn cần chọn "a.node" thay vì "circle.node". Điều này là do các siêu liên kết của bạn sẽ là các phần tử cha. Nếu không có phần tử cha mẹ rõ ràng và bạn chỉ muốn thêm nhiều phần tử cho từng mốc dữ liệu, hãy sử dụng <g>, phần tử nhóm của SVG.

Sau đó, bạn muốn nối thêm một phần tử <a> vào mỗi nút trong lựa chọn nhập. Điều này tạo ra các siêu liên kết của bạn. Sau khi đặt từng thuộc tính của siêu liên kết, bạn muốn cung cấp cho nó một con số <circle>. Đơn giản: chỉ cần gọi .append("circle").

var node = vis.selectAll("a.node") 
    .data(nodes); 

// The entering selection: create the new <a> elements here. 
// These elements are automatically part of the update selection in "node". 
var nodeEnter = node.enter().append("a") 
    .attr("class", "node") 
    .attr("xlink:href", "http://whatever.com") 
    .call(force.drag); 

// Appends a new <circle> element to each element in nodeEnter. 
nodeEnter.append("circle") 
    .attr("r", 5) 
    .style("fill", function(d) { return fill(d.group); }) 

node.attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); 

Hãy nhớ rằng D3 chủ yếu hoạt động trên lựa chọn các nút. Vì vậy, hãy gọi số .append() khi nhập lựa chọn có nghĩa là mỗi nút trong lựa chọn sẽ nhận được một con mới. Công cụ mạnh mẽ!

Một điều nữa: SVG có its own <a> element, đó là những gì tôi đã đề cập ở trên. Điều này khác với HTML! Thông thường, bạn chỉ sử dụng các phần tử SVG với SVG và HTML với HTML.

Nhờ @mbostock cho thấy tôi làm rõ đặt tên biến.

+0

Mặc dù tôi hiểu tại sao điều này lại hiệu quả đối với sáng tạo, nhưng nó có vi phạm khi cập nhật không? Vì append() hợp nhất các lựa chọn nhập và cập nhật, nó sẽ không thêm một vòng tròn mới vào các nút cũ mỗi lần cập nhật được gọi? –

+0

Tôi đã cập nhật ví dụ để làm cho nó rõ ràng hơn. selection.append không * hợp nhất * bất kỳ lựa chọn nào, nhưng selection.enter(). append tự động thêm các phần tử vào lựa chọn cập nhật. Ví dụ ban đầu của tôi có vis.selectAll (…) .data (…) .enter(). Append (…). Điều này chỉ phụ thêm các phần tử vào lựa chọn nhập, do đó, không có vấn đề ở đó; điểm mấu chốt là lựa chọn nhập ban đầu chỉ chứa phần giữ chỗ cho các phần tử * mới * chưa tồn tại. –

10

Trả lời Jason Davies (vì luồng ngăn xếp giới hạn thời lượng nhận xét trả lời…): Câu trả lời xuất sắc. Hãy cẩn thận với phương pháp chuỗi mặc dù; thông thường bạn muốn node để tham chiếu đến phần tử neo bên ngoài thay vì phần tử vòng tròn bên trong. Vì vậy, tôi muốn đề xuất một biến thể nhỏ:

var node = vis.selectAll("a.node") 
    .data(nodes) 
    .enter().append("a") 
    .attr("class", "node") 
    .attr("xlink:href", "http://whatever.com") 
    .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }) 
    .call(force.drag); 

node.append("circle") 
    .attr("r", 5) 
    .style("fill", function(d) { return fill(d.group); }); 

Tôi cũng đã thay thế các thuộc tính cx và cy của vòng tròn bằng biến đổi trên phần tử neo chứa; một trong hai sẽ hoạt động. Bạn có thể xử lý svg: một phần tử như svg: g (cả hai đều là các thùng chứa), điều này rất hay nếu bạn muốn thêm nhãn sau này.

+0

Cảm ơn! Tôi đã sửa đổi ví dụ đầu tiên một chút (loại bỏ 'var node =' vì nó dư thừa và có khả năng gây nhầm lẫn khi bạn chỉ ra).Ví dụ thứ hai với các biến phù hợp với biến của bạn, mặc dù tôi đồng ý rằng biến đổi có thể hữu ích hơn. –

Các vấn đề liên quan