简体   繁体   English

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

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

I'm trying to migrate this JSFiddle which is in D3 v3 to D3 v4, but it is not working. 我正在尝试将D3 v3中的这个JSFiddle迁移到D3 v4,但它无法正常工作。

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

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

with Chrome saying: 与Chrome说:

Uncaught TypeError: Cannot read property '0' of undefined 未捕获的TypeError:无法读取未定义的属性“0”

How do I go about changing this JSFiddle so it runs in D3 v4? 如何更改此JSFiddle以便在D3 v4中运行?

As of D3 v4 a selection no longer is an array of arrays but an object. 从D3 v4开始,选择不再是数组数组而是对象。 The changelog has it: 更改日志有:

Selections no longer subclass Array using prototype chain injection; 选择不再使用原型链注入子类化Array; they are now plain objects, improving performance. 它们现在是普通物体,提高了性能。

When doing self.rectangleElement[0][0] in v3 you were accessing the first node in a selection. 在v3中执行self.rectangleElement[0][0] ,您正在访问选择中的第一个节点。 To get this node in v4 you need to call selection.node() on self.rectangleElement . 要在v4中获取此节点,您需要在self.rectangleElement上调用selection.node() With this your code becomes: 有了这个你的代码变成:

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

Have a look at the updated JSFiddle for a working version. 看看更新的JSFiddle的工作版本。

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. 例如,self.rectangleElement是rect的选择。 Second, passing an object to .attr is no longer supported in version 4 . 其次, 在版本4中不再支持将对象传递给.attr。 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 dx += e.dx }) .attr('cy', function(d) { return dy += 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> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM