#d3.js
#d3.js
Вопрос:
У меня есть функция, которая отображает текстовый элемент с помощью tspan. Моя проблема в том, что функция draw() добавляет новый текстовый элемент, а не удаляет старый при перерисовке.
function draw(params) {
let g = d3.select(`#msr_${Id}`);
const value = params.Value;
const [a, b, c, d, x, y] = params.Matrix;
const matrix = [a, b, c, d, x params.Coord[0], y params.Coord[1]];
let text = g
.append("text")
.attr("font-weight", params.Font.Weight)
.attr("font-size", params.Font.Size)
.attr("font-family", params.Font.Family)
.attr("text-decoration", params.Font.Decoration)
.attr("transform", `matrix(${matrix})`)
.selectAll("text");
let desc = text.select("tspan").data([params.MsrName]);
desc
.enter()
.append("tspan")
.text((d) => d);
let textValue = text.select("tspan").data([value]);
textValue
.enter()
.append("tspan")
.text((d) => d);
g.exit().remove();
}
Комментарии:
1. Вы надеетесь выйти из tspans или удалить / заменить / обновить предыдущий родительский текстовый элемент? Если первое, то создание нового родительского
text
элемента при каждом цикле рисования означает, что все будет введено и ничего не выйдет (поскольку родительский элемент является новым и не имеет дочерних элементов для выхода).2. Я бы хотел обновить / заменить tspan. Я пытался добавить text.exit().remove() или desc.exit().remove(), но ничего не изменилось.
Ответ №1:
Я решаю эту проблему, создавая группу svg вручную.
<g id={`msr_${Id}`}>
<text id={`msr_txt_${Id}`}>
<tspan id={`msr_desc_${Id}`}></tspan>
<tspan id={`msr_value_${Id}`}></tspan>
</text>
</g>
Вот код:
let g = d3.select(`#msr_${Id}`);
let text = g
.select(`#msr_txt_${Id}`)
let desc = text.select(`#msr_desc_${Id}`).data([name]);
desc.text((d) => d);
desc.exit().remove();
let textValue = text.select(`#msr_value_${Id}`).data([value]);
textValue.text((d) => d);
textValue.exit().remove();
g.exit().remove()
Ответ №2:
Я не уверен, что d3 — лучший вариант для применения здесь, но это можно сделать. Это решение предназначено только для того, чтобы заставить его работать, оно никоим образом не оптимизировано.
function draw(params) {
// I am assuming that you have access to the svg
const value = params.Value;
const [a, b, c, d, x, y] = params.Matrix;
const matrix = [a, b, c, d, x params.Coord[0], y params.Coord[1]];
// #1. make sure that the container exists
if (!d3.select(`#msr_${Id}`).node()) {
d3.select(svg).append('g')
.attr('id', `#msr_${Id}`)
.append('text')
.attr('id', `#msr_desc_${Id}`);
}
// #2 - update the text element
const text = d3.select(`#msr_desc_${Id}`)
.attr("font-weight", params.Font.Weight)
.attr("font-size", params.Font.Size)
.attr("font-family", params.Font.Family)
.attr("text-decoration", params.Font.Decoration)
.attr("transform", `matrix(${matrix})`);
// #3 - update the tspan elements
let desc = text.selectAll("tspan")
.data([[params.MsrName, `msr_desc_${Id}`], [value, `msr_value_${Id}`]]);
desc
.enter()
.append("tspan")
.merge(desc)
.attr('id', (d) => d[1])
.text((d) => d[0]);
desc.exit().remove();
}