首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何使用d3.js更新svg路径

如何使用d3.js更新svg路径
EN

Stack Overflow用户
提问于 2014-03-25 06:25:07
回答 2查看 30.2K关注 0票数 18

我想应用官方文档中的"general update pattern"来更新鼠标事件上的svg路径(但可以是按钮或其他任何东西)。

但是路径只会被添加,而不会被更新。我想这就是为什么我没有正确使用enterexit属性的原因,但经过各种尝试后,我无法让它工作。

这是一个jsfiddle

我的js代码如下:

代码语言:javascript
复制
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:

代码语言:javascript
复制
<!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>
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-25 07:03:25

您的代码没有选择现有的元素,所以不是通过update选择来更新现有路径的"d“属性,而是每次都附加一个新的路径。此版本的render()产生了预期的行为。更多关于选择here的信息。

代码语言:javascript
复制
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执行的任何操作都将应用于现有元素和新元素。

票数 16
EN

Stack Overflow用户

发布于 2014-03-25 09:20:55

请尝试以下代码,我认为这是您想要的。这个问题是因为当你想要更新元素时,你应该区分enter,update和exit,否则它会一次又一次地添加数据。

代码语言:javascript
复制
$(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();
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22621865

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档