2013-04-22 31 views
6

Tôi đang sử dụng d3.js để tạo biểu đồ bánh rán có nhãn ở bên ngoài. Sử dụng một lượng giác dựa trên trọng tâm của mỗi lát bánh, tôi định vị các nhãn.d3js Phân phối lại nhãn xung quanh biểu đồ hình tròn

g.append("g") 
     .attr("class", "percentage") 
     .append("text") 
      .attr("transform", function(d) 
       { 
        var c = arc.centroid(d); 
        var x = c[0]; 
        var y = c[1]; 
        var h = Math.sqrt(x*x + y*y); 
        return "translate(" + (x/h * obj.labelRadius) + ',' + (y/h * obj.labelRadius) + ")"; 
       } 
      ) 
      .attr("dy", ".4em") 
      .attr("text-anchor", function(d) 
       { 
        return (d.endAngle + d.startAngle)/2 > Math.PI ? "end" : "start"; 
       } 
      ) 
      .text(function(d) { return d.data.percentage+"%"; }); 

Điều cuối cùng tôi đang cố gắng hoàn thành là sắp xếp lại các nhãn nằm ngoài các cạnh của biểu đồ hình tròn, để ngăn trùng lặp.

enter image description here

Một trong những cách tôi đã cố gắng để giải quyết vấn đề là xác định thiết lập "điểm neo", trong đó nhãn có thể được bố trí, đảm bảo rằng họ sẽ không có sự chồng chéo. Vấn đề là lập bản đồ các centroids đến các neo và bảo quản một số cảm giác tương ứng trực quan giữa các lát và các nhãn (Đặc biệt khó khăn khi lát mỏng).

enter image description here

Hình ảnh trên cho thấy vị trí có thể của neo (centroids của lát hiển thị). Với những vị trí này, không thể có sự chồng chéo. Thêm sự phức tạp cho vấn đề là khi nhãn (chúng nằm ngang) gần đầu hoặc cuối của bánh, chúng dễ bị chồng chéo hơn, khi chúng ở bên phải hoặc bên trái của chiếc bánh .

Bất kỳ ý tưởng nào về cách tiếp cận vấn đề này?

[EDIT] Sau đề nghị của meetamit, tôi thực hiện như sau:

.attr("dy", function(d) 
{ 
    var c = arc.centroid(d); 
     var x = c[0]; 
     var y = c[1]; 
     var h = Math.sqrt(x*x + y*y); 
     var dy = y/h * obj.labelRadius; 
    dy=dy*fontSizeParam*.14/heightParam); 
    return (dy)+"em"; 
}) 

Nó giúp một chút, và đưa ra một số phòng để các nhãn, vẫn đang tìm kiếm một giải pháp mà sẽ bao gồm tất cả các trường hợp mặc dù. ..

+0

Bạn có thể đưa ra một ví dụ về những gì bạn có cho đến nay trên jsfiddle không? – Jonah

+0

Tôi đã thêm hình ảnh cho rõ ràng. Tôi đã không thực hiện trong mã giải pháp "neo", như tôi đã làm việc trên giấy các trường hợp khác nhau, nơi nó có thể thất bại. – Cenobyte321

+0

Tôi hiểu. Thật vậy, bạn có một vấn đề khó khăn, và một trong đó thực sự có rất ít để làm với d3 mỗi se: bạn đang tìm kiếm một thuật toán chung cho việc sắp xếp các nhãn trên biểu đồ của bạn. Bạn có thể đưa ra bất kỳ giả định nào không? Ví dụ, nếu tất cả các phần đều nhỏ như màu xanh lá cây và màu vàng, sẽ không có cách nào tốt để phù hợp với tất cả các nhãn trong? Điều gì về việc hiển thị nhãn chỉ khi di chuột cho các phần dưới một kích thước nhất định? – Jonah

Trả lời

0

Bạn không thể tạo hai vòng cung? một cho biểu đồ, và một cho các nhãn?

// first arc used for drawing the pie chart 
var arc = d3.svg.arc() 
    .outerRadius(radius - 10) 
    .innerRadius(0); 

// label attached to first arc 
g.append("text") 
    .attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; }) 
    .attr("dy", ".35em") 
    .style("text-anchor", "middle") 
    .text(function(d) { return d.data.age; }); 

// second arc for labels 
var arc2 = d3.svg.arc() 
    .outerRadius(radius + 20) 
    .innerRadius(radius + 20); 

// label attached to second arc 
g.append("text") 
    .attr("transform", function(d) { return "translate(" + arc2.centroid(d) + ")"; }) 
    .attr("dy", ".35em") 
    .style("text-anchor", "middle") 
    .text(function(d) { return d.data.age; }); 
1

Có một tốt, thực dụng d3.js giải pháp dựa trên bằng cách lập trình John Williams trình bày ở đây:

https://www.safaribooksonline.com/blog/2014/03/11/solving-d3-label-placement-constraint-relaxing/

Nó sẽ làm việc tốt cho trường hợp với những hạn chế hợp lý, ví dụ tối đa 12 nhãn như đã thảo luận ở trên. Ngoài ra còn có các con trỏ trong bài viết cho các thuật toán nâng cao hơn, nhưng cách tiếp cận đơn giản này có thể thực sự, khi được sử dụng với đủ ràng buộc nội dung nhãn, cho kết quả có ngoại hình trực quan hơn các phương pháp khác.

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