2012-12-02 49 views
7

Tôi đang chơi một chút với D3.js và tôi có hầu hết mọi thứ hoạt động. Nhưng tôi muốn đặt hình dạng svg của tôi trong một vòng tròn. Vì vậy, tôi sẽ hiển thị sự khác biệt về dữ liệu với màu sắc và văn bản. Tôi biết cách vẽ hình tròn và biểu đồ hình tròn, nhưng tôi muốn cơ bản có một vòng tròn có cùng kích thước. Và không có chúng chồng lên nhau, thứ tự không liên quan. Tôi không biết bắt đầu từ đâu, để tìm x & y cho mỗi vòng kết nối.Làm thế nào để đặt hình dạng svg trong một vòng tròn?

Trả lời

6

Dưới đây là cách tiếp cận khác để này, đối với hình dạng kích thước tùy ý, sử dụng tree bố trí D3 của: http://jsfiddle.net/nrabinowitz/5CfGG/

Cách bố trí tree (docs, example) sẽ tìm ra x, y vị trí của từng hạng mục cho bạn, dựa trên một bán kính nhất định và một hàm trả về sự tách biệt giữa các trung tâm của bất kỳ hai mục nào. Trong ví dụ này, tôi sử dụng hình tròn kích thước khác nhau, vì vậy sự tách biệt giữa chúng là một chức năng của bán kính của họ:

var tree = d3.layout.tree() 
    .size([360, radius]) 
    .separation(function(a, b) { 
     return radiusScale(a.size) + radiusScale(b.size); 
    }); 

Sử dụng D3 tree bố trí giải quyết vấn đề đầu tiên, đặt ra các mục trong một vòng tròn. Vấn đề thứ hai, như ghi chú @Markus, là cách tính bán kính phù hợp cho vòng tròn. Tôi đã thực hiện một cách tiếp cận hơi thô lỗ ở đây, vì lợi ích của tính hiệu quả: Tôi ước tính chu vi của vòng tròn như tổng các đường kính của các vật phẩm khác nhau, với một khoảng đệm nhất định, sau đó tính bán kính từ chu vi:

var roughCircumference = d3.sum(data.map(radiusScale)) * 2 + 
     padding * (data.length - 1), 
    radius = roughCircumference/(Math.PI * 2); 

Chu vi ở đây không chính xác, và điều này sẽ ít chính xác hơn và ít hơn các mục bạn có trong vòng kết nối, nhưng nó đủ gần cho mục đích này.

+0

Đây là phần còn thiếu, cảm ơn vì điều đó. – user1870877

9

Nếu tôi hiểu bạn một cách chính xác, đây là một câu hỏi toán khá chuẩn:

Đơn giản chỉ cần vòng qua một số góc biến trong kích thước bước thích hợp và sử dụng sin()cos() để tính x và giá trị y.

Ví dụ:

Giả sử bạn đang cố gắng đặt 3 đối tượng. Có một vòng tròn 360 độ. Vì vậy, mỗi đối tượng là 120 độ đi từ tiếp theo. Nếu đối tượng của bạn là pixel 20x20 về kích thước, đặt chúng tại các địa điểm sau:

x1 = sin( 0 * pi()/180) * r + xc - 10; y1 = cos( 0 * pi()/180) * r + yc - 10 
x2 = sin(120 * pi()/180) * r + xc - 10; y2 = cos(120 * pi()/180) * r + yc - 10 
x3 = sin(240 * pi()/180) * r + xc - 10; y3 = cos(240 * pi()/180) * r + yc - 10 

Ở đây, r là bán kính của vòng tròn và (xc, yc) là tọa độ của điểm trung tâm của vòng tròn. Các -10's đảm bảo rằng các đối tượng có trung tâm của họ (chứ không phải là góc trên bên trái của họ) trên vòng tròn. Các * pi()/180 chuyển đổi độ để radian, đó là đơn vị triển khai nhất của sin()cos() yêu cầu.

Lưu ý: Điều này đặt các hình dạng được phân bố đều xung quanh vòng tròn. Để đảm bảo chúng không trùng lặp, bạn phải chọn r đủ lớn. Nếu các đối tượng có ranh giới đơn giản và giống hệt nhau, chỉ cần đặt ra 10 trong số chúng và tìm ra bán kính bạn cần và sau đó, nếu bạn cần đặt 20, làm cho bán kính gấp đôi lớn, cho 30 ba lần lớn và vv. Nếu các đối tượng được định hình bất thường và bạn muốn đặt chúng theo thứ tự tối ưu xung quanh vòng tròn để tìm vòng tròn nhỏ nhất có thể, vấn đề này sẽ cực kỳ lộn xộn. Có thể có một thư viện cho điều này, nhưng tôi không có một trong đầu của tôi và kể từ khi tôi đã không sử dụng D3.js, tôi không chắc chắn liệu nó sẽ cung cấp cho bạn chức năng này hoặc.

+0

Cảm ơn thông tin khớp nền, tôi đang tìm kiếm giải pháp D3js cụ thể, nhưng điều này giúp hiểu. – user1870877

+0

Tôi đang tìm một giải pháp - điều này sẽ cho phép các chấm được đặt trong các hình dạng đường dẫn khác - như crescents cũng như các vòng tròn. http://stackoverflow.com/questions/22340334/d3-js-user-viewer-chart –

+0

đây là câu trả lời :) – mithunsatheesh

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