# HG changeset patch # User Jordi GutiƩrrez Hermoso # Date 1534860945 14400 # Node ID 528f9ff42e9e3b08d43d182be3db6261fd567e2d # Parent b94d24316ea8b628539c366e91d4737957b87b56 slider works diff --git a/splines.html b/splines.html --- a/splines.html +++ b/splines.html @@ -38,140 +38,22 @@ .selected { fill: #ff7f0e; + fill-opacity: 1; stroke: #ff7f0e; } - + +

+
- + diff --git a/splines.js b/splines.js new file mode 100644 --- /dev/null +++ b/splines.js @@ -0,0 +1,137 @@ +var width = 960, + height = 500; + +var points = d3.range(1, 5).map(function(i) { + return [i * width / 5, 50 + Math.random() * (height - 100), 1]; +}); + +var dragged = null, + selected = points[0]; + +var slider = d3.slider() + .axis(true) + .min(-1) + .max(1) + .value(1) + .on("slide", function(evt, value){ + selected[2] = value; + }); + +var line = d3.svg.line(); + +var svg = d3.select("#splines").append("svg") + .attr("width", width) + .attr("height", height) + .attr("tabindex", 1); + +svg.append("rect") + .attr("width", width) + .attr("height", height) + .on("mousedown", mousedown); + +svg.append("path") + .datum(points) + .attr("class", "line") + .call(redraw); + +d3.select(window) + .on("mousemove", mousemove) + .on("mouseup", mouseup) + .on("keydown", keydown); + +d3.select("#interpolate") + .on("change", change) + .selectAll("option") + .data([ + "linear", + "step-before", + "step-after", + "basis", + "basis-open", + "basis-closed", + "cardinal", + "cardinal-open", + "cardinal-closed", + "monotone" + ]) + .enter().append("option") + .attr("value", function(d) { return d; }) + .text(function(d) { return d; }); + +svg.node().focus(); + +d3.select("#slider").call(slider); + +function redraw() { + svg.select("path").attr("d", line); + + var circle = svg.selectAll("circle") + .data(points, function(d) { return d; }); + + circle.enter().append("circle") + .attr("r", 1e-6) + .on("mousedown", function(d, i) { + selected = dragged = d; + slider.value(d[2]); + redraw(); + }) + .transition() + .duration(750) + .ease("elastic") + .attr("r", 6.5); + + circle + .classed("selected", function(d) { return d === selected; }) + .attr("cx", function(d) { return d[0]; }) + .attr("cy", function(d) { return d[1]; }); + + circle.exit().remove(); + + if (d3.event) { + d3.event.preventDefault(); + d3.event.stopPropagation(); + } +} + +function change() { + line.interpolate(this.value); + redraw(); +} + +function mousedown() { + var newcirc = d3.mouse(svg.node()); + newcirc.push(1); + slider.value(1); + points.push(selected = dragged = newcirc); + redraw(); +} + +function mousemove() { + if (!dragged) return; + var m = d3.mouse(svg.node()); + dragged[0] = Math.max(0, Math.min(width, m[0])); + dragged[1] = Math.max(0, Math.min(height, m[1])); + redraw(); +} + +function mouseup() { + if (!dragged) return; + mousemove(); + dragged = null; +} + +function keydown() { + if (!selected) return; + switch (d3.event.keyCode) { + case 8: // backspace + case 46: { // delete + var i = points.indexOf(selected); + points.splice(i, 1); + selected = points.length ? points[i > 0 ? i - 1 : 0] : null; + redraw(); + break; + } + } +} + +