Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

310
Visualizações
Is it possible to not reorder elements when using d3.join?

In d3, we may change the order of elements in a selection, for example by using raise.

Yet, when we rebind the data and use join, this order is discarded.

This does not happen when we use "the old way" of binding data, using enter and merge.

See following fiddle where you can click a circle (for example the blue one) to bring it to front. When you click "redraw", the circles go back to their original z-ordering when using join, but not when using enter and merge.

Can I achive that the circles keep their z-ordering and still use join?

const data = [{
  id: 1,
  v: 10,
  c: 'red'
}, {
  id: 2,
  v: 30,
  c: 'blue'
}, {
  id: 3,
  v: 60,
  c: 'green'
}]

let nDrawCall = 0

function redraw() {
  nDrawCall++
  //svg1 with old enter-merge pattern that works
  const circles = d3.select('#svg1')
    .selectAll('circle')
    .data(data, d => d.id)
  circles
    .enter()
    .append('circle')
    .on('click', function() {
      d3.select(this).raise()
    })
    .merge(circles)
    .attr('cx', d => d.v * nDrawCall)
    .attr('cy', d => d.v)
    .attr('r', d => d.v)
    .attr('fill', d => d.c)
    
  //svg2 with new join pattern that sadly reorders
  d3.select('#svg2')
    .selectAll('circle')
    .data(data, d => d.id)
    .join(enter => enter
      .append('circle')
      .on('click', function() {
        d3.select(this).raise()
      })
    )
    .attr('cx', d => d.v * nDrawCall)
    .attr('cy', d => d.v)
    .attr('r', d => d.v)
    .attr('fill', d => d.c)
}

function reset() {
  nDrawCall = 0
  redraw()
}

redraw()

/*
while (true) {
  iter++
  console.log(iter)
  sleepFor(500)
}
*/
svg {
  height: 100px;
  width: 100%;
}
<html>
  <head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.3.0/d3.min.js"></script>
  </head>
  <body>
    <button onclick="redraw()">
      Redraw
    </button>
    <button onclick="reset()">
      Reset
    </button>
    <div>
      <svg id="svg1" />  
      <svg id="svg2" />
    </div>
  </body>

</html>

over 4 years ago · Santiago Trujillo
1 Respostas
Responde à pergunta

0

join does an implicit order after merging the enter- and update-selection, see https://github.com/d3/d3-selection/blob/91245ee124ec4dd491e498ecbdc9679d75332b49/src/selection/join.js#L14.

The selection order after the data binding in your example is still red, blue, green even if the document order is changed. So the circles are reordered to the original order using join.

You can get around that by changing the data binding reflecting the change in the document order. I did that here, by moving the datum of the clicked circle to the end of the data array.

let data = [{
  id: 1,
  v: 10,
  c: 'red'
}, {
  id: 2,
  v: 30,
  c: 'blue'
}, {
  id: 3,
  v: 60,
  c: 'green'
}]

let nDrawCall = 0

function redraw() {
  nDrawCall++
  d3.select('#svg2')
    .selectAll('circle')
    .data(data, d => d.id)
    .join(enter => enter
      .append('circle')
      .on('click', function() {
        const circle = d3.select(this).raise();
        data.push(data.splice(data.indexOf(circle.datum()), 1)[0]);
      })
    )
    .attr('cx', d => d.v * nDrawCall)
    .attr('cy', d => d.v)
    .attr('r', d => d.v)
    .attr('fill', d => d.c)
}

function reset() {
  nDrawCall = 0
  redraw()
}

redraw()
svg {
  height: 100px;
  width: 100%;
}
<html>
  <head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.3.0/d3.min.js"></script>
  </head>
  <body>
    <button onclick="redraw()">
      Redraw
    </button>
    <button onclick="reset()">
      Reset
    </button>
    <div>
      <svg id="svg2" />
    </div>
  </body>

</html>

over 4 years ago · Santiago Trujillo Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda