绘制力导向图的时候通常节点都是圆形,但也会遇到公司节点绘制成圆型,人绘制成方形的情况,那我们怎么依据数据绘制不同的形状。

你可能首先会想到,这很简单啊,是公司的时候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>

效果如图

d3根据数据绘制不同的形状的更多相关文章

  1. d3 根据数据绘制svg

    , , , , ]; var circles = svg.selectAll("circle") .data(dataset) .enter() .append("cir ...

  2. d3.js:数据可视化利器之快速入门

    hello,data! 在进入d3.js之前,我们先用一个小例子回顾一下将数据可视化的基本流程. 任务 用横向柱状图来直观显示以下数据: var data = [10,15,23,78,57,29,3 ...

  3. 如何将内存中的位图数据绘制在DC上

    假如你定义了一个位图类,里面包含位图头,位图信息头,调色板,位图数据.然后你按照位图的格式将位图文件读入你的类中,现在你知道了位图的全部信息了.主要信息包含在位图信息头里面,数据则在位图数据缓冲里面. ...

  4. Highcharts使用CSV格式数据绘制图表

    Highcharts使用CSV格式数据绘制图表 CSV(Comma-Separated Values,逗号分隔值文本格式)是採用逗号切割的纯文本数据.通常情况下.每一个数据之间使用逗号切割,几个相关数 ...

  5. linux环境安装nagiosgraph将nagios的性能数据绘制成动态图表?

    需求描述: 在安装完成nagios之后,比如有监控磁盘负载信息的,连接数的,进程数的,可以通过安装nagiosgraph软件, 将nagios的性能数据绘制成图表,可以看到一段时间内数据的变化 环境说 ...

  6. Highcharts使用表格数据绘制图表

    Highcharts使用表格数据绘制图表 在Highcharts中,同意用户使用网页中现有的表格数据作为数据来源,然后依据该数据来源绘制图表.对于一个典型的HTML表格.当中,第一列的数据会作为x轴刻 ...

  7. WPF 自定义的图表(适用大量数据绘制)下

    原文:WPF 自定义的图表(适用大量数据绘制)下 上一篇文章中讲了WPF中自定义绘制大量数据的图标,思路是先将其绘制在内存,然后一次性加载到界面,在后续的调试过程中,发现当数据量到达10W时,移动鼠标 ...

  8. WPF 自定义的图表(适用大量数据绘制)

    原文:WPF 自定义的图表(适用大量数据绘制) 在WPF中绘制图表比较简单,有很多的第三方控件,但是在绘制大量数据的时候,就显得有些吃力,即便是自己用StreamGeometry画也达不到理想的效果, ...

  9. 使用d3.v3插件绘制出svg图

    众所周知,这个插件使用的svg技术,而IE8(包括IE8)之前的浏览器是不支持svg的 接下来看代码吧 从后台获取到带id和父id的目录数据[json格式] var module = requestU ...

随机推荐

  1. SQL Server 2000 sp2 及更低版本不受此版本的 Windows 支持

    SQL Server 2000 sp2 及更低版本不受此版本的 Windows 支持.在安装了 SQL Server 2000 之后请应用 sp3. 出现这种现象的原因在于:Windows Serve ...

  2. ubuntu15.10下编译安装wine1.8 rc4

    ubuntu15.10下编译安装wine1.8rc4 Wine (“Wine Is Not an Emulator” 的递归缩写)是一个能够在多种 POSIX-compliant 操作系统(诸如 Li ...

  3. PMP 第九章 项目人力资源管理

    1制定人力资源计划 2组建项目团队 3建设项目团队 4管理项目团队 1.规划人力资源管理的作用是什么?组织图和职位描述的表现形式有哪些?RAM和RACI的关系是什么?人力资源管理计划的内容有哪些? 人 ...

  4. CodeIgniter中驱动器的使用方法

    驱动器“Drivers”是CodeIgniter框架从2.0版本开始加入的新特性.正如中文版译者所言: 笔者看了这三篇英文参考,加上自己的一些理解,对官方文档关于驱动器的这一部分进行了一些补充. 1. ...

  5. asp.net下载文件方法

    /// <summary> /// 下载 /// </summary> /// <param name="url"></param> ...

  6. DOS命令解释程序的编写

    实验一.DOS命令解释程序的编写 专业:物联网工程   姓名:黄淼  学号:201306104145 一. 实验目的 (1)认识DOS: (2)掌握命令解释程序的原理: (3)掌握简单的DOS调用方法 ...

  7. centos6.5 安装jdk7和tomcat7

    JDK安装: 安装说明 系统环境:centos-6.5安装方式:rpm安装软件:jdk-7-linux-x64.rpm下载地址:http://www.oracle.com/technetwork/ja ...

  8. FCKeditor

    FCKeditor是一个专门使用在网页上属于开放源代码的所见即所得文字编辑器.它志于轻量化,不需要太复杂的安装步骤即可使用.     它可和PHP.JavaScript.ASP.ASP.NET.Col ...

  9. CSS中清除浮动的方法

    CSS浮动,最早是为了达到文字环绕的效果提出的,也可以用来做布局,但是布局会产生很多问题(高度塌陷,漂浮在普通流上),会使当前标签产生上浮的效果,会影响前后标签,同样的代码在不同的浏览器的兼容性也不一 ...

  10. python+NLTK 自然语言学习处理二:文本

    在前面讲nltk安装的时候,我们下载了很多的文本.总共有9个文本.那么如何找到这些文本呢: text1: Moby Dick by Herman Melville 1851 text2: Sense ...