D3.jsV5入门教程

D3.jsV5入门教程

最近一直在开发3D可视化组件,偶尔也开发2D的组件。但是2D我也是用3D的方式开发的,感觉有点浪费。所以打算入手一下D3,毕竟D3还是挺有市场的灵活性非常大,很适合二次开发。

  • d3官网:https://d3js.org/

  • d3案例:https://github.com/d3/d3/wiki/Gallery

  • d3教程:https://github.com/d3/d3/wiki/Tutorials

  • d3 API:https://github.com/d3/d3/blob/master/API.md

  • mbostock案例地址:https://bl.ocks.org/mbostock

  • d3的中文网址:https://d3js.org.cn/

  • observable D3的案例:https://observablehq.com/@d3?tab=collections

  • JQuery之家:SVG系列教程:http://www.htmleaf.com/ziliaoku/qianduanjiaocheng/201507082192.html

  • SVG精髓》 阅读笔记 :https://github.com/xswei/SVG_Essentials

  • SVG 教程 : https://www.nhooo.com/svg/svg-tutorial.html

  • MDN :https://developer.mozilla.org/zh-CN/docs/Web/SVG

  • svg animate :https://developer.mozilla.org/zh-CN/docs/Web/SVG/Element/animate

  • SVG SMIL animation动画详解:https://www.zhangxinxu.com/wordpress/2014/08/so-powerful-svg-smil-animation/

  • SVG颜色渐变动画效果 :http://www.htmleaf.com/ziliaoku/qianduanjiaocheng/201504141680.html

提示:D3的V3-V4-V5版本之间API变化很大,所以自己学习过程要查询最新的API文档,不要盲目复制别人的代码,切记,切记~
重要提示:D3的V3-V4-V5版本之间API变化很大,所以自己学习过程要查询最新的API文档,不要盲目复制别人的代码,切记,切记~

1 安装D3

  1. 通过npm的方式安装:npm install d3 --save,我现在的版本是5.9.2
    然后引入d3 import * as d3 from "d3";

  2. 直接引入<script src="https://d3js.org/d3.v5.min.js"></script>

2 D3数据驱动的文档

d3的主页有个简短的文档,很有必要认真了解一下。

2.1简介

  1. D3允许您将任意数据绑定到文档对象模型(DOM),然后将数据驱动的转换应用于文档。例如,您可以使用D3从数组中生成HTML表。或者,使用相同的数据创建具有平滑过渡和交互的交互式SVG条形图。
    D3不是一个单一的框架,旨在提供所有可能的功能。相反,D3解决了问题的关键:基于数据有效地处理文档。这避免了专有的表示,并提供了非凡的灵活性,暴露了HTML,SVG和CSS等Web标准的全部功能。D3的开销极小,支持大型数据集和交互动画的动态行为。D3的功能风格允许通过各种官方和社区开发的模块重用代码。

2.2选择器

2.3 动态属性

3 制作一个柱状图

从制作一个简单的柱状图开始来理解d3的运行方式。

3.1 绘制柱状图和值

柱状图

  1. 定义两个参数,作为svg的宽和高
  2. 定义一个svg,通过select选择器选择body对象,然后添加一个svg子对象并设置宽高以及背景颜色
  3. 定义一个数组作为数据集
  4. 定义四个参数作为边距
  5. 定义两个参数作为柱状图的宽度和整体间隔(宽度加间隙)
  6. 在svg对象中通过select选择器选择rect,然后绑定数据,通过enter方式后,在添加rect。绘制矩形需要几个默认参数,x,y,width,height,这和canvas类似。这一步难点是数据的绑定。匿名函数中的d是数据集中的数据,i是索引号。这样就绘制了数据集中8个数据,数据的值就是矩形图的高度(暂时没有做映射处理)。
  7. 绘制文字,这个和上面的原理类似,就是注意一下定位问题就ok。

在这个最简单的柱状图中需要重点理解的地方有两个:

  1. 选择器,这是D3的基础之一,和css选择器类似。
  2. 数据绑定。这也是D3的核心之一。需要慢慢体会
const width = 400, height = 400;
const svg = d3.select('body')
    .append('svg')
    .attr('width', width)
    .attr('height', width)
    .style('background-color','lightblue')
var array = [100, 200, 300, 150, 160, 130,80,160]
var padding = { top: 20, right: 20, bottom: 30, left: 40 }
var rectStep = 40;
var rectWidth = 30
svg.selectAll('rect')
    .data(array)
    .enter()
    .append('rect')
    .attr('fill', 'steelblue')
    .attr('x', function (d, i) {
        return padding.left + i * rectStep;
    })
    .attr('y', function (d) {
        return height - padding.bottom - d;
    })
    .attr('width', rectWidth)
    .attr('height', function (d) {
        return d
    })
