d3根据数据绘制不同的形状
2018-06-24 00:40:54来源:未知 阅读 ()
绘制力导向图的时候通常节点都是圆形,但也会遇到公司节点绘制成圆型,人绘制成方形的情况,那我们怎么依据数据绘制不同的形状。
你可能首先会想到,这很简单啊,是公司的时候append circle,是人的时候append rect。但是append并没有提供回调也就是说我们不能这样做。
node.append((data)=>{ return data.type === 'person' ? 'rect' : 'circle'; });
下面介绍两种方案:
第一种,先append一个g然后根据数据设置不同的类名
var nodeGUpdate = this.nodeG .selectAll('g') .data(this.nodesData, (data) => data.id);
var nodeGEnter = nodeGUpdate.enter(); var nodeGExit = nodeGUpdate.exit(); // 更新 nodeGUpdate
.transition() .attr('class', (data) => { return (data.hide && 'hide') || (data.nodeStatus < 0 && 'noActive') || (data.cateType === 0 && 'mainCompany') || (data.cateType === 1 && 'relativeCompany') || (data.cateType === 2 && 'relativePerson'); }) nodeGEnter.append('g')
.attr('class', (data)=> { return data.cateType === 2 ? 'person' : 'company'; })
然后依据类名append不同形状
添加矩形
this.nodeG .selectAll('.person') .append('rect') .attr('class', (data) => { return (data.hide && '.hide') || (data.cateType === 0 && 'mainCompany') || (data.cateType === 1 && 'relativeCompany') || (data.cateType === 2 && 'relativePerson'); }) .attr('width', 20) .attr('height', 20);
添加圆形
this.nodeG .selectAll('.company') .append('circle') .attr('class', (data) => { return (data.hide && '.hide') || (data.cateType === 0 && 'mainCompany') || (data.cateType === 1 && 'relativeCompany') || (data.cateType === 2 && 'relativePerson'); }) .attr('r', 20);
最后效果
这有点尴尬,矩形是以它自身的左上角的为基点,所以你可能还需要根据象限进行平移。
上面这种思路是我从其它文章看来的,但出处忘了,但是由于还要将矩形的中心移到线的端点太麻烦,所以最终没有采用这种方法。
下面来讲另外一种方法
整体思路是统一append circle 但是当是人的时候填充圆形。就是可以想象append的这个circle相当于一个透明的画布,如果fill的值是颜色,那就是用这个颜色去填充这个圆。如果fill的是一个形状,就是用这个形状填充,由于背景是透明的,所以看起来好像append了其它形状上去。
首先在svg中定义一个矩形,defs简单来说就是一个容器,在这个元素里面你可以定义一些元素供你重复使用,例如箭头和这里定义的矩形。
这里有几个地方需要注意:
矩形 x,y的值
x,y是矩形的左上角相对于圆形的位置,设置x,y的值将矩形移至圆的中心,这样才能确保线的端点指向矩形的中心。
计算公式是 x=y = r - 矩形宽度 / 2
确保矩形小于圆的内切正方形
打个比方,如果你透过一个圆形孔看一个较小的红色正方形,你会看到一个个完整的正方形,但如果正方形过大,你可能就只能看到一个红色的圆形了。
所以正方形宽度推导公式就是 width < 2*r / √2
<svg width="1000" height="1000"> <defs> <pattern id="person" patternUnits="objectBoundingBox" width="1" height="1"> <rect x="10" y="10" width="20" height="20" fill="#7FBBA1" stroke="#5CA083"/> </pattern> </defs> </svg>
确保圆是透明的
通俗点讲就是用于填充矩形的圆的样式中不能在设置fill和stroke了
然后在绘制圆形的地方引用
nodeEnter .append('circle') .attr('class', (data) => { return (data.hide && '.hide') || (data.cateType === 0 && 'mainCompany') || (data.cateType === 1 && 'relativeCompany') || (data.cateType === 2 && 'shape-relativePerson'); }) .attr('r', 20) .attr('fill', (data)=>{ return data.cateType === 2 ? 'url(#person)' : ''; })
下面是结果图
当然你可以扩展,例如如果是人的话绘制一个人的图片
<pattern id="person" patternUnits="objectBoundingBox" width="1" height="1"> <image href={user} width="20" height="20" x="10" y="10"/> </pattern>
效果如图
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:微信小程序购物车-多商家-多商品
下一篇:如何线上部署node.js项目
- 如何用javascript连接access数据库 2020-03-20
- 根据分辨率调用css文件的方法 2020-03-19
- 如何用算法删除重复数据 2020-03-18
- JavaScript中双向数据绑定详解 2020-03-05
- js插件实现图片滑动验证码 2020-01-17
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash