Как разместить фигуры 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, я не уверен, предоставит ли он вам эту функциональность.