>在本文中,我想带您完成我最近构建的示例项目 - a完全原始的使用D3库的可视化类型,该类型展示了这些组件中的每个组件如何累加以使D3一个很棒的图书馆。
D3代表数据驱动的文档。这是一个JavaScript库,可用于制作各种出色的数据可视化和图表。>如果您曾经看过《纽约时报》中的任何出色的互动故事,那么您已经看到了D3的行动。您还可以在此处查看使用D3构建的一些很棒的项目。
>
>有三个主要因素确实使D3在那里的任何其他库中脱颖而出:调整通货膨胀时,尽管每工业生产力一直在飙升,但家庭收入在40%的社会中保持了几乎恒定的。它确实是最高的20%,它获得了更多的好处(在该括号内,如果您看着前5%的前5%,那么差异更加令人震惊)。
这是我想以令人信服的方式传播的信息,这为使用一些D3.js提供了绝佳的机会,所以我开始绘制一些想法。>
素描。制作简单的线图,条形图或气泡图非常容易,但是我想做一些不同的东西。 >我发现人们倾向于用作对不平等问题的担忧的最常见类比是“如果馅饼变大,那么还有更多事情要解决”。直觉是,如果GDP的总份额在很大程度上增加了,那么即使有些人获得了pie的较薄
,但它们仍然会更好地> 🎜>。但是,正如我们所看到的,馅饼完全有可能变得更大和让人们总体上变得更少。 我可视化这些数据的第一个想法看起来像这样:
的想法是,我们将拥有此脉动饼图,每个切片代表美国收入分配的五分之一。每个派片的面积与该人口的收入收入有关,图表的总面积将代表其总GDP。
但是,我很快遇到了一些问题。事实证明,人的大脑在区分不同区域的大小方面非常差。当我更具体地将其映射出来时,该消息并没有像应该如此明显的地方:
这是在实践中最终寻找的方式:
但是,我致力于做出独特的可视化,我想将此消息锤回回家,即
pie 可以得到更大的> ,而ashare> share>它可以得到较小的。现在我有了我的主意,是时候用D3构建它了。>
>借用代码。 >您可能会认为我会从头开始编写我的前几行代码行,但是您错了。这是D3,由于我们正在与D3合作,因此我们总是可以从社区中找到一些预先编写的代码,以使我们脱颖而出。>
>我们正在创建全新的东西,但是它与常规饼图有很多共同点,因此我快速查看了bl.ocks.org,我决定使用Mike Bostock的经典实施, D3的创造者之一。该文件可能已经复制了数千次,而写它的人是带有JavaScript的真正向导,因此我们可以确定我们已经从一个不错的代码开始了。此文件写在D3 V3中,该文件现在已经过时了两个版本,因为版本5最终在上个月发布。 D3 V4的一个很大的变化是,库切换到使用平坦的名称空间,因此比例功能诸如d3.scale.ordinal()的编写一样,就像d3.scaleordinal()相反。在版本5中,最大的更改是,数据加载函数现在是按照承诺构造的,这使得更容易一次处理多个数据集。
> 为了避免混乱,我已经遇到了创建此代码的更新V5版本的麻烦,我已将其保存在blockbuilder.org上。我还将语法转换为适合ES6惯例,例如将ES5匿名函数切换到箭头函数。这是我们已经开始的:
>
然后,我将这些文件复制到我的工作目录中,并确保我可以在自己的计算机上复制所有内容。如果您想自己跟随本教程,那么您可以从我们的GitHub仓库中克隆该项目。您可以从文件启动器.html中的代码开始。请注意,您将需要一台服务器(例如该服务器)来运行此代码,因为它依赖于Fetch API检索数据。
>让我快速介绍此代码的工作原理。
浏览我们的代码
首先,我们在文件顶部声明了一些常数,我们将使用该常数来定义饼图的大小:
>这使我们的代码超级重复使用,因为如果我们想使其更大或更小,那么我们只需要担心在此处更改这些值。
>
接下来,我们将SVG画布附加到屏幕上。如果您对SVG的了解不多,那么您可以将画布视为我们可以绘制形状的页面上的空间。如果我们尝试在该区域之外绘制SVG,那么它根本不会出现在屏幕上:
<span>const width = 540; </span><span>const height = 540; </span><span>const radius = Math.min(width, height) / 2; </span>>我们正在用图表区域的ID抓住一个空的DIV,并致电D3.Select()。我们还使用d3.append()方法将SVG画布附加,并且使用d3.attr()方法为其宽度和高度设置了一些尺寸。
>我们还将SVG组元素附加到此画布上,这是一种特殊类型的元素,我们可以将其用于将元素构造在一起。这使我们可以使用组元素的转换属性将整个可视化转移到屏幕的中心。
之后,我们正在设置一个默认量表,我们将使用该量表来为我们的派的每一个分配新颜色:>
接下来,我们有几行设置了D3的派布局:
<span>const svg = d3.select("#chart-area") </span> <span>.append("svg") </span> <span>.attr("width", width) </span> <span>.attr("height", height) </span> <span>.append("g") </span> <span>.attr("transform", <span>`translate(<span>${width / 2}</span>, <span>${height / 2}</span>)`</span>); </span>转换的数组
,然后我们可以用。 然后,我们需要定义一个可以用来绘制弧的路径生成器。路径生成器允许我们在Web浏览器中绘制路径SVG。 D3真正要做的就是将数据与屏幕上的形状相关联,但是在这种情况下,我们要定义更复杂的形状,而不是简单的圆或正方形。路径SVG通过定义在之间绘制线路的路由来工作,我们可以使用其D属性来定义。
这可能是:<span>const color = d3.scaleOrdinal(["#66c2a5", "#fc8d62", "#8da0cb","#e78ac3", "#a6d854", "#ffd92f"]); </span>>
d属性包含一个特殊的编码,可以让浏览器绘制我们想要的路径。如果您真的想知道此字符串的含义,则可以在MDN的SVG文档中找到它。对于D3中的编程,我们实际上不需要了解此特殊编码的任何信息,因为我们的发电机会为我们吐出D属性,我们只需要使用一些简单的参数来初始化。 对于弧线,我们需要为我们的路径发生器一个Innerradius和像素中的外段值,并且发电机将分类为我们计算每个角度的复杂数学:
>对于我们的图表,我们为Innerradius使用了零值,这为我们提供了标准的饼图。但是,如果我们想绘制甜甜圈图,那么我们要做的就是插入一个小于我们的outerradius值的值。
<span>const pie = d3.pie() </span> <span>.value(d => d.count) </span> <span>.sort(null); </span>>
>几次函数声明后,我们将使用d3.json()函数加载数据:
>
>使用此行,我们将在单击我们的一个无线电按钮时切换我们正在查看的数据:
>首先,我们使用默认函数参数作为值。如果我们将参数传递到我们的update()函数(当我们第一次运行时),我们将使用该字符串,否则我们将从单击事件中获得所需的值我们的无线电输入。
>每次我们的可视化更新时,这都会将新的数据与我们的SVG在屏幕上关联。我们将数据(“苹果”或“橙色”的数组)传递到我们的PIE()布局函数中,该功能正在计算一些开始角度和端角,可用于绘制我们的弧线。现在,此路径变量包含屏幕上所有弧的特殊 。
接下来,我们将更新数据数组中仍然存在的屏幕上的所有SVG。我们在此处添加了一个过渡 - D3库的绝妙功能 - 传播这些更新超过200毫秒: >我们在d3.transition()呼叫上使用attrtwien()方法来定义D3应使用的自定义过渡,以更新其每个ARC的位置(使用D属性过渡)。如果我们试图将过渡到大多数属性添加过渡,但是我们需要这样做,但是我们需要这样做以在不同的路径之间过渡。 D3无法真正弄清楚如何在自定义路径之间过渡,因此我们使用Arctween()函数来让D3知道如何在每时每刻都应绘制我们的每条路径。 这是此功能的样子: 我们在此处使用d3.interpaly()来创建所谓的插装器。当我们调用我们存储在I变量中的函数,值在0到1之间,我们将获得一个介于此之间的值。_current和a。在这种情况下,this._current是一个包含我们正在查看的PIE切片的开始和末端角度的对象,A表示我们正在更新为。
>
>
适应代码 >现在我们在本地环境中有一些代码,并且我们了解它在做什么,我将切换我们正在查看的数据,以便它可以与我们感兴趣的数据一起使用。 >我已经包含了我们将在项目的数据/文件夹中使用的数据。由于此新的incomes.csv文件这次是CSV格式(这是可以使用Microsoft Excel打开的文件),因此我将使用d3.csv()函数,而不是D3.json( )函数: 此函数基本上与D3.json()基本相同 - 将我们的数据转换为我们可以使用的格式。我还将type()initializer函数作为这里的第二个参数删除,因为这是我们旧数据的特定于。
>
为了解决此问题,我将添加一个称为repardata()的新函数以替换我们以前拥有的type()函数,该功能将在加载时迭代我们的每个数据: >每年,此功能将返回具有值数组的对象,我们将将其传递到我们的数据加入中。我们将这些值中的每一个都标记为名称字段,并且根据我们已经拥有的收入价值,我们为它们提供了数值。我们还在跟踪比较每年的平均收入。 >在这一点上,我们的数据格式可以使用: >我将在数据中的第一年生成图表,然后我会担心在剩下的几年中更新它。 >目前,我们的数据始于2015年,在1967年结束,因此我们需要扭转此数组,然后才能做其他任何事情: 与普通饼图不同,对于我们的图形,我们要固定每个弧的角度,并且随着可视化更新的变化,半径更改。为此,我们将更改PIE布局上的Value()方法,以便每个派slice始终具有相同的角度: input >一旦我们可以访问数据,我们就会添加这个量表,我们说我们的投入应在0到我们数据集中最大的价值之间,这是去年最富有的群体的收入在我们的数据中(数据[49]。值[4]。值)。对于域,我们设置了我们的输出值应范围的间隔。
请注意,我们还在此处使用 。我们这样做的原因是,我们希望我们的馅饼切片区域与每个小组的收入成正比,而不是半径。由于区域=πr2>,我们需要使用平方根刻度来解释这一点。
然后,我们可以使用此量表来更新Update()函数中的ARC Generator的Outerradius值:
>
使事情更有用。我还将添加一些标签,这些标签为我们提供了原始数字。我将用以下方式替换文件正文中的所有HTML代码
然后,每当我们的数据更改时,我将使用jQuery更新所有这些: >我还将对我们文件顶部的CSS进行一些编辑,这将为我们提供每个弧的传奇,并以我们的标题为中心:
(join/exit/exit/extim/update/enter)。 >
>然后,我将在UPDATE()函数的末尾更新此版本。
>我应该注意,对于我们来说,在我们的第一个call to Update()之后,添加每个圆圈 >我们的弧路径(SVG层取决于将它们添加到屏幕的顺序,而不是通过其z索引)。
使其互动
play/暂停
>每当我们的按钮单击时,我们的if/else block在这里将定义不同的行为,具体取决于我们的按钮是“播放”按钮还是“暂停”按钮。如果我们单击的按钮说“播放”,我们将按钮更改为“暂停”按钮,然后开始我们的间隔循环。另外,如果按钮是“暂停”按钮,我们将其文本更改为“ play”,我们将使用clearInterval()函数来阻止循环运行。 对于我们的滑块,我想使用jQuery UI库随附的滑块。我将其包含在我们的HTML中,并且我将写几行以将其添加到屏幕上: >我们可以在Update()函数末尾添加此行,以便我们的滑块移动到我们的循环运行时正确的一年:
>我将向我们的CSS扔几行,以使一切看起来有些整洁: 希望,本教程展示了D3的真实力量,让您绝对创建任何您可以想象的东西。 >从头开始始终是一个艰难的过程,但是奖励值得。如果您想学习如何创建自己的自定义可视化,这里有一些在线资源,您可能会发现有帮助: > D3与其他JavaScript库有何不同?之所以独特,是因为它使您可以灵活地创建其他库无法使用的数据可视化。它使您可以直接操纵DOM,这意味着您可以完全控制可视化的最终外观。 D3还使用声明的方法,这意味着您定义了想要最终结果的外观,而D3算出了如何到达那里。 > d3提供了几种将交互性添加到可视化的方法。您可以使用事件侦听器响应诸如点击或鼠标运动之类的用户操作,并且可以使用过渡来对数据进行动画更改。 D3还支持缩放和平移,这对于探索大型数据集可能很有用。 我是否需要知道JavaScript来使用D3? ,对JavaScript有效使用D3是必要的。 D3是一个JavaScript库,因此您需要编写JavaScript代码来创建可视化。但是,D3的API旨在直观且易于学习,因此,即使您不是JavaScript专家,您仍然可以使用D3创建强大的可视化。是的,可以与其他JavaScript库或框架一起使用D3。例如,您可以使用D3来创建使用React或Angular。非常适合实时数据可视化。它具有灵活的数据更新机制,可让您在新数据进来时轻松更新可视化。这使D3成为仪表板或实时数据馈送等应用程序的绝佳选择。<span>const width = 540;
</span><span>const height = 540;
</span><span>const radius = Math.min(width, height) / 2;
</span>
在D3版本5.x中,呼叫d3.json()返回诺言,这意味着D3将获取它在我们给它的相对路径上找到的JSON文件的内容,并执行该功能加载后,我们将在The The The The The The The()方法中调用。然后,我们可以访问我们在回调的数据参数中查看的对象。<span>const svg = d3.select("#chart-area")
</span> <span>.append("svg")
</span> <span>.attr("width", width)
</span> <span>.attr("height", height)
</span> <span>.append("g")
</span> <span>.attr("transform", <span>`translate(<span>${width / 2}</span>, <span>${height / 2}</span>)`</span>);
</span>
如果我们添加console.log(data);向我们的d3.json回调的口头声明,我们可以查看我们现在正在使用的数据:<span>const color = d3.scaleOrdinal(["#66c2a5", "#fc8d62", "#8da0cb","#e78ac3", "#a6d854", "#ffd92f"]);
</span>
>
<span>const pie = d3.pie()
</span> <span>.value(d => d.count)
</span> <span>.sort(null);
</span>
<span><span><span><svg</span> width<span>="190"</span> height<span>="160"</span>></span>
</span> <span><span><span><path</span> d<span>="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80"</span> stroke<span>="black"</span> fill<span>="transparent"</span>/></span>
</span><span><span><span></svg</span>></span>
</span>
<span>const arc = d3.arc()
</span> <span>.innerRadius(0)
</span> <span>.outerRadius(radius);
</span>
来处理我们的弧的行为。这通常涉及执行数据加入,退出旧元素,更新屏幕上的现有元素,并添加添加到我们数据中的新元素。在此示例中,我们不必担心退出元素,因为我们在屏幕上始终具有相同数量的饼片。<span>const width = 540;
</span><span>const height = 540;
</span><span>const radius = Math.min(width, height) / 2;
</span>
<span>const svg = d3.select("#chart-area")
</span> <span>.append("svg")
</span> <span>.attr("width", width)
</span> <span>.attr("height", height)
</span> <span>.append("g")
</span> <span>.attr("transform", <span>`translate(<span>${width / 2}</span>, <span>${height / 2}</span>)`</span>);
</span>
<span>const color = d3.scaleOrdinal(["#66c2a5", "#fc8d62", "#8da0cb","#e78ac3", "#a6d854", "#ffd92f"]);
</span>
>不用担心您是否无法完全遵循它的工作原理,因为它是D3中的一个相当高级的话题。这个库的伟大是,您不需要了解其所有内部工作,就可以用它创建一些强大的东西。只要您能理解需要更改的位,就可以抽象一些并不是完全必不可少的细节。<span>const width = 540;
</span><span>const height = 540;
</span><span>const radius = Math.min(width, height) / 2;
</span>
<span>const svg = d3.select("#chart-area")
</span> <span>.append("svg")
</span> <span>.attr("width", width)
</span> <span>.attr("height", height)
</span> <span>.append("g")
</span> <span>.attr("transform", <span>`translate(<span>${width / 2}</span>, <span>${height / 2}</span>)`</span>);
</span>
回想一下,在我们的最后一个示例中,我们有一个数组,其中包含一个项目,适用于要在屏幕上显示的每个派。将此与我们目前拥有的东西进行比较,这是一个对象,其钥匙为1至5,代表我们要绘制的每个派。<span>const color = d3.scaleOrdinal(["#66c2a5", "#fc8d62", "#8da0cb","#e78ac3", "#a6d854", "#ffd92f"]);
</span>
<span>const pie = d3.pie()
</span> <span>.value(d => d.count)
</span> <span>.sort(null);
</span>
<span>const width = 540;
</span><span>const height = 540;
</span><span>const radius = Math.min(width, height) / 2;
</span>
接下来,每次可视化更新时,我们都需要更新半径。为此,我们需要提出一个可以使用的量表。比例尺是D3中的一个函数,在两个值之间采用<span>const svg = d3.select("#chart-area")
</span> <span>.append("svg")
</span> <span>.attr("width", width)
</span> <span>.attr("height", height)
</span> <span>.append("g")
</span> <span>.attr("transform", <span>`translate(<span>${width / 2}</span>, <span>${height / 2}</span>)`</span>);
</span>
<span>const color = d3.scaleOrdinal(["#66c2a5", "#fc8d62", "#8da0cb","#e78ac3", "#a6d854", "#ffd92f"]);
</span>
>
<span>const pie = d3.pie()
</span> <span>.value(d => d.count)
</span> <span>.sort(null);
</span>
<span><span><span><svg</span> width<span>="190"</span> height<span>="160"</span>></span>
</span> <span><span><span><path</span> d<span>="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80"</span> stroke<span>="black"</span> fill<span>="transparent"</span>/></span>
</span><span><span><span></svg</span>></span>
</span>
<span>const arc = d3.arc()
</span> <span>.innerRadius(0)
</span> <span>.outerRadius(radius);
</span>
使其动态
<span>const width = 540;
</span><span>const height = 540;
</span><span>const radius = Math.min(width, height) / 2;
</span>
>我们正在使用Bootstrap的网格系统在此处构建页面,这使我们可以将页面元素整洁地格式化为框。<span>const svg = d3.select("#chart-area")
</span> <span>.append("svg")
</span> <span>.attr("width", width)
</span> <span>.attr("height", height)
</span> <span>.append("g")
</span> <span>.attr("transform", <span>`translate(<span>${width / 2}</span>, <span>${height / 2}</span>)`</span>);
</span>
我们最终得到的是相当可观的东西:<span>const color = d3.scaleOrdinal(["#66c2a5", "#fc8d62", "#8da0cb","#e78ac3", "#a6d854", "#ffd92f"]);
</span>
>我正在使用array.foreach()方法来完成此操作,尽管我也可以再次使用D3的常规
<span>const pie = d3.pie()
</span> <span>.value(d => d.count)
</span> <span>.sort(null);
</span>
>我还想添加一行以显示美国的平均收入,我每年都会更新。首先,我将首次添加平均线:<span><span><span><svg</span> width<span>="190"</span> height<span>="160"</span>></span>
</span> <span><span><span><path</span> d<span>="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80"</span> stroke<span>="black"</span> fill<span>="transparent"</span>/></span>
</span><span><span><span></svg</span>></span>
</span>
><span>const arc = d3.arc()
</span> <span>.innerRadius(0)
</span> <span>.outerRadius(radius);
</span>
>
>这是我用来将这些元素添加到屏幕上的HTML:
>我们需要在这两个元素中添加一些事件听众,以设计我们要寻找的行为。
首先,我想定义我们的<span>const width = 540;
</span><span>const height = 540;
</span><span>const radius = Math.min(width, height) / 2;
</span>
<span>const svg = d3.select("#chart-area")
</span> <span>.append("svg")
</span> <span>.attr("width", width)
</span> <span>.attr("height", height)
</span> <span>.append("g")
</span> <span>.attr("transform", <span>`translate(<span>${width / 2}</span>, <span>${height / 2}</span>)`</span>);
</span>
>在这里,我们使用幻灯片选项将事件侦听器连接到滑块。每当我们的滑块转移到另一个值时,我们都会将计时器更新到此新值,并且在当年的数据中运行了Update()函数。
<span>const color = d3.scaleOrdinal(["#66c2a5", "#fc8d62", "#8da0cb","#e78ac3", "#a6d854", "#ffd92f"]);
</span>
<span>const pie = d3.pie()
</span> <span>.value(d => d.count)
</span> <span>.sort(null);
</span>
>我们拥有它 - 我们的成品 - 一个功能齐全的交互式数据可视化,一切都按预期工作。
<span><span><span><svg</span> width<span>="190"</span> height<span>="160"</span>></span>
</span> <span><span><span><path</span> d<span>="M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80"</span> stroke<span>="black"</span> fill<span>="transparent"</span>/></span>
</span><span><span><span></svg</span>></span>
</span>
>
d3(代表数据驱动的文档)是一个JavaScript库,该库是广泛用于创建交互式数据可视化的JavaScript库。它允许您将任意数据绑定到文档对象模型(DOM),然后将数据驱动的转换应用于文档。 D3不是一个单层框架,它试图提供所有可以想象的功能。取而代之的是,它解决了问题的关键:根据数据有效操纵文档。这避免了专有表示形式,并具有非凡的灵活性,揭示了HTML,SVG和CSS等网络标准的全部功能。我可以将D3用于大数据集吗?是的,D3能够处理大型且复杂的数据集。它具有强大的数据操作功能,可让您以任何格式使用数据。 D3还具有用于从不同来源加载数据的内置功能,使其更容易与您的现有数据基础结构集成。
>如何使我的D3可视化互动互动?
>在广泛的领域中,从新闻到新闻业到D3?商业科学。一些常见的用例包括创建交互式图,构建动态图表和图形,可视化复杂的网络以及创建自定义数据驱动的动画。
>有许多可用于学习D3的资源。 D3官方网站有大量的文档和示例,并且有许多在线教程和课程深度涵盖D3。练习也是关键 - 您使用D3越多,您的概念和API都会变得越舒适。
> d3?
以上是与现代JavaScript和D3的交互式数据可视化的详细内容。更多信息请关注PHP中文网其他相关文章!