D3 Appending Duplicates
by k_sav
HTML
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<body>
</body>
</html>
https://jsfiddle.net/AlexMarshaall/srL3huk9/4/#
CSS
svg {
background-color: #FFF;
cursor: default;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
}
svg:not(.active):not(.ctrl) {
cursor: crosshair;
}
path.link {
fill: none;
stroke: #000;
stroke-width: 4px;
cursor: default;
}
svg:not(.active):not(.ctrl) path.link {
cursor: pointer;
}
path.link.selected {
stroke-dasharray: 10, 2;
}
path.link.dragline {
pointer-events: none;
}
path.link.hidden {
stroke-width: 0;
}
circle.node {
stroke-width: 1.5px;
cursor: pointer;
}
text {
font: 12px sans-serif;
pointer-events: none;
}
text.id {
text-anchor: middle;
font-weight: bold;
}
JavaScript
const svg = d3.select('body')
.append('svg')
.attr('width', 900)
.attr('height', 500);
let hoverOverNode = null; // the node the mouse is currently hovering over
let mousedownNode = null; // the node that the mouse went down over
function resetMouseVars() {
mousedownNode = null;
}
var lastNodeId = 1;
var node1 = {
id: "n" + lastNodeId++,
xVal: 50,
yVal: 50
};
var node2 = {
id: "n" + lastNodeId++,
xVal: 100,
yVal: 100
}
const nodesData = [node1, node2];
const edgeData = [{
source: node1,
target: node2
}];
let paths = svg.append('svg:g').selectAll('path');
let nodes = svg.append('svg:g').selectAll('g');
const dragLine = svg.append('svg:path')
.attr('class', 'link dragline hidden')
.attr('d', 'M0,0L0,0');
function restart() {
nodes = nodes.data(nodesData, (d) => d.id); // Nodes is just the nodes to update
nodes.selectAll('g')
.style('fill', "DarkGreen");
nodes.exit().remove();
var newNodesToBeAdded = nodes.enter().append('svg:g');
newNodesToBeAdded.attr('transform', (d) => `translate(${d.xVal},${d.yVal})`)
.attr('id', (d) => d.id);
newNodesToBeAdded.append('svg:circle')
.attr('class', 'node')
.attr('r', 12)
.attr('stroke-width', 3)
.attr('stroke', 'black')
.style('fill', "DarkGreen")
.on('mouseover', function(d) {
hoverOverNode = d;
d3.select(this).attr('transform', 'scale(1.1)');
})
.on('mouseout', function(d) {
hoverOverNode = null;
d3.select(this).attr('transform', '');
})
.on('mousedown', (d) => {
if (d3.event.ctrlKey) return;
mousedownNode = d;
dragLine
.classed('hidden', false)
.attr('d', `M${mousedownNode.xVal},${mousedownNode.yVal}L${mousedownNode.xVal},${mousedownNode.yVal}`);
restart();
})
.on('mouseup', (d) => {
dragLine.classed('hidden', true);
});
newNodesToBeAdded.append('svg:text')
.attr('x', 0)
.attr('y', 4)
.attr('class', 'id')
.text((d) =>...