аккорд d3: текст по центру

1

Я использую пример диаграммы аккордов d3 от Andrew и хочу сосредоточить все текстовые метки внутри изогнутого фрагмента. Я много пробовал, но никогда не мог сосредоточить тексты. Знаете ли вы, что такое уловка wizzard?

Изображение 174551

var width = 720,
height = 720,
outerRadius = Math.min(width, height) / 2 - 10,
innerRadius = outerRadius - 24;

var formatPercent = d3.format(".1%");

var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);

var layout = d3.layout.chord()
.padding(.04)
.sortSubgroups(d3.descending)
.sortChords(d3.ascending);

var path = d3.svg.chord()
.radius(innerRadius);

var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("id", "circle")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

svg.append("circle")
.attr("r", outerRadius);

d3.csv("ex_csv.csv", function(cities) {
d3.json("ex_json.json", function(matrix) {

// Compute the chord layout.
layout.matrix(matrix);

// Add a group per neighborhood.
var group = svg.selectAll(".group")
.data(layout.groups)
.enter().append("g")
.attr("class", "group")
.on("mouseover", mouseover);


// Add the group arc.
var groupPath = group.append("path")
.attr("id", function(d, i) { return "group" + i; })
.attr("d", arc)
.style("fill", function(d, i) { return cities[i].color; });

// Add a text label.
var groupText = group.append("text")
.attr("x", 6)
.attr("dy", 15);

groupText.append("textPath")
.attr("xlink:href", function(d, i) { return "#group" + i; })
.text(function(d, i) { return cities[i].name; });

// Remove the labels that don't fit. :(
groupText.filter(function(d, i) { return groupPath[0][i].getTotalLength() / 2 - 16 < this.getComputedTextLength(); })
.remove();

// Add the chords.
var chord = svg.selectAll(".chord")
.data(layout.chords)
.enter().append("path")
.attr("class", "chord")
.style("fill", function(d) { return cities[d.source.index].color; })
.attr("d", path);


}
});
});

</script>
Теги:
d3.js
chord-diagram

1 ответ

3
Лучший ответ

В стороне, я бы предложил посмотреть обновление до версии v4, документация для v2 почти не существует, и с ней очень сложно справиться.

Вы можете установить свойство text-anchor и startOffset для достижения того, что вы ищете.

Во-первых, вы хотите установить text-anchor к middle как легче указать среднюю точку, чем найти среднюю точку и вернуться назад, чтобы найти, где должен начинаться текст.

Во-вторых, вам нужно установить startOffset. Обратите внимание, что если вы используете 50%, текст не будет отображаться там, где вы хотите, поскольку общая длина пути текста - это все стороны замкнутого цикла (привязка аккорда), к которому вы добавляете. Установка его на 25% будет работать, если у вас не будет другого внешнего и внутреннего радиуса. Но, поскольку у вас есть внешний радиус, который на 24 пикселя больше внутреннего радиуса, вы можете попробовать что-то вроде этого, чтобы вычислить количество пикселей, необходимое для смещения центра текста:

groupText.append("textPath")
.attr("xlink:href", function(d, i) { return "#group" + i; })
.text(function(d, i) { return cities[i].name; })
.attr("startOffset",function(d,i) { return (groupPath[0][i].getTotalLength() - 48) / 4 })
.style("text-anchor","middle");

Я вычитаю 48, потому что стороны анкера равны 24 пикселям (разница в радиусах). Я деляю на четыре, потому что путь удваивается. Если бы это была общая линия, я бы разделил ее на две части.

Этот подход немного упрощен, так как внешняя окружность не такая же, как внутренняя окружность каждого аккорда, поэтому я немного ухожу, но она должна быть работоспособной.

Для ярлыков, которые находятся на вершине отображения, это будет неудобно: внутренний радиус короче, поэтому формула для определения, если строка достаточно короткая, чтобы отображаться, может быть неправильной - что может привести к тому, что некоторые персонажи поднимаются по бокам (ваш пример также 16 пикселей как разница в радиусах, чтобы вычислить, если текст слишком длинный, а не 24).

Это конечный результат:

Изображение 174551

Вот демонстрация.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню