viewof lines = {
const lines = [
[[464, 166], [637, 141]],
[[396, 396], [381, 299]]
].map(l => l.map(([x, y]) => [x / 964 * width, y]));
const svg = d3.select(DOM.svg(width, height))
.property("value", lines);
const line = svg.append("g")
.attr("stroke", "#ccc")
.selectAll("line")
.data(lines)
.enter().append("line");
const lineSegment = svg.append("g")
.attr("stroke", "black")
.attr("stroke-width", 1.5)
.selectAll("line")
.data(lines)
.enter().append("line");
const lineBisect = svg.append("g")
.attr("stroke-width", 1.5)
.selectAll("line")
.data(["red", "blue"])
.enter().append("line")
.attr("stroke", d => d);
const point = svg.append("g")
.attr("cursor", "move")
.attr("pointer-events", "all")
.attr("stroke", "transparent")
.attr("stroke-width", 30)
.selectAll("circle")
.data(d3.merge(lines))
.enter().append("circle")
.attr("r", 2.5)
.call(d3.drag()
.subject(([x, y]) => ({x, y}))
.on("drag", dragged));
update();
function dragged(d) {
d[0] = d3.event.x;
d[1] = d3.event.y;
update();
svg.dispatch("input");
}
function update() {
point
.attr("cx", d => d[0])
.attr("cy", d => d[1]);
line.data(lines.map(l => lineExtend(...l)))
.attr("x1", d => d[0][0])
.attr("y1", d => d[0][1])
.attr("x2", d => d[1][0])
.attr("y2", d => d[1][1]);
lineSegment
.attr("x1", d => d[0][0])
.attr("y1", d => d[0][1])
.attr("x2", d => d[1][0])
.attr("y2", d => d[1][1]);
lineBisect
.data([
lineExtend(...lineLineBisect(...lines[0], ...lines[1], +1)),
lineExtend(...lineLineBisect(...lines[0], ...lines[1], -1))
])
.attr("x1", d => d[0][0])
.attr("y1", d => d[0][1])
.attr("x2", d => d[1][0])
.attr("y2", d => d[1][1]);
}
return svg.node();
}