Как разместить фигуры svg в круге?

Я немного играю с D3.у нас с Джей-Эс почти все работает. Но я хочу поместить свои svg-фигуры в круг. Поэтому я покажу разницу в данных с цветом и текстом. Я знаю, как рисовать круги и круговые диаграммы, но я хочу иметь круг одинакового размера. И чтобы они не перекрывались, порядок не имеет значения. Я не знаю, с чего начать, чтобы узнать x & y для каждого круга.

2 ответов


вот еще один подход к этому, для форм произвольного размера, используя D3 tree макет:http://jsfiddle.net/nrabinowitz/5CfGG/

на tree макет (docs, пример) выяснит размещение x,y каждого элемента для вас, на основе заданного радиуса и функции, возвращающей разделение между центрами любых двух элементов. В этом примере я использовал круги разных размеров, поэтому разделение между ними является функцией их радиусы:

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

использование D3 tree макет решает первую проблему, выкладывая элементы по кругу. Вторая проблема, как отмечает @Markus, заключается в том, как вычислить правильный радиус для круга. Я взял немного грубый подход здесь, ради целесообразности: я оцениваю окружность круга как сумму диаметров различных элементов с заданной прокладкой между ними, а затем вычисляю радиус от окружности:

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

в окружность здесь не точная, и это будет все менее и менее точным, чем меньше элементов у вас есть в круге, но это достаточно близко для этой цели.


если я правильно вас понимаю, это довольно стандартный математический вопрос:

просто петля над некоторыми угол переменная в соответствующем размере шага и использовать sin() и cos() для вычисления значений x и y.

например:

предположим, вы пытаетесь разместить 3 объекта. Есть 360 градусов по кругу. Таким образом, каждый объект находится на расстоянии 120 градусов от следующего. Если ваши объекты имеют размер 20x20 пикселей, поместите их на следующие места:

 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

здесь r - это радиус круга и (xc, yc) являются координатами центральной точки круга. The -10's убедитесь, что объекты имеют свой центр (а не верхний левый угол) на круг. The * pi()/180 преобразует градусы в радианы, что является единицей большинства реализаций sin() и cos() требуют.

Примечание: это помещает фигуры равномерно распределены по кругу. Чтобы убедиться, что они не перекрытие, вы должны выбрать свой r достаточно большой. Если объекты имеют простые и идентичные границы, просто выложите 10 из них и вычислите радиус, который вам нужен, а затем, если вам нужно разместить 20, сделайте радиус в два раза больше, для 30 в три раза больше и так далее. Если объекты имеют неправильную форму, и вы хотите разместить их в оптимальном порядке по кругу, чтобы найти наименьший возможный круг, эта проблема будет чрезвычайно запутанной. Может быть, для этого есть библиотека, но я не знаю. у меня есть один в верхней части головы, и так как я не использовал D3.js, я не уверен, предоставит ли он вам эту функциональность.