我正在处理包含3个点的图形。 (0,0),(5,5),(10,10)。用户可以在y轴上移动这些点。目前,我可以在Y轴上移动这些点,但是当其中之一移动时,无法“更新”这些点之间的路径。
我会提供任何帮助,谢谢!
这是代码,我正在使用d3js v4:
<script>
// Set the dimension of the canvas / graph
var margin = { top: 30, right: 20, bottom: 30, left: 50 };
var width = 600 - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;
// Add the svg canvas
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Set the linear scale and the range for the axes
var xRange = d3.scaleLinear().range([0, width]).domain([0, 10]);
var yRange = d3.scaleLinear().range([height, 0]).domain([0, 10]);
var line = d3.line()
.x(d => xRange(d.x))
.y(d => yRange(d.y))
.curve(d3.curveLinear);
var drag = d3.drag()
.on("drag", function (d) {
var dragPoint = d3.select(this);
dragPoint.attr("cy", d.y = d3.event.y);
});
// Points dataset
var radius = 6;
var points = [{ x: 0, y: 0 }, { x: 5, y: 5 }, { x: 10, y: 10 }];
// Add the X axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(xRange));
// Add the Y axis
svg.append("g")
.call(d3.axisLeft(yRange));
// Add points to the svg
var circles = svg.attr("class", "circle")
.selectAll("circle")
.data(points)
.enter()
.append("circle")
.attr("cx", d => xRange(d.x))
.attr("cy", d => yRange(d.y))
.attr("r", radius)
.attr("fill", "teal")
.style("cursor", "pointer");
// Add the path
var path = svg.append("path")
.attr("d", line(points));
drag(circles);
</script>
答案 0 :(得分:0)
您的drag
几乎不需要调整。
使用https://stackoverflow.com/a/38650810/9938317更改了起始对象,因此我们开始在圆形位置拖动。
然后,我们需要将这一点的y值反转并将其填充到基准对象中。为了限制拖动超出轴域,我们首先将其钳位到该域。
然后,我们根据更新后的path
数组来更新points
。
var drag = d3.drag()
.subject(function() {
var t = d3.select(this);
return {x: t.attr("cx"), y: t.attr("cy")};
})
.on("drag", function (d) {
var domain = yRange.domain();
d.y = Math.max(domain[0], Math.min(yRange.invert(d3.event.y), domain[1]))
d3.select(this).attr("cy", yRange(d.y));
path.attr("d", line(points));
});
完整的示例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://d3js.org/d3.v5.min.js"></script>
<style>
.line {stroke:steelblue; fill:none;}
</style>
</head>
<body>
<script>
// Set the dimension of the canvas / graph
var margin = { top: 30, right: 20, bottom: 30, left: 50 };
var width = 600 - margin.left - margin.right;
var height = 500 - margin.top - margin.bottom;
// Add the svg canvas
var svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
// Set the linear scale and the range for the axes
var xRange = d3.scaleLinear().range([0, width]).domain([0, 10]);
var yRange = d3.scaleLinear().range([height, 0]).domain([0, 10]);
var line = d3.line()
.x(d => xRange(d.x))
.y(d => yRange(d.y))
.curve(d3.curveLinear);
var drag = d3.drag()
.subject(function() {
var t = d3.select(this);
return {x: t.attr("cx"), y: t.attr("cy")};
})
.on("drag", function (d) {
var domain = yRange.domain();
d.y = Math.max(domain[0], Math.min(yRange.invert(d3.event.y), domain[1]))
d3.select(this).attr("cy", yRange(d.y));
path.attr("d", line(points));
});
// Points dataset
var radius = 6;
var points = [{ x: 0, y: 0 }, { x: 5, y: 7 }, { x: 10, y: 10 }];
// Add the X axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(xRange));
// Add the Y axis
svg.append("g")
.call(d3.axisLeft(yRange));
// Add points to the svg
var circles = svg.attr("class", "circle")
.selectAll("circle")
.data(points)
.enter()
.append("circle")
.attr("cx", d => xRange(d.x))
.attr("cy", d => yRange(d.y))
.attr("r", radius)
.attr("fill", "teal")
.style("cursor", "pointer");
// Add the path
var path = svg.append("path")
.attr("class", "line")
.attr("d", line(points));
drag(circles);
</script>
</body>
</html>