d3.js实现多个元素的同时拖拽效果
需求是画公司与人员的关系,用圆圈表示公司或者人员,然后在圆圈内容通过文本写上公司和人员的名称。然后鼠标拖拽圆圈的时候,圆圈要和文本一起同步移动。
不同的元素怎么移动?
圆圈Circle可以通过修改其cx、cy属性移动,也可以通过transform进行移动。
文本Text可以通过修改其x、y属性移动,也可以通过transform进行移动。
如何理解相对定位与绝对定位?
这是移动SVG元素的关键。
要把其参考的定位参照物搞清楚。
如何给SVG的元素设置样式?
一句话经验
SVG的定位属性不可以直接在控制台调整查看效果
最耗费时间的有3个点:
- 编程思路不清晰
- 对D3的API不熟悉
- 见少识窄
【精】联动思维
比如拖拽,其实我只需要直接操纵圆圈就行了,然后把其他相关元素的操作,用单独的函数封装起来,通过圆圈的数据变更来触发。
这个思维可以做出很多炫酷的效果,比如旋转的时钟、抖动等等。
常见问题
不知道效果该怎么实现
可以从D3的Demo网站上,找别人实现的类似案例,参考他们的思路。
用D3实现炫酷效果的核心在于想法和思路,这需要多看、多思考才能提升。
能不能通过给g设置transform属性来移动里面的所有元素?
可以,这也是最优的方案。
使用这种方案的时候,注意g里面的元素,不要给其设置x、y信息。
为什么用g包裹circle和text后,circle定位正常,text不正常了?
应为我给text下面的tspan单独设置了x、y属性。
去掉这个属性就可以了。
x、y、dx、dy有什么区别?
x和y规定的是字符的绝对定位,dx和dy规定字符的相对定位。
相对定位,是针对该元素自身在文档常规流(Nomal Flow,即postion:static)中的原始位置来定位的。
也就是说,dx和dy是相对该元素自己的x、y进行平移的, 经过平移,起始位置会变成x+dx、y+dy。
比如有如下结构:
1 | |
你给A和B都设置dx=10, dy=10,由于按照自动的布局,B应该位于A的右侧,那么经过相对定位之后,实际上A的坐标会变成(10, 10),B的坐标会变成(20, 20)
这种情况建议设置x、y属性更好,因为x和y是相对text的定位,更容易控制。
TODO:这里有个地方我没弄明白,即绝地定位的参照物问题。
因为无论是text还是外面的g,都没有指定position,其position值都是static,按理说这种情况,是不能作为tspan的定位参照物的,那tspan的x和y到底是参照了哪个元素呢?
圆圈中的文本的位置怎么定位才能居中、还有换行?
通过给text内部添加tspan来解决,可以将tspan简单理解为常规DOM中的span。