Лучший способ уместить текст переменного размера в полукруг в d3.js?
В настоящее время я работаю над визуализацией в d3.js с целью визуализировать сходство данных. Я хочу сравнить свои данные в кругах, создав два полукруга для каждого узла и поместив данные сравнения в эти полукруги. Мои данные состоят из строк (каждый полукруг получает одно предложение).
Мой нынешний подход заключается в следующем:
сначала я создаю необходимые данные узла, используя pack-layout.
var bubble = d3.pack().size([SVG_WIDTH,SVG_HEIGHT]).padding(CIRCLE_PADDING),
root = d3.hierarchy({children: COMPARISON_DATA}).sum(function(d){ return d.children ? 0 : d[2]});
var nodeData = bubble(root).children;
d[2] - максимальная длина строки из двух предложений, помещаемых в полукруги, и, таким образом, определяет радиус кругов.
Затем я перебираю каждый узел и создаю соответствующие полукруги. Я удалил все части кода, которые не имеют отношения к моему вопросу.
nodeData.forEach(function (data, index) {
//upperCircleGroup simply adds a small y-translate, so that the semicircles have a margin
var gUpper = upperCircleGroup.append("g");
var gLower = lowerCircleGroup.append("g");
var lowerCircle = gLower.append('path')
.attr('d', d3.arc()({
innerRadius: 0,
outerRadius: data.r,
startAngle: Math.PI / 2,
endAngle: 3 / 2 * Math.PI
}))
.attr('transform', `translate(${data.x},${data.y})`)
var upperCircle = gUpper.append('path')
.attr('d', d3.arc()({
innerRadius: 0,
outerRadius: data.r,
startAngle: 1 / 2 * Math.PI,
endAngle: - 1 / 2 * Math.PI
}))
.attr('transform', `translate(${data.x},${data.y})`)
var upperText = gUpper
.append("foreignObject")
.attr("width", () => {return data.r*Math.sqrt(2)})
.attr("height", () => {return data.r*(Math.sqrt(2)/2)})
.attr('transform', `translate(${data.x - (data.r / Math.sqrt(2))},${data.y - (data.r/Math.sqrt(2)) })`)
.text(() => {return data.data[0]})
var lowerText = gLower
.append("foreignObject")
.attr("width", () => {return data.r*Math.sqrt(2)})
.attr("height", () => {return data.r*(Math.sqrt(2)/2)})
.attr('transform', `translate(${data.x - (data.r / Math.sqrt(2))},${data.y })`)
.text(() => {return data.data[1]})
});
Как видите, я рисую полукруги с помощью дуги d3. Здесь возникает мой вопрос. У меня возникли проблемы с размещением моего текстового содержимого внутри дуги, поэтому после некоторого поиска я выбрал это решение, чтобы поместить div внутри моих полукругов, которые затем получают текст. Операции sqrt(2) используются для размещения квадрата в полукруге.
Моя проблема с этим решением заключается в том, что иногда предложение просто не помещается в div, и часть содержимого теряется. Есть ли способ вычислить необходимый размер шрифта строки, чтобы он соответствовал div заданного размера? Если бы это было возможно, я мог бы просто вычислить соответствующий размер шрифта и добавить параметр масштабирования к визуализации. Кроме того, если есть более эффективные способы достичь того, что я пытаюсь сделать, я также был бы рад получить некоторые отзывы от вас, ребята, потому что я полный новичок, когда дело доходит до использования d3.
1 ответ
Сделать текст отзывчивым на элемент сложно, но CSS-Tricks сделали отличную статью о различных способах подхода к этому...