使用 D3 和 Angular 创建多功能可视化

学习如何结合 D3 数据可视化工具和 Angular 跨平台应用开发平台来创建交互式可视化。
425 位读者喜欢这篇文章。
An introduction to GNU Screen

Opensource.com

我们的世界基于数据。我们从各处收集数据:表单、反馈、学习技术、数据挖掘等等。当涉及到处理这些数据时,我们需要的不仅仅是向用户展示数字;我们需要让他们容易理解数字的含义。

通过结合 D3 数据可视化工具和 Angular 跨平台应用程序开发平台,我们可以利用这些数据创建多功能和交互式的可视化,以响应动态数据。 这可以从您的数据中挤出最后 10% 的价值,并将您的数据驱动应用程序提升到一个新的水平,为您的用户带来更好的体验。

什么是 D3?

D3.js 是一个开源 JavaScript 库,它提供了由数据驱动的文档对象模型 (DOM) 的强大操作功能。 它为您提供了创建任何您能想象到的可视化所需的所有工具。 您可以获得数据转换来准备数据,形状创建来可视化数据,布局将数据转换为不同的表示布局,过渡效果在数据和形状变化时赋予视觉效果,以及强大的交互工具。 它基于 Web 标准,允许您使用 HTML、CSS 和 SVG 转换您的数据并赋予其生命。

入门 D3 很简单。 要创建可视化,我们首先需要一个 SVG 元素来使用

var width = 500,
    height = 500;
var svg = d3.select('body')
    .append('svg')
    .attr('width', width)
    .attr('height', height)
    .append('g')
    .attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ') rotate(-90 0 0)');

让我们来一点乐趣,创建一个旭日图。 可以把它想象成一个多层甜甜圈图,非常适合显示层次结构数据。(它也比简单的条形图示例更有趣。) 要开始,我们需要一个形状生成器,在本例中是弧形。 D3 提供了一个生成器来创建您可以自定义的圆形扇区。

var arc = d3.svg.arc()
    .startAngle(function(d) {
      return Math.max(0, Math.min(2 * Math.PI, xScale(d.x)));
    })
    .endAngle(function(d) {
      return Math.max(0, Math.min(2 * Math.PI, xScale(d.x + d.dx)));
    })
    .innerRadius(function(d) {
      return Math.max(0, yScale(d.y));
    })
    .outerRadius(function(d) {
      return Math.max(0, yScale(d.y + d.dy));
    });

现在我们准备好数据了。

通用更新模式

D3 有一种处理数据的方式。 这种模式是join(连接)、enter(进入)、update(更新)和 exit(退出)。 这涉及到数据连接以合并新的和现有数据,然后是数据的进入、更新和删除。 使用 D3,通过 data()append()transition()exit() 可以轻松实现这种模式。

/* JOIN new data with old elements */
var gs = svg.selectAll('g')
  .data(partition.nodes(root));

/* ENTER new elements present in new data */
var g = gs.enter().append('g')
  .on('click', click)
  .on('mouseover', mouseoverArc)
  .on('mousemove', mousemoveArc)
  .on('mouseout', mouseoutArc);

var path = g.append('path');

/* UPDATE old elements present in new data */
gs.select('path')
  .style('fill', function(d) {
      return color((d.co ? d.co : 'base'));
  })
  .transition().duration(500)
  .attr('d', arc)
  .each(function(d) {
      this.x0 = d.x;
      this.dx0 = d.dx;
  });

/* EXIT old elements not present in new data */
gs.exit()
  .transition()
  .duration(500)
  .style('fill-opacity', 0)
  .remove();

通过将所有这些与一些数据结合起来,D3 将完成创建旭日图的繁重工作。 我们甚至设置了函数来提供交互性(请参阅代码的 ENTER 部分)。 但是,如果我们希望此图表与其他图表通信怎么办? 引入 Angular 组件。

什么是 Angular?

Angular 是一个用于构建移动和桌面 Web 应用程序的平台。 这是一个专为构建应用程序而设计的有主见的框架,为您提供所需的所有组件。 它有很多特性,但我们将专注于一个方面:组件。 它们是 UI 的基本构建块和将与我们的 D3 代码交互的 Angular 代码。

结合我们的力量

增强 D3 可视化的组件的两个强大组成部分是输入和输出。 输入允许我们的组件接收数据,这意味着我们可以拥有一个生成旭日图的组件,它不知道如何获取数据,但仍然会在数据传入时渲染它。 输出允许我们的组件将数据传递回父组件,将事件和数据传递回堆栈。

@Input()
sunData: dataPoint[];

@Input()
filters: string[];

@Output()
onFilter: EventEmitter<string[]> = new EventEmitter<string[]>();

Angular 在其代码中同时使用了装饰器和 TypeScript,这为您的代码增加了很多价值和力量。 @Input@Output 的属性装饰器定义了我们组件的输入和输出。 通过以这种方式定义属性,Angular 编译器会自动创建到该属性的绑定并将其链接起来。 在输入方面,我们可以为数据分配类型。 它通过定义期望的数据来创建更好的代码,这在您将组件连接到 Angular 应用程序中的其他代码时会派上用场。 Angular 还可以使用不同的变更检测策略来优化组件。 您可以告诉组件仅在推送时才更新自身,在这种情况下,它会查看输入的引用,并且仅在引用发生更改时才更新。

在输出方面,我们使用 EventEmitter。 这使我们的组件能够将数据发送到提供给组件的函数。 我们可以将其连接到我们的可视化和点击事件。 当我们单击点时,我们可以将值传递给包含我们的组件,例如 DashboardComponent。 然后 DashboardComponent 可以通过过滤数据或查询 API 来更新数据。 我们的 D3 旭日图组件和我们创建的任何其他组件都将看到更改,并且通用更新模式将接管。

开源走向未来

使用 Angular 和 D3 的一大优点是它们都是开源的,并且提供了来自每个社区的大量示例。 例如,D3 有一个很棒的社区,其中包含大量图表,从基本的到富有想象力的。 它们可以作为您数据的灵感,或者作为帮助您开始创建那个伟大创意的起点。

要了解更多信息,请参加 John Niedzwiecki 在 Connect.Tech (亚特兰大,2017 年 9 月 21-22 日) 上的演讲“D3 + Angular = Visual Awesomesauce”。

User profile image.
我们友好的邻居,穿苏格兰短裙的程序员。 Web、JavaScript、D3 和 Angular 的开发者。 姜黄色极客爸爸。

7 条评论

这篇文章有点令人失望,与如此雄心勃勃的标题/副标题相比。

已经有大约一千个“import d3, 在 Angular 中画一条线。 现在,去创造酷炫的东西”教程了。

很抱歉让您失望了。 这篇文章实际上是作为我将在 Connect.Tech 上就此主题发表演讲的引子,所以它只是介绍性的。 我试图展示的不仅仅是使用弧线和创建旭日图来画一条线。 我邀请您在下周之后查看我的个人 Github / 博客,以获取我将在会议后发布的完整演示文稿,希望这能给您更多您想要的东西。 另外,您想看到或期望看到什么? 只是这篇文章的简洁性有问题吗?您想看到一个完整的可工作的原型吗?

回复 ,作者 colin_adsf (未验证)

感谢 John 的文章.. 但是您可以发布完整的源代码吗? 我真的无法理解。 我看不到您试图创建/呈现的内容 - 全貌。 谢谢

JJ,

这是我为下周的演讲编写的一段代码(这篇文章是作为预览),所以我很快就会有一个完全可工作的版本。 您可以查看我的个人 Github (rhgeek),但我也会确保在准备好后回来发布一个直接链接给您,让您知道。

回复 ,作者 JJ

完整的源代码在 Github 上可用。 https://github.com/RHGeek/d3-ng-visual-awesomesauce

您可以在 /examples/sunburst 下找到旭日图的代码。 演讲的幻灯片也可用。 Connect.Tech 录制了演讲,我认为他们将在本周晚些时候开始在网上发布。 希望这些对您有所帮助,如果您需要更多帮助,请随时在此处或在 Twitter (@rhgeek) 上与我联系。

回复 ,作者 JJ

我已经看到很多优秀的视觉交互程序,但想知道如何制作像这样的网站? 他们在做什么? https://www.earthslab.com/anatomy/maxilla/ 看看他们交互式的解剖界面。

通过右键单击并检查(结合少量谷歌搜索类名),看起来他们专门使用了一个名为 image map pro for wordpress 的工具。 现在,话虽如此,您可以自己重新创建该功能。 从技术层面来说,它是如何完成的呢?他们加载图像,基于您是否想要头骨、肌肉等,然后在上面覆盖一个 SVG。 如果您检查,您会看到很多多边形。 它创建的是图像上的形状,以定义您想要显示包含更多信息的 div 区域,例如工具提示。 因此,他们在图像上绘制一个形状来表示额骨是什么,当您悬停时,他们会显示包含所有相关文本的 div。

您可以使用 D3 或直接使用 SVG 自己创建类似的东西。 D3 可以为您提供创建这些部分和交互的代码。 这将取决于总体目标,它可能更像是一种混合解决方案,或者甚至可能不需要 D3。 在这个特定示例中最困难的部分是定义与您的区域匹配的区域,因为它位于固定图像的顶部。 这是他们的工具显然可以做到的,我认为您可能会通过谷歌搜索找到帮助您定义该区域的工具,然后供其他代码使用。

希望这能帮助您走上正确的道路。

回复 ,作者 Nathan

Creative Commons License本作品根据 Creative Commons Attribution-Share Alike 4.0 International License 许可。
© . All rights reserved.