d3 svg path添加文本_数据之美-d3/svg实现孔雀开屏图

292fc07218d8a620bf6c87002bbf0c9a.png

前言

本文章适合有适当d3基础的同学阅读,全程阅读大约30分钟。

阅读前可以了解下:

  • [SVG元素] (Docute)
  • [D3比例尺] (人类身份验证 - SegmentFault)
  • [贝塞尔曲线] (深度掌握SVG路径path的贝塞尔曲线指令 " 张鑫旭-鑫空间-鑫生活)
  • [SVG线性渐变] (SVG 线性渐变)
  • [选择器、数据绑定、元素操作] (D3 v5 学习笔记-1 选择器)

实现效果

因其实现效果如孔雀开屏一般,所以称其为孔雀图

c38413117f8e9215768829aaea9666f5.gif
点我访问​codepen.io

场景描述

小明是一家大型公司的老总,公司旗下有32家子公司。小明想要知道各子公司的成立时间以及公司规模情况,还想分析总公司以及各子公司去年一年的利润额营业额的占比情况,除此之外还想知道有哪些子公司有业务异常情况。

数据准备

  • 方便起见,以下所有的业务主体我们都称为节点,总公司我们称为根节点,子公司我们称为子节点

9bfb3abb2f68558f6b5060000f3c4acd.png
  • 以下数据均为mock数据,只为展示所用,并无实际考究,如有不当,请忽略。

89a1884f4264db474b21821a517f6f9f.png
{
  

画图

  • 初始化画布
  1. 首先我们得有个容器:
<

加点装饰:

// 

2. 在容器中初始化一个 800 x 660 的画布:

const 

3d474a2267cff73603f6abafa9c8fd80.png
初始化的画布
  • 定义全局入场动画

我们期望图表的入场是有一个动画效果的,为了保持统一,我们在全局定义一个动画效果。需要动画的时候只需要.transition(t())就可以。

const 
  • 单圆方法

从实现效果图可以看出,是整个图表的最主要的元素,所以我们这里封装一个单圆方法。

  1. setStyleMap方法:遍历样式对象,给ele元素赋予attr属性值:
/**

2. drawCircle方法:画单个圆,包含6个参数,参数含义参考如下代码注释:

/**
  • 双圆方法

有了单圆方法,我们就可以基于单圆封装一个双圆方法。包含9个参数,参数含义参考如下代码注释:

/**
  • 画根节点

此时我们可以开始画图了,先画根节点,起到一个初始定位的作用。

  1. 常量定义及数据计算。
// 给纵轴留出的左侧距离,以下很多定位需要用到这个常量

2. 调用drawDoubleCircle方法,画根节点。

// h - 1 是为了让根节点底部没有被截掉的感觉

3. 画根节点标签值。

rootNodeG

根节点效果如图:

6ced08e72d6d631f64f70cce4b00973c.png
  • 画子节点

首先思考一下,有了双圆方法,我们要画子节点还缺少什么。

  1. 半径最大最小值的限制,不然无法计算半径比例尺;
  2. 异常子节点波纹动画的扩散距离是需要考虑的,涉及横轴和纵轴两个比例尺的计算;
  3. 纵轴0刻度与根节点的距离,涉及纵轴比例尺的计算;
  4. 三个比例尺的定义,包括横轴比例尺、纵轴比例尺、子节点半径比例尺;
  5. 子节点渐变颜色的设置;
  6. 鼠标hover高亮效果的实现。

我们一个一个解决:

1. 常量定义。

// 子节点半径最大值

2. 根据数据定义三个比例尺。

// 横轴:时间比例尺

3. 定义线性渐变过滤器。

我们这里使用<linearGradient>来定义一个线性渐变,渐变定义在<defs>引用容器中,然后给渐变定义一个id号,在需要赋予颜色的元素上调用此id号即可。

// 颜色值计算

4. 画子节点。

// 定义子节点总容器

效果图如下,异常节点为灰色,其余为渐变色:

a1e9597a415215e13640c298b7a1d048.png

5. 添加异常情况下波纹动画。

/**

遍历画子节点的代码中添加`drawRippleAnimate`方法:

...

效果图如下,异常节点添加了波纹动画:

fc90ff7cbb6ff2baab6e70b3b6efcc4c.png
  • 画连线路径
  1. 定义贝塞尔曲线方法。
/**

2. 画连接路径。

// 定义连线路径容器
此时你会发现一个问题,视觉上连接路径浮在子节点上,所以我们将 连接路径提到 子节点之前画。

9c06f7fdc49ee40439c4e01e5f7a18f3.png
连接路径浮在子节点上
  • 画网格线、刻度、及纵轴标题

1. 常量定义及刻度值计算。

// 定义刻度数量

2. 画网格线及刻度值。

// 定义坐标轴线容器

3. 画纵轴标题。

axisG
同样的道理,这一步再提到 连接路径之前画,防止出现浮在上面的视觉问题。

此时dom结构如下:

a868e3fe854a1b52312dd39abe904798.png

实现效果图如下:

b29dc68d655fee7ca4914db75de629dd.png
  • 添加hover子节点时的高亮效果
/**

遍历画子节点的代码中添加添加drawHoverStyle方法:

...
.each(function (d, index) { // 遍历去画子节点
  ...
  drawHoverStyle(nodeG)
})

尝试一下hover子节点,效果如下:

9866cb9c87ef50c4b8a154c2f880ecce.png

结语

至此我们就逐步实现了这个图表,此图表的优势在于:展示多维度的数据并且不失美观,感兴趣同学可以画起来哦,如有不明确或不合理的地方,欢迎留言指正。

https://codepen.io/sienhang/pen/wLgNeK​codepen.io
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ERROR Failed to compile with 48 errors 上午10:53:54 These dependencies were not found: * core-js/modules/es.array.push.js in ./node_modules/.store/@[email protected]/node_modules/@babel/runtime/helpers/esm/objectSpread2.js, ./node_modules/.store/[email protected]/node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/.store/[email protected]/node_modules/babel-loader/lib!./node_modules/.store/[email protected]/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/.store/[email protected]/node_modules/vue-loader/lib??vue-loader-options!./src/components/HeaderSearch/index.vue?vue&type=script&lang=js& and 29 others * core-js/modules/es.error.cause.js in ./node_modules/.store/@[email protected]/node_modules/@babel/runtime/helpers/esm/regeneratorRuntime.js, ./node_modules/.store/[email protected]/node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/.store/[email protected]/node_modules/babel-loader/lib!./node_modules/.store/[email protected]/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/.store/[email protected]/node_modules/vue-loader/lib??vue-loader-options!./src/layout/components/Navbar.vue?vue&type=script&lang=js& and 5 others * core-js/modules/es.object.proto.js in ./node_modules/.store/@[email protected]/node_modules/@babel/runtime/helpers/esm/regeneratorRuntime.js * core-js/modules/es.regexp.dot-all.js in ./node_modules/.store/[email protected]/node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/.store/[email protected]/node_modules/babel-loader/lib!./node_modules/.store/[email protected]/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/.store/[email protected]/node_modules/vue-loader/lib??vue-loader-options!./src/components/ThemePicker/index.vue?vue&type=script&lang=js&, ./node_modules/.store/[email protected]/node_modules/cache-loader/dist/cjs.js??ref--12-0!./node_modules/.store/[email protected]/node_modules/babel-loader/lib!./node_modules/.store/[email protected]/node_modules/cache-loader/dist/cjs.js??ref--0-0!./node_modules/.store/[email protected]/node_modules/vue-loader/lib??vue-loader-options!./src/layout/components/Navbar.vue?vue&type=script&lang=js& and 2 others * core-js/modules/web.url-search-params.delete.js in ./src/utils/request.js * core-js/modules/web.url-search-params.has.js in ./src/utils/request.js * core-js/modules/web.url-search-params.size.js in ./src/utils/request.js * qs in ./src/utils/request.js * svg-baker-runtime/browser-symbol in ./src/icons/svg/user.svg To install them, you can run: npm install --save core-js/modules/es.array.push.js core-js/modules/es.error.cause.js core-js/modules/es.object.proto.js core-js/modules/es.regexp.dot-all.js core-js/modules/web.url-search-params.delete.js core-js/modules/web.url-search-params.has.js core-js/modules/web.url-search-params.size.js qs svg-baker-runtime/browser-symbol怎么解决如何安装
07-21

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值