114 строки
2.5 KiB
JavaScript
114 строки
2.5 KiB
JavaScript
var w = 960,
|
|
h = 500,
|
|
line = d3.svg.line(),
|
|
points = d3.range(1, 5).map(function(i) { return [i * w / 5, 50 + Math.random() * (h - 100)]; }),
|
|
dragged = null,
|
|
selected = points[0];
|
|
|
|
var vis = d3.select("#chart").append("svg:svg")
|
|
.attr("width", w)
|
|
.attr("height", h);
|
|
|
|
vis.append("svg:rect")
|
|
.attr("width", w)
|
|
.attr("height", h)
|
|
.on("mousedown", function() {
|
|
points.push(selected = dragged = d3.svg.mouse(vis.node()));
|
|
update();
|
|
});
|
|
|
|
vis.append("svg:path")
|
|
.data([points])
|
|
.attr("class", "line")
|
|
.call(update);
|
|
|
|
d3.select(window)
|
|
.on("mousemove", mousemove)
|
|
.on("mouseup", mouseup)
|
|
.on("keydown", keydown);
|
|
|
|
// Add interpolator dropdown
|
|
d3.select("#interpolate")
|
|
.on("change", function() {
|
|
line.interpolate(this.value);
|
|
update();
|
|
})
|
|
.selectAll("option")
|
|
.data([
|
|
"linear",
|
|
"step-before",
|
|
"step-after",
|
|
"basis",
|
|
"basis-open",
|
|
"basis-closed",
|
|
"cardinal",
|
|
"cardinal-open",
|
|
"cardinal-closed",
|
|
"monotone"
|
|
])
|
|
.enter().append("option")
|
|
.attr("value", String)
|
|
.text(String);
|
|
|
|
function update() {
|
|
vis.select("path").attr("d", line);
|
|
|
|
var circle = vis.selectAll("circle")
|
|
.data(points, function(d) { return d; });
|
|
|
|
circle.enter().append("svg:circle")
|
|
.attr("class", function(d) { return d === selected ? "selected" : null; })
|
|
.attr("cx", function(d) { return d[0]; })
|
|
.attr("cy", function(d) { return d[1]; })
|
|
.attr("r", 1e-6)
|
|
.on("mousedown", function(d) {
|
|
selected = dragged = d;
|
|
update();
|
|
})
|
|
.transition()
|
|
.duration(750)
|
|
.ease("elastic")
|
|
.attr("r", 6.5);
|
|
|
|
circle
|
|
.attr("class", function(d) { return d === selected ? "selected" : null; })
|
|
.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 mousemove() {
|
|
if (!dragged) return;
|
|
var m = d3.svg.mouse(vis.node());
|
|
dragged[0] = Math.max(0, Math.min(w, m[0]));
|
|
dragged[1] = Math.max(0, Math.min(h, m[1]));
|
|
update();
|
|
}
|
|
|
|
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;
|
|
update();
|
|
break;
|
|
}
|
|
}
|
|
}
|