从D3.js v3迁移到D3.js v4无法正常工作 - 选择问题?

时间:2016-08-20 17:29:17

标签: javascript d3.js d3v4

我正在尝试将D3 v3中的JSFiddle迁移到D3 v4,但它无效。

我知道D3拖动行为现在只是d3.drag()我已经改变了,但是当试图运行它时,它在第53行给出错误:

rect = d3.select(self.rectangleElement[0][0]);

与Chrome说:

  

未捕获的TypeError:无法读取未定义的属性“0”

如何更改此JSFiddle以便它在D3 v4中运行?

2 个答案:

答案 0 :(得分:2)

从D3 v4开始,选择不再是数组数组而是对象。 changelog有它:

  

选择不再使用原型链注入子类化Array;它们现在是普通物体,提高了性能。

在v3中执行self.rectangleElement[0][0]时,您正在访问选择中的第一个节点。要在v4中获取此节点,您需要在self.rectangleElement上致电selection.node()。这样你的代码就变成了:

rect = d3.select(self.rectangleElement.node());

查看已更新JSFiddle的工作版本。

答案 1 :(得分:1)

首先,你为什么要重新选择那些东西?它们已经是您想要的选择。例如,self.rectangleElement是rect的选择。其次,将对象传递给.attr是no longer supported in version 4。第三,拖动行为已经改变,圆圈正在吃你的第二个鼠标。这是我修复这些内容的版本:



d3.select('#rectangle').on('click', function(){ new Rectangle(); });

var w = 600, h = 500;
var svg = d3.select('body').append('svg').attr("width", w).attr("height", h);

function Rectangle() {
    var self = this, rect, rectData = [], isDown = false, m1, m2, isDrag = false;
    
    svg.on('mousedown', function() {
    		console.log(isDown);
        m1 = d3.mouse(this);
        if (!isDown && !isDrag) {
            self.rectData = [ { x: m1[0], y: m1[1] }, { x: m1[0], y: m1[1] } ];
            self.rectangleElement = d3.select('svg').append('rect').attr('class', 'rectangle').call(dragR);
            self.pointElement1 = d3.select('svg').append('circle').attr('class', 'pointC').call(dragC1);
            self.pointElement2 = d3.select('svg').append('circle').attr('class', 'pointC').call(dragC2);            
            self.pointElement3 = svg.append('circle').attr('class', 'pointC').call(dragC3);
            self.pointElement4 = svg.append('circle').attr('class', 'pointC').call(dragC4);
            updateRect();
            isDrag = false;
        } else { 
            isDrag = true;
        }
        isDown = !isDown;   
    })
    
    .on('mousemove', function() {
        m2 = d3.mouse(this);
        if(isDown && !isDrag) { 
            self.rectData[1] = { x: m2[0] - 5, y: m2[1] - 5};
            updateRect();
        } 
    });  
    
    function updateRect() {  
        self.rectangleElement
        		.attr("x", self.rectData[1].x - self.rectData[0].x > 0 ? self.rectData[0].x : self.rectData[1].x)
            .attr("y", self.rectData[1].y - self.rectData[0].y > 0 ? self.rectData[0].y :  self.rectData[1].y)
            .attr("width", Math.abs(self.rectData[1].x - self.rectData[0].x))
            .attr("height", Math.abs(self.rectData[1].y - self.rectData[0].y));  

        var point1 = self.pointElement1.data(self.rectData);
        point1.attr('r', 5)
              .attr('cx', self.rectData[0].x)
              .attr('cy', self.rectData[0].y);        
        var point2 = self.pointElement2.data(self.rectData);
        point2.attr('r', 5)
              .attr('cx', self.rectData[1].x)
              .attr('cy', self.rectData[1].y);
        var point3 = self.pointElement3.data(self.rectData);
        point3.attr('r', 5)
              .attr('cx', self.rectData[1].x)
              .attr('cy', self.rectData[0].y);        
        var point3 = self.pointElement4.data(self.rectData);
        point3.attr('r', 5)
              .attr('cx', self.rectData[0].x)
              .attr('cy', self.rectData[1].y);
    }
    
    var dragR = d3.drag().on('drag', dragRect);
    
    function dragRect() {
        var e = d3.event;
        for(var i = 0; i < self.rectData.length; i++){
            self.rectangleElement
                .attr('x', self.rectData[i].x += e.dx )
                .attr('y', self.rectData[i].y += e.dy );
        }
        self.rectangleElement.style('cursor', 'move');
        updateRect();
    }
    
    var dragC1 = d3.drag().on('drag', dragPoint1);
    var dragC2 = d3.drag().on('drag', dragPoint2);
    var dragC3 = d3.drag().on('drag', dragPoint3);
    var dragC4 = d3.drag().on('drag', dragPoint4);
    
    function dragPoint1() {
        var e = d3.event;
        self.pointElement1
            .attr('cx', function(d) { return d.x += e.dx })
            .attr('cy', function(d) { return d.y += e.dy });        
        updateRect();   
    }   
    
    function dragPoint2() {
        var e = d3.event;
        self.pointElement2
            .attr('cx', self.rectData[1].x += e.dx )
            .attr('cy', self.rectData[1].y += e.dy );
        updateRect();   
    }   
    
    function dragPoint3() {
        var e = d3.event;
        self.pointElement3
            .attr('cx', self.rectData[1].x += e.dx )
            .attr('cy', self.rectData[0].y += e.dy );     
        updateRect();   
    }   
    
    function dragPoint4() {
        var e = d3.event;
        self.pointElement4
            .attr('cx', self.rectData[0].x += e.dx )
            .attr('cy', self.rectData[1].y += e.dy );
        updateRect();   
    }   
    
}//end Rectangle
&#13;
svg {
    border: solid 1px red;
}

rect {
    fill: lightblue;
    stroke: blue;
    stroke-width: 2px;
}
&#13;
<button id='rectangle'>Rectangle</button>
<script src="https://d3js.org/d3.v4.js" charset="utf-8"></script>
&#13;
&#13;
&#13;