我想应用官方文档中的"general update pattern"来更新鼠标事件上的svg路径(但可以是按钮或其他任何东西)。
但是路径只会被添加,而不会被更新。我想这就是为什么我没有正确使用enter
和exit
属性的原因,但经过各种尝试后,我无法让它工作。
这是一个jsfiddle。
我的js代码如下:
var shapeCoords = [
[10, 10], [100, 10], [100, 100], [10, 100]
];
$(function() {
var container = $('#container');
// D3
console.log("D3: ", d3);
var svg = d3.select('#container')
.append('svg:svg')
.attr('height', 600)
.attr('width', 800);
var line = d3.svg.line()
.x(function(d) { return d[0]; })
.y(function(d) { return d[1]; })
.interpolate('linear');
function render() {
svg.data(shapeCoords)
.append('svg:path')
.attr('d', line(shapeCoords) + 'Z')
.style('stroke-width', 1)
.style('stroke', 'steelblue');
}
render();
var mouseIsDown = false;
container.on('mousedown mouseup mousemove', function(e) {
if (e.type == 'mousedown') {
mouseIsDown = true;
shapeCoords[3] = [e.offsetX, e.offsetY];
} else if (e.type == 'mouseup' ){
mouseIsDown = false;
shapeCoords[3] = [e.offsetX, e.offsetY];
} else if (e.type == 'mousemove') {
if (mouseIsDown) {
shapeCoords[3] = [e.offsetX, e.offsetY];
render();
}
}
});
});
和html:
<!DOCTYPE html>
<html>
<head>
<title>D3 mousemove</title>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js">
</script>
<script type="text/javascript"
src="http://mbostock.github.com/d3/d3.js">
</script>
<script type="text/javascript" src="script.js"></script>
<style>
#container {
width: 800px;
height: 600px;
border: 1px solid silver; }
path, line {
stroke: steelblue;
stroke-width: 1;
fill: none;
}
</style>
</head>
<body>
<div id="container"></div>
</body>
</html>
发布于 2014-03-25 07:03:25
您的代码没有选择现有的元素,所以不是通过update
选择来更新现有路径的"d“属性,而是每次都附加一个新的路径。此版本的render()
产生了预期的行为。更多关于选择here的信息。
function render() {
path = svg.selectAll('path').data([shapeCoords])
path.attr('d', function(d){return line(d) + 'Z'})
.style('stroke-width', 1)
.style('stroke', 'steelblue');
path.enter().append('svg:path').attr('d', function(d){return line(d) + 'Z'})
.style('stroke-width', 1)
.style('stroke', 'steelblue');
path.exit().remove()
通过.data()
在path
上运行数据连接后,在path
上执行的操作将仅应用于更新选择。也就是说,只有那些在新连接下仍具有相应数据元素的现有元素。当您调用enter().append()
时,它将为没有预先存在的元素的每个数据元素附加一个新元素,然后将以下操作仅应用于这些元素。
在上面的代码中,上面的第一个path.attr()
只在现有元素上操作;在path.enter()
之后应用的那些只适用于新元素。它没有出现在上面的代码片段中,但是enter()
将enter选项添加到更新选项中:在调用enter()
之后对path
执行的任何操作都将应用于现有元素和新元素。
发布于 2014-03-25 09:20:55
请尝试以下代码,我认为这是您想要的。这个问题是因为当你想要更新元素时,你应该区分enter,update和exit,否则它会一次又一次地添加数据。
$(function() {
var container = $('#container');
// D3
console.log("D3: ", d3);
var svg = d3.select('#container')
.append('svg:svg')
.attr('height', 600)
.attr('width', 800);
var line = d3.svg.line()
.x(function(d) { return d[0]; })
.y(function(d) { return d[1]; })
.interpolate('linear');
svg.data(shapeCoords)
.append('svg:path')
.attr('d', line(shapeCoords) + 'Z')
.style('stroke-width', 1)
.style('stroke', 'steelblue');
function render() {
var svg = d3.select('#container').select("svg").selectAll('path').data(shapeCoords);
svg.enter().append('svg:path')
.attr('d', line(shapeCoords) + 'Z')
.style('stroke-width', 1)
.style('stroke', 'steelblue');
svg.attr('d', line(shapeCoords) + 'Z')
.style('stroke-width', 1)
.style('stroke', 'steelblue');
svg.exit().remove();
}
render();
https://stackoverflow.com/questions/22621865
复制相似问题