graphic = () => {
const svg = d3.create("svg")
.attr("width", w)
.attr("height", height);
const start = svg.append("circle")
.attr("class", "a")
.attr("r", r)
.attr("cx", mutable a[0])
.attr("cy", mutable a[1])
.style("fill", color(.02))
.call(drag);
const controlA = svg.append("circle")
.attr("class", "b")
.attr("r", r)
.attr("cx", mutable b[0])
.attr("cy", mutable b[1])
.style("fill", "white")
.style("fill-opacity", 0)
.style("stroke", "black")
.call(drag);
const controlB = svg.append("circle")
.attr("class", "c")
.attr("r", r)
.attr("cx", mutable c[0])
.attr("cy", mutable c[1])
.style("fill", "white")
.style("fill-opacity", 0)
.style("stroke", "black")
.call(drag);
const end = svg.append("circle")
.attr("class", "d")
.attr("r", r)
.attr("cx", mutable d[0])
.attr("cy", mutable d[1])
.style("fill", color(1))
.call(drag);
const line = svg.append("polyline")
.attr("fill", "none")
.attr("stroke", "black")
.lower();
updateCurve();
function updateCurve(){
mutable bezier = cubicBezier(a, b, c, d, precision);
line.attr("points", bezier);
if (showPoints) {
const curve = svg.selectAll(".bezier")
.data(bezier);
curve.exit().remove();
curve.enter().append("circle")
.attr("class", "bezier")
.style("pointer-events", "none")
.attr("r", r / 2)
.merge(curve)
.style("fill", (d, i) => color(i / (bezier.length - 1)))
.attr("cx", d => d[0])
.attr("cy", d => d[1]);
}
}
return svg.node();
}