svg.selectAll('text')
    .data(array)
    .enter()
    .append('text')
    .attr('fill', "white")
    .attr('font-size', '14px')
    .attr('text-anchor', 'middle')
    .attr('x', function (d, i) {
        return padding.left + i * rectStep
    })
    .attr('y', function (d) {
        return height - padding.bottom - d;
    })
    .attr('dx', rectWidth / 2)
    .attr('dy', '1em')
    .text(function (d) {
        return d
    })

3.2 绘制坐标轴

在这里插入图片描述

  1. d3.scaleLinear 创建定量线性比例尺,指定定义域domain和值域range。就是个线性函数。
  2. d3.axisBottom - 创建一个底部轴生成器,作为X轴,
  3. 创建一个组把x轴添加进去

Y轴创建的方式类似不在复述,这样一个最简单的坐标轴就绘制出来了。数据集是个一位数据,所以这个Y轴是有意义的,X轴就没有什么指定意义了。

 var xlinear = d3.scaleLinear()
     .domain([0, 10])
     .range([0, 320])
 var Xaxis = d3.axisBottom()
             .scale(xlinear)        
 var g = svg.append('g')
             .attr('transform',`translate(${padding.left},${height- padding.bottom})`)
 Xaxis(g)  

 var ylinear = d3.scaleLinear()
     .domain([d3.max(array), 0])
     .range([0, d3.max(array)])
 var gy = svg.append('g')
             .attr('transform',`translate(${padding.left},${height- padding.bottom-d3.max(array)})`)
 var yAxis = d3.axisLeft(ylinear);
 yAxis(gy)

3.3 更新数据

更新一组数据,如右边的图所示。因为值没有做映射处理所以Y轴发生了变化。图形边的不合理了。
在这里插入图片描述
简单粗暴的方式就是在更新数据前过remove方法删除整个svg。然后绘制一个新的。这种方式操作简单可行性高啊。

var svg = d3.select('svg');
svg.remove();

第二种方式就是改变指定的矩形的高度。同时也要考虑Y轴的变化,以及数据数量的变化。多了添加柱状图,少了删除柱状图,数据太多了就要考虑改变宽度来摆放更多的数据。总之要做到灵活摆放,合理显示。

进入-更新-退出模式enter-update-exit
在这里插入图片描述

var data = [100, 159, 125, 135, 189, 145, 111, 136, 158, 20, 40, 198]
var colorScale = d3.scaleLinear()
   .domain([0, 200])
   .range(['#666666', '#4682b4'])
function render() {
   var bars = d3.select('body').selectAll('div.h-bar')
       .data(data)
   bars.enter()
       .append('div')
       .attr('class', 'h-bar')
       .merge(bars)
       .style('width', function (d) {
           return d + 'px';
       })
       .style('background-color', (d) => {
           return colorScale(d)
       })
       .text(function (d) {
           return d
       })
   bars.exit().remove()
}
render()
setInterval(() => {
   data.shift()
   data.push(Math.round(Math.random() * 180 + 20))
   render()
}, 1500);
// css样式
.h-bar {
    min-height: 15px;
    min-width: 10px;
    background-color: steelblue;
    margin-bottom: 2px;
    font-size: 11px;
    color: #f0f8ff;
    text-align: right;
    padding-right: 2px;
}

关于Update、Enter、Exit可以看下这篇教程:https://wiki.jikexueyuan.com/project/d3wiki/enterexit.html讲解的很到位。
由于d3的链式操纵,我们可以把三个过程写在一起。
看下面代码,以一个矩形集为案例

  1. 先创建一个rect选择器
  2. 接入新的数据集
  3. 更新数据,就是Update操作,修改已有rect的属性,如果为空,则不会执行任何操作。
  4. enter部分,就是添加新的矩形,
  5. Exit部分,就是数据集中的数据比原来的rect数量还少,就删除多余的rect。
    在这里插入图片描述
    比如之前有3个rect,现在的数据集有6个。那么就会先更新3个,接着创建3个,然后直接退出。
    比如之前有6个rect,现在的数据集有3个。那么就会先更新3个,接着不创建rect,最后删除原来多余的3个rect。

特么今天发现连在一起写有问题还是分开干吧。估计链式的问题。
在这里插入图片描述

3.4 添加动画

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

X01动力装甲

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值