#javascript #svg #d3.js #css-selectors
#javascript #svg #d3.js #css-селекторы
Вопрос:
Я использую d3 v6 для создания группы, bucket
, содержащей подгруппы, содержащие разные SVG-элементы. После создания я хотел бы обновить данные для текстовых элементов svg в каждой группе класса textbox
, но я не могу выбрать и обновить элементы. В приведенном ниже коде я попытался обновить только текстовые элементы класса large
, но ничего не происходит. Я неправильно использую селекторы классов?
Вот как я создаю группы:
const bucket = svg.append('g')
.attr('class', 'bucket')
const textboxes = bucket.selectAll('g')
.data(data)
.join('g')
.attr('class', 'textbox')
.attr('transform', d => `translate(0, ${d.index * spacing})`)
const rects = textboxes.append('rect')
.attr("width", 5)
.attr("height", 50);
const textlarge = textboxes.append('text')
.attr('class', 'large')
.text(d => d.text);
const textsmall = textboxes.append('text')
.attr('class', 'small')
.text(d => d.text2);
Приведенный выше код приводит к следующей структуре DOM:
<svg>
<g class="bucket" transform="translate(50, 0)">
<g class="textbox">
<rect></rect>
<text class="large">A</text>
<text class="small">2</text>
</g>
<g class="textbox">
<rect></rect>
<text class="large">B</text>
<text class="small">1</text>
</g>
</g>
</svg>
Вот как я сейчас пытаюсь обновить данные в полях (в этом отрывке я пытаюсь обновить только текст класса large
):
let bucket = container.select('g.bucket')
.selectAll('g.textbox')
.data(newdata)
.join('g')
.attr('class', 'textbox')
.attr('transform', d => `translate(0, ${d.index * spacing})`)
const textlarge = bucket.append('text')
.attr('class', 'large')
.text(d => d.text));
Комментарии:
1. Я рекомендую вам ознакомиться с тем, что
.append
и как работают селекторы. Чтобы выделить весь текст с большим классом, используйтеtext.large
или.large
. Вы добавляете новые элементы, а не выбираете существующие.2. Вы имеете в виду что-то вроде
container.select('g.bucket').selectAll('g.textbox').selectAll('text.large')
? И добавить данные после этого?3. Если вы говорите об обновлении текстов, то да. Хотя вы можете просто использовать
container.selectAll('text.large')
напрямую, если хотите, нет необходимости в промежуточных шагах4. Хорошо, да,
container.selectAll('text.large')
работает. Я также понял, что мне нужно удалитьjoin()
, потому что я хочу полностью заменить содержимое. Вот почему он продолжал создавать новые элементы