Выделение D3 не обновляет существующие классифицированные текстовые элементы

#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() , потому что я хочу полностью заменить содержимое. Вот почему он продолжал создавать новые элементы