Add spline editor example.
This commit is contained in:
Родитель
020aaa53e1
Коммит
beb53fe035
|
@ -0,0 +1,22 @@
|
|||
body {
|
||||
font: 10px sans-serif;
|
||||
}
|
||||
|
||||
.rule line {
|
||||
stroke: #eee;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
|
||||
.rule line.axis {
|
||||
stroke: #000;
|
||||
}
|
||||
|
||||
.line {
|
||||
fill: none;
|
||||
stroke: steelblue;
|
||||
stroke-width: 1.5px;
|
||||
}
|
||||
|
||||
circle.line {
|
||||
fill: #fff;
|
||||
}
|
|
@ -1,101 +1,11 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Line Chart</title>
|
||||
<link type="text/css" rel="stylesheet" href="line.css"/>
|
||||
<script type="text/javascript" src="../../d3.js"></script>
|
||||
<style type="text/css">
|
||||
|
||||
body {
|
||||
font: 10px sans-serif;
|
||||
}
|
||||
|
||||
.rule line {
|
||||
stroke: #eee;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
|
||||
.rule line.axis {
|
||||
stroke: #000;
|
||||
}
|
||||
|
||||
.line {
|
||||
fill: none;
|
||||
stroke: steelblue;
|
||||
stroke-width: 1.5px;
|
||||
}
|
||||
|
||||
circle.line {
|
||||
fill: #fff;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
|
||||
var data = d3.range(20).map(function(i) {
|
||||
return {x: i / 19, y: (Math.sin(i / 3) + 1) / 2};
|
||||
});
|
||||
|
||||
var w = 450,
|
||||
h = 275,
|
||||
p = 20,
|
||||
x = d3.scale.linear().domain([0, 1]).range([0, w]),
|
||||
y = d3.scale.linear().domain([0, 1]).range([h, 0]);
|
||||
|
||||
var vis = d3.select("body")
|
||||
.data([data])
|
||||
.append("svg:svg")
|
||||
.attr("width", w + p * 2)
|
||||
.attr("height", h + p * 2)
|
||||
.append("svg:g")
|
||||
.attr("transform", "translate(" + p + "," + p + ")");
|
||||
|
||||
var rules = vis.selectAll("g.rule")
|
||||
.data(x.ticks(10))
|
||||
.enter().append("svg:g")
|
||||
.attr("class", "rule");
|
||||
|
||||
rules.append("svg:line")
|
||||
.attr("x1", x)
|
||||
.attr("x2", x)
|
||||
.attr("y1", 0)
|
||||
.attr("y2", h - 1);
|
||||
|
||||
rules.append("svg:line")
|
||||
.attr("class", function(d) { return d ? null : "axis"; })
|
||||
.attr("y1", y)
|
||||
.attr("y2", y)
|
||||
.attr("x1", 0)
|
||||
.attr("x2", w + 1);
|
||||
|
||||
rules.append("svg:text")
|
||||
.attr("x", x)
|
||||
.attr("y", h + 3)
|
||||
.attr("dy", ".71em")
|
||||
.attr("text-anchor", "middle")
|
||||
.text(x.tickFormat(10));
|
||||
|
||||
rules.append("svg:text")
|
||||
.attr("y", y)
|
||||
.attr("x", -3)
|
||||
.attr("dy", ".35em")
|
||||
.attr("text-anchor", "end")
|
||||
.text(y.tickFormat(10));
|
||||
|
||||
vis.append("svg:path")
|
||||
.attr("class", "line")
|
||||
.attr("d", d3.svg.line()
|
||||
.x(function(d) { return x(d.x); })
|
||||
.y(function(d) { return y(d.y); }));
|
||||
|
||||
vis.selectAll("circle.line")
|
||||
.data(data)
|
||||
.enter().append("svg:circle")
|
||||
.attr("class", "line")
|
||||
.attr("cx", function(d) { return x(d.x); })
|
||||
.attr("cy", function(d) { return y(d.y); })
|
||||
.attr("r", 3.5);
|
||||
|
||||
</script>
|
||||
<script type="text/javascript" src="line.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -0,0 +1,63 @@
|
|||
var data = d3.range(20).map(function(i) {
|
||||
return {x: i / 19, y: (Math.sin(i / 3) + 1) / 2};
|
||||
});
|
||||
|
||||
var w = 450,
|
||||
h = 275,
|
||||
p = 20,
|
||||
x = d3.scale.linear().domain([0, 1]).range([0, w]),
|
||||
y = d3.scale.linear().domain([0, 1]).range([h, 0]);
|
||||
|
||||
var vis = d3.select("body")
|
||||
.data([data])
|
||||
.append("svg:svg")
|
||||
.attr("width", w + p * 2)
|
||||
.attr("height", h + p * 2)
|
||||
.append("svg:g")
|
||||
.attr("transform", "translate(" + p + "," + p + ")");
|
||||
|
||||
var rules = vis.selectAll("g.rule")
|
||||
.data(x.ticks(10))
|
||||
.enter().append("svg:g")
|
||||
.attr("class", "rule");
|
||||
|
||||
rules.append("svg:line")
|
||||
.attr("x1", x)
|
||||
.attr("x2", x)
|
||||
.attr("y1", 0)
|
||||
.attr("y2", h - 1);
|
||||
|
||||
rules.append("svg:line")
|
||||
.attr("class", function(d) { return d ? null : "axis"; })
|
||||
.attr("y1", y)
|
||||
.attr("y2", y)
|
||||
.attr("x1", 0)
|
||||
.attr("x2", w + 1);
|
||||
|
||||
rules.append("svg:text")
|
||||
.attr("x", x)
|
||||
.attr("y", h + 3)
|
||||
.attr("dy", ".71em")
|
||||
.attr("text-anchor", "middle")
|
||||
.text(x.tickFormat(10));
|
||||
|
||||
rules.append("svg:text")
|
||||
.attr("y", y)
|
||||
.attr("x", -3)
|
||||
.attr("dy", ".35em")
|
||||
.attr("text-anchor", "end")
|
||||
.text(y.tickFormat(10));
|
||||
|
||||
vis.append("svg:path")
|
||||
.attr("class", "line")
|
||||
.attr("d", d3.svg.line()
|
||||
.x(function(d) { return x(d.x); })
|
||||
.y(function(d) { return y(d.y); }));
|
||||
|
||||
vis.selectAll("circle.line")
|
||||
.data(data)
|
||||
.enter().append("svg:circle")
|
||||
.attr("class", "line")
|
||||
.attr("cx", function(d) { return x(d.x); })
|
||||
.attr("cy", function(d) { return y(d.y); })
|
||||
.attr("r", 3.5);
|
|
@ -0,0 +1,19 @@
|
|||
body {
|
||||
font: 13px sans-serif;
|
||||
}
|
||||
|
||||
circle, .line {
|
||||
fill: none;
|
||||
stroke: steelblue;
|
||||
stroke-width: 1.5px;
|
||||
}
|
||||
|
||||
circle {
|
||||
fill: rgba(255,255,255,.2);
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
circle.selected {
|
||||
fill: rgba(255,239,14,.2);
|
||||
stroke: #ff7f0e;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Spline Editor</title>
|
||||
<link type="text/css" rel="stylesheet" href="spline-editor.css"/>
|
||||
<script type="text/javascript" src="../../d3.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="chart"></div>
|
||||
<p><label for="interpolate">Interpolate:</label>
|
||||
<select id="interpolate"></select>
|
||||
<script type="text/javascript" src="spline-editor.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,121 @@
|
|||
var w = 800,
|
||||
h = 600,
|
||||
p = 20,
|
||||
index = 3,
|
||||
duration = 1000;
|
||||
|
||||
var points = d3.range(1, 5).map(function(i) {
|
||||
return [
|
||||
i * w / 5,
|
||||
50 + Math.random() * (h - 100)
|
||||
];
|
||||
});
|
||||
|
||||
var wrapper = d3.select("#chart")
|
||||
.data([points])
|
||||
.append("svg:svg")
|
||||
.attr("width", w + p * 2)
|
||||
.attr("height", h + p * 2);
|
||||
|
||||
var vis = wrapper.append("svg:g")
|
||||
.attr("transform", "translate(" + p + "," + p + ")");
|
||||
|
||||
var line = d3.svg.line()
|
||||
.x(function(d) { return d[0]; })
|
||||
.y(function(d) { return d[1]; });
|
||||
|
||||
vis.append("svg:path")
|
||||
.attr("class", "line")
|
||||
|
||||
function update() {
|
||||
vis.select("path")
|
||||
.transition().duration(duration)
|
||||
.attr("d", line);
|
||||
|
||||
var circle = vis.selectAll("circle")
|
||||
.data(points, function(d) { return d; });
|
||||
|
||||
circle.enter().append("svg:circle")
|
||||
.attr("class", function(d, i) { return i === index ? "selected" : null; })
|
||||
.attr("cx", function(d) { return d[0]; })
|
||||
.attr("cy", function(d) { return d[1]; })
|
||||
.attr("r", 6.5)
|
||||
.attr("opacity", 1)
|
||||
.on("mousedown", function(d, i) {
|
||||
vis.selectAll("circle").filter(function(d, j) {
|
||||
return j === index;
|
||||
}).attr("class", null);
|
||||
var circle = d3.select(this)
|
||||
.attr("class", "selected");
|
||||
index = i;
|
||||
wrapper.on("mousemove", function() {
|
||||
var m = d3.svg.mouse(this);
|
||||
m[0] -= p;
|
||||
m[1] -= p;
|
||||
points[index] = m;
|
||||
circle
|
||||
.attr("cx", m[0])
|
||||
.attr("cy", m[1]);
|
||||
vis.select("path")
|
||||
.attr("d", line);
|
||||
});
|
||||
d3.event.preventDefault();
|
||||
d3.event.stopPropagation();
|
||||
});
|
||||
|
||||
circle
|
||||
.attr("class", function(d, i) { return i === index ? "selected" : null; });
|
||||
|
||||
circle.exit().transition()
|
||||
.duration(duration / 4)
|
||||
.attr("opacity", 1e-6)
|
||||
.remove();
|
||||
}
|
||||
|
||||
update();
|
||||
|
||||
wrapper.on("mousedown", function() {
|
||||
var m = d3.svg.mouse(this);
|
||||
index = points.push([m[0] - p, m[1] - p]) - 1;
|
||||
update();
|
||||
});
|
||||
|
||||
wrapper.on("mouseup", function() {
|
||||
wrapper.on("mousemove", null);
|
||||
});
|
||||
|
||||
d3.select(window).on("keydown", function() {
|
||||
var e = d3.event;
|
||||
// code 8 is backspace, code 46 is delete
|
||||
if ((e.keyCode == 8 || e.keyCode == 46) && (index >= 0)) {
|
||||
points.splice(index--, 1);
|
||||
update();
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
// Add interpolator dropdown
|
||||
var interpolators = [
|
||||
"linear",
|
||||
"step-before",
|
||||
"step-after",
|
||||
"basis",
|
||||
"basis-closed",
|
||||
"cardinal",
|
||||
"cardinal-closed"
|
||||
];
|
||||
|
||||
var select = d3.select("#interpolate");
|
||||
|
||||
select.selectAll("option")
|
||||
.data(interpolators)
|
||||
.enter().append("option")
|
||||
.attr("value", String)
|
||||
.text(String);
|
||||
|
||||
select.on("change", function() {
|
||||
line.interpolate(this.value);
|
||||
vis.select("path")
|
||||
.transition().duration(1000)
|
||||
.attr("d", line);
|
||||
});
|
Загрузка…
Ссылка в новой задаче