Migrating from D3.js v3 to D3.js v4 not working - a select issue?

molotofc

I'm trying to migrate this JSFiddle which is in D3 v3 to D3 v4, but it is not working.

I know D3 drag behavior is now simply d3.drag() which I've changed, but when trying to run it, it is giving an error on line 53:

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

with Chrome saying:

Uncaught TypeError: Cannot read property '0' of undefined

How do I go about changing this JSFiddle so it runs in D3 v4?

Mark

First, why are you re-selecting those things? They are already the selection you want. For example, self.rectangleElement is the selection of the rect. Second, passing an object to .attr is no longer supported in version 4. Third, the drag behavior has changed and the circle are eating your second mouse down. Here's a version where I've fixed up these things:

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
svg {
    border: solid 1px red;
}

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

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related