function update(obj, data, type, config) {
let circles = obj.selectAll('circle').data(data, d=>d.id)
circles.exit().remove()
let entered_circles = circles
.enter()
.append('circle')
if(config){
entered_circles
.style('opacity', 1)
.attr('id', d => d.id)
.attr('cx', d => d.x)
.attr('cy', d => d.y)
.style('fill', d => d.color)
.attr('r', d => d.radius)
} else {
entered_circles
.style('opacity', 1)
.attr('id', d => d.id)
.style('fill', d => d.color)
.attr('r', d => d.radius)
}
circles = circles.merge(entered_circles)
if(config){
let t = d3.transition()
.duration(config.DURATION)
.ease(d3.easeQuadOut)
if(type=='transition_by_default'){
circles
.transition(t)
.attr('cx', d => d.x)
.attr('cy', d => d.y)
.attr('r', d => d.radius)
.style('fill', d => d.color)
} else if(type=='transition_by_index'){
config.category.map((d,i)=> {
circles.filter("circle[id^='" + i.toString() + "']")
.transition(t)
.delay(function(d,i){ return config.DELAY*i })
.attr('cx', d => d.x)
.attr('cy', d => d.y)
})
} else if(type=='transition_by_length'){
config.category.map((d,i)=> {
circles.filter("circle[id^='" + i.toString() + "']")
.transition(t)
.delay(function(d,i){ return d.length*config.DELAY })
.attr('cx', d => d.x)
.attr('cy', d => d.y)
})
}
}
return circles
}