2
头图

背景

本篇收录于《数据可视化和图形学》专栏

上文介绍了纹理相关的内容,并使用WebGL进行了3d的实现,emm.....
本篇文章呢算是一个新方向,也算探索写作的一个思路。(应着群内小伙伴的需求来讲讲框架的日常使用) 当然理论知识肯定是依旧会穿插进来。

写作方式会从学习(调研),使用,深入进行混讲。 其实就是我日常使用某一个(框架)库的基础流程分享出来希望帮助到大家。

在开始前简单介绍下今天的主角D3JS(下面简称D3)

  • D3全称 Data-Driven Documents 3个D开头的单词也是它D3简写的由来(不要有的人用了半天不知道这名字怎么来的 不要当假粉 哼~)
  • D3的优势 :

    1. 明星级别库毋庸置疑 github的star 将近98k。那么可想而知用户 社区必然是完备的。
    2. D3是灵活的 各模块可拆分可组合。
    3. 渲染方面设计优秀,关注的是shape,scale基础图元。不是特定图表的配置化。这样灵活性更高
    4. animation(动画),interaction(交互)效果很优秀。
    5. 支持多种渲染模式,svg,canvas 很多...
  • 图表种类,图表示例很全很全,所以日常开发可能都不需要基础模块的组合 示例教程在Observable
今天对于如何学习D3,使用D3,深入D3做一次浅显的探讨。 follow me!

本篇大纲

  1. 学习库阶段(调研阶段)
  2. 使用库阶段(日常开发阶段)
  3. 深入库阶段(学习框架,或者新需求在框架源码上进行定制化。)

学习库(调研库)

从几个方面进行调研考察

  1. 首先看库是否满足业务开发和业务拓展
  2. 看下该库更新的一个频率,稳定性问题。( 当然有实力团队也可以clone一份当前使用版本,方便后续的维护。)
  3. 该库社区是否活跃 方便后续问题探讨跟进 (如果team有足够示例 可以不care这点)
  4. 对于是否与现有主框架(主要技术栈)兼容问题,这个如果一个库满足以上几点。应该问题不大(也可以列入考察中)

按上述步骤看看D3怎么说

1.首先看库是否满足业务开发和业务拓展

D3支持SVG(HTML)/Canvas的渲染模式,简单来说一些适合的抽象业务场景

  • 日常图表开发种类丰富,有关系类,统计类,简单地图类...
  • 数据量大但是属于静态类分析(只加载一次)可选择SVG渲染
  • 数据量大而且属于高频交互 可以选择Canvas渲染(如果数据量海量。从交互,渲染等方面优化 甚至需要换渲染方式)
  • 图表渲染前,中,后需要酷炫的动画效果。
  • ...
第2,3点问题呢 贴几个图吧
commit的一个情况和issues反馈情况

image.png

image.png


从成员以及提交曲线来看(截图不全 可以去github查看 还有这个是近一年的,可能不太准 bug太少了哈哈)

image.png

使用库阶段(日常开发阶段)

存在几种情况

  1. 有现成的例子且完全满足开发需求
  2. 无现成的例子但是可以通过几个例子混合使用达到效果
  3. 自己动手利用API使用 并深入研究,在库不满足需求情况下进行定制化开发。
首先很多人都处于第1种和第2种情况一直徘徊.这个原因说直白点还是代码搬运工的水平. 当然这个更多属于深入模块 只有知道它是什么才能发挥更大的优势。这方面的分享可能目前来说较少
拿一个图表来做示例。

image.png
实现上图只需要下面几个步骤

  • 需要限制画布的一些属性,宽高
  • 需要绘制2个刻度尺, 通过数据计算min,max
  • 需要绘制柱状图形 ,数据绑定
需要限制画布的一些属性,宽高

var  width = 1000;
var  height = 500;
var  margin = ({
    top:20,
    right:0,
    bottom:30,
    left:40
})
const  svg = d3.select("body").append("svg");
需要绘制2个刻度尺。
var x = 
d3.scaleBand()
    .domain(data.map(d=>d.name))
    .range([margin.left,width-margin.right])
    .padding(0.2)

var y = 
d3.scaleLinear()
    .domain([0,d3.max(data,d=>d.value)]).nice()
    .range([height - margin.bottom,margin.top])        
    
svg.append("g")
    .attr("class","x-axis")
    .attr("transform",`translate(0,${height- margin.bottom})`)
    .call(d3.axisBottom(x).tickSizeOuter(0))
    // 设置x轴刻度


svg.append("g")
    .attr("class","y-axis")
    .attr("transform",`translate(${margin.left},0)`)
    .call(d3.axisLeft(y))  //y轴坐标刻度
需要绘制柱状图形
svg.append("g")
    .attr("class","bars")
    .attr("fill","skyblue")
    .selectAll("rect")
    .data(data)
    .join("rect")
    .attr("x",d=>x(d.name))
    .attr("y",d=>y(d.value))
    .attr("width",x.bandwidth())
    .attr("height",d=>y(0) - y(d.value))


上面这个简单的例子可以反映出来你使用D3的基本流程 首先你要明白你的画布是如何限制的。然后呢你要想你画什么。 其次就是把数据对应的加上去。
当然很重要的一点要学习它的语法 转变你编码的思维。 非结构化的编程过程。

深入库阶段(学习框架,或者新需求在框架源码上进行定制化。)

首先先不考虑进行定制化开发,本篇首先去了解下它内部的实现。

image.png

打开D3的仓库,阅读源码你会发现这个情况

  1. d3-array 数组
  2. d3-axis 坐标轴
  3. d3-brush
  4. d3-color 颜色
  5. ...

其实这个跟它的设计是有关系的。是把能拆的部分尽可能的拆出来,这样的优势在于你如果想与目前使用的库进行一些整合,非常简单。这也是D3火的原因。本篇不打算拆开具体模块进行展开。基本我目前用到的可能 drag(拖拽计算), quadtree(四叉树) 还有一些layout算法... 其实也并不是很多。有兴趣可以留言 专门拿出几篇来写这个《讨论如何在底层进行定制化》。

友情链接

最后

关于图形学/数据可视化,怎么学习的方向问题呢,我也属于摸索。或许等我写完这个系列能够更好的解答大家。

请大家多提提意见,不吝赐教指正。 有任何希望分享的地方只要我了解或者我可以学来分享。 (当然学不会肯定不会丢人现眼的呢 哈哈)

wlove
6.9k 声望1.8k 粉丝

wx:wywin2023