D3.js专家讨论了这个JavaScript库的新手如何更轻松地处理看起来很难使用结构的问题。
有一天有人问我如何从头开始学习D3.js。我打趣说,这让我写了一本书来真正学习它。这是一个图书馆的地狱。
大多数人不会走得那么远。他们不需要。大多数人从一个问题开始,找到类似的例子,做一些副本,调整,直到它工作,并最终得到他们不明白的工作可视化。你会很惊讶,很少有人真正了解他们的D3数据如何工作。
但只有1或2个,也许3个关键概念,你必须去理解每个D3的例子......它让我在晚上不停地工作。D3 中的3个关键洞察是什么?
1)数据处理与DOM操作
所有的D3例子分成两部分:数据操作和DOM操作。首先,你准备你的价值观,然后渲染。
你必须通过许多例子来注意发生了什么。推理学习很难。大多数初学者错过了这种模式,这使得D3看起来更加迷惑不解。
我们以D3的文档为例,这是一个具有悬停效果的条形图。
D3的创建者Mike Bostock用43行代码构建了这张图表。他们来了:
这个代码有两部分:数据操作和DOM操作。
博斯托克在这里首先准备好他的数据:
一些尺寸变量(边距,宽度,高度)。
两个缩放比例来帮助进行数据到坐标的转换(x,y)。
加载他的数据集(d3.tsv)并更新他的比例域。
在DOM操作过程中使用比例来计算属性。
在DOM操作部分,他将形状和对象放入SVG中。这是您在浏览器中看到的部分。
D3中的DOM操作通过D3选择发生。他们很像jQuery $(something)。就我个人而言,我喜欢用我的书React + D3v4中描述的React来完成这部分。
这里,博斯托克做了一些事情:
选择<svg>节点(d3.select)。
附加一个<g>带有SVG定位属性(翻译)的分组节点(.append)。
添加一个底部轴<g>,移动它,然后调用d3.axisBottom它。D3有内置的轴生成器。
使用相同的方法添加左轴,但旋转刻度。
在左侧轴上添加文本标签“频率”。
用于selectAll.data虚拟选择.bar节点并附加一些数据,然后为每个新数据值(.enter)添加一个<rect>节点并为其提供属性。
最后一部分是人们迷路的地方。它看起来很神奇。我已经使用了D3多年,它看起来仍然很神奇。
这是一种呈现数据的声明性方法。很好,很难理解。这就是为什么我在React中做到这一点。
您可以将其.enter视为对数据的循环,而后面链接的所有内容.enter都是您的循环体。有点像做data.map(d => append(rect).setManyAttributes())
精明?
2)尺度尺度是D3最通用的概念。他们帮助您在两个不同的空间之间进行翻译 就像数学空间一样。
它们就像你在学校学到的数学功能。一个域使用某种公式映射到一个范围。
域中的彩色形状映射到范围内的颜色。没有这个公式,这使得它成为一个序数量级。
let shapes = d3.scaleOrdinal() .domain(['red triangle', 'orange rectangle', ...) .range(['red', 'orange', ...)一旦你有这个规模,你可以用它来从形状转换到颜色。例如shapes('red triangle')返回'red'。
存在许多不同类型的量表。线性,对数,量化等。您可以想到的任何基本转换都存在。剩下的可以通过编写自定义比例来创建。
您最常使用比例将您的数据值转换为坐标。但其他用例存在。
3)D3布局当然.enter.append看起来很神奇,但D3的布局是D3生态系统的真正意义。他们把你的输入数据,并返回一个全功能的可视化的东西。
但是,关于布局魔术的一个关键洞见是:它们是数据的一部分。
你拿一个forceLayout例子来填充你的数据。它返回一个带有tick事件回调的对象。
var simulation = d3.forceSimulation() .force("link", d3.forceLink().id(function(d) { return d.id; })) .force("charge", d3.forceManyBody()) .force("center", d3.forceCenter(width / 2, height / 2));这simulation现在处理渲染节点的一切。它在每个tick回调中改变其立场。
但是由你来渲染它们。布局处理抽象中的数据。你仍然是控制渲染的人。
对于强制布局,您必须在动画的每个刻度上更新DOM。对于圆形包装,您只需渲染一次。
我花了一段时间才得到这个,但是一旦我做完了,所有看起来很奇怪的可视化开始变得有意义了。
结束总而言之,您需要深入了解D3的3个关键洞察力,才能做到有意义。一旦他们点击,一个全新的世界就会打开。
代码分为数据和DOM操作。
比例很大,用得很多。
你总是在控制渲染。