D3 & update data

by Riderman Sousa

HTML

<script src="https://unpkg.com/[email protected]"></script>
<script src="https://unpkg.com/[email protected]"></script>
<h3>Update data in D3 v4 using enter and exit not working</h3>

<button id="update"> Update data </button>
<button id="remove"> Remove data </button>
<button id="add"> Add data </button>
<br><hr>
<div id="matrix"> </div>
<p>You can check the question <a href="http://stackoverflow.com/questions/42962792/update-data-in-d3-v4-using-enter-and-exit-not-working#">on StackOverflow</a> </p>

CSS

html, body: {
  height: 100%;
  width: 100%;
}
#matrix {
  border: 1px solid black;
  height: 400px;
}

Babel + JSX

const data = [
  {"id": "A", "x": 2000, "y": 2000 },
  {"id": "B", "x": 5000, "y": 5000 },
  {"id": "C", "x": 10000, "y": 10000 }
]

const letters = "DEFGHIJKLMNOPQRSTUVXWYZ".split('')

const el = document.getElementById("matrix")

const SIZE = {width: el.offsetWidth, height: el.offsetHeight};
const DOMAIN = {x: [20000, 0], y: [0, 20000]};
const SCALES = {
	x: d3.scaleLinear().range([SIZE.width, 0]).domain(DOMAIN.x),
  y: d3.scaleLinear().range([0,  SIZE.height]).domain(DOMAIN.y)
}

// Draw board
const chart = d3.select(el)
    .append('svg:svg')
    .attr('width', SIZE.width)
    .attr('height', SIZE.height)
    .attr('class', 'chart');
    
const svg = chart.append('g')
	.attr('transform', `translate(0, 0`)
  .attr('width', SIZE.width)
  .attr('height', SIZE.height)
  .attr('class', 'main')

// Handle Event to update D3
$(el).bind("updateD3", function () {
	
  let dot = svg
		.selectAll('.dot')
  	.data(data, d => d.id + d.y + d.x)
    
	dot.exit().remove()
    
	let dotG = dot.enter()
    .append("g")
    .attr('class', 'dot')
  let circle = dotG
    .append("circle")
    .attr('class', 'circle')
  circle
  	.attr('fill', 'black')
    .attr('r', '9')
    .attr('cx', d => SCALES.x(d.x))
    .attr('cy', d => SCALES.y(d.y))
    .merge(circle)
  /*
  const letter = dot
    .append("text")
    .attr('class', 'letter')
    .attr('x', d => SCALES.x(d.x))
    .attr('y', d => SCALES.y(d.y))
    .attr('text-anchor', 'middle')
    .attr('fill', 'white')
    .attr('alignment-baseline', 'central')
    .text(d => d.id)
    */
});

$(el).trigger("updateD3");

// Handle Button Clicks
$("#update").click(function() {
  const idx =  _.random(0, data.length-1)
  data[idx].x = _.random(0, 20000);
  data[idx].y = _.random(0, 20000);
  console.log('Modified object %s: %O', data[idx].id, data[idx])
  $(el).trigger("updateD3");
})

$("#add").click(function() {
  data.push({ 
  	id: letters.shift(), 
    x: _.random(0, _.max(DOMAIN.x)), 
    y: _.random(0, _.max(DOMAIN.y)) 
  })
 ...