我正在开发一个中型应用程序,其中将包含大量 D3 图表/交互。我想知道是否有人尝试过将 Backbone、Angular 或 Ember 与 D3 一起使用,如果是的话,哪一个似乎最适合前端 MV* 框架。该应用程序不会执行大量 CRUD 操作,主要是交互式图表和小部件来操作它们。
任何意见表示赞赏!
我正在开发一个中型应用程序,其中将包含大量 D3 图表/交互。我想知道是否有人尝试过将 Backbone、Angular 或 Ember 与 D3 一起使用,如果是的话,哪一个似乎最适合前端 MV* 框架。该应用程序不会执行大量 CRUD 操作,主要是交互式图表和小部件来操作它们。
任何意见表示赞赏!
我们在一个由多个“场景”组成的项目中非常广泛地使用了 d3 和 Backbone。每个场景都包含一组不同的图表,用户可以从一个场景导航到另一个场景。这些场景及其内容都需要高度可配置(例如标签颜色和格式,或指示应在给定轴上绘制哪些数据参数)。
D3(理所当然地)不提供视图管理系统,这是 Backbone 接管的地方。主干视图用作 d3 图表的包装器。可以预见的是,骨干模型充当了 d3 绘图数据的载体。但更有趣的是,我们还发现它们可以很好地控制主干视图中包含的 d3 代码的外观和行为;本质上,它们充当了视图模型。由于 d3 提倡将函数作为参数传递给其他函数,因此这些 Backbone Models-as-view-models 最终在其中包含了许多函数。
下面是一个简单的例子,但是用几十个属性来做这件事。在这里使用咖啡脚本,因为它更短(而且更好)。
首先是模型,我们在(例如)路由器的事件处理程序中对其进行实例化。我们使用将应用于 d3 选择器的函数填充此模型。
barChartModel = new Backbone.Model
barColor: (d, i) -> if d.profits < 0 then "red" else "green"
barLengthVal: (d, i) -> return bar.profits #// profits will be the prop we graph
onClick: (d, i) ->
console.log "We are", if d.profits <= 0 then "losing" else "making", "money"
data: someJsonWeLoaded
我们将此模型传递到一个新视图中:
barChartView = new BarChartView
el: "#the_bar_chart"
model: barChartModel
一个视图可以这样实现:
class BarChartView extends Backbone.View
render: ->
bars = d3.select(@el)
.selectAll('.bar')
.data(@model.get 'data') # <---- THIS
bars.enter()
.attr('class', 'bar')
.attr('fill', @model.get 'barColor') # <---- THIS
.attr('height', (d, i) ->
@barLengthScale @model.get('barLengthVal')(d, i) # <---- AND THIS
)
.on('click', @model.get 'onClick') # <---- INTERACTIVITY TOO
initialize: ->
@barLengthScale = d3.scale.linear()
.domain([-100, 100]) # <---- THIS COULD ALSO COME FROM MODEL
.range([0, @$el.height()])
@render()
我在几个仪表板上使用了 D3 和 Angular,效果非常好。我从来没有真正使用过 Backbone,也没有使用过 D3,所以我无法将两者进行比较。我选择 Angular 来补充 D3,因为在我看来,最近 D3 社区一直在使用 D3 和 Angular,这是你提到的三个选项中的大部分,所以有很多可用的资源。最近有一整本书致力于将 D3 和 Angular 结合使用。我之前也使用过 Angular,并且知道指令。指令(在 Angular 中是扩展 html 标签的一种方式)非常适合与 D3 啮合。每个图表都可以成为一个指令,然后使重用图表变得非常容易,只需更改 $scope 数据。这些是我发现在结合两者时有用的一些资源:
https://www.youtube.com/watch?v=aqHBLS_6gF8
https://leanpub.com/d3angularjs
http://plnkr.co/edit/WnoCtNPV9azj0oPwv9kM?p=preview
http://vicapow.github.io/angular -d3-talk/slides/demos/a-donut-chart-editor/index.html#/
我最近就这个话题发表了演讲,这里有一些链接:视频·代码·幻灯片
我已经使用与 meetamit 类似的方法完成了一些较小的项目,但最近开始探索 Ember + D3。我还没有做太多,但我认为 Ember 可以提供很多可以简化构建这些类型的应用程序的功能。想到的一些事情:
计算属性:您通常会显示聚合,因此使用计算属性对数据进行切片意味着您只需在数据更改时调用图表的更新函数,一切顺利。不再担心向每个视图发送事件,当数据的特定部分发生更改时,该事件将发生更改。另外,这些可能是控制器上的属性,而不是在特定图表或视图中计算,这将使重用变得更加容易。
存储状态:我很难找到在 Backbone 中存储状态的最佳方式。我一开始试图通过事件来协调一切,但最终我找到了一个独立的状态模型,它充当了整个系统的大脑。
到目前为止,我并没有经常使用 Backbone 的路由器,但是 Ember 的路由器 + 对状态的关注使这个设计挑战对我来说变得更容易了。如果您在系统内构建,您可以点击您的过滤器和控件,一切正常。在 Backbone 中做同样的事情是可能的,但是对于严重减少你的认知负荷来说,有一些话要说。您也可以显式使用StateManager对象——这里可能有一些非常有趣的解决方案,尽管我还没有探索过它们。
同样,我对这个组合的经验很浅,但如果我的直觉是正确的,那么在 Ember 的约定中构建可视化将会有很多收获。
如果您还没有遇到过这种情况,Square 发表了一篇文章,简要介绍了他们使用 Ember + D3 构建交互式仪表板的经验。
让我们了解您的最新进展+您遇到的任何见解,祝您好运!
我的团队在 d3 中同时使用了 Angular 和 Backbone,我们出于不同的原因喜欢这两种方法。
Backbone 对构建应用程序的方式不那么固执己见,如果您需要自定义处理数据以提高性能的方式,这很好。您通常将 d3 与主干视图集成。
使用 Backbone 的一个挑战是复杂视图的内存管理,但使用marionette 有助于解决这个问题。此外,如果您想使用crossfilter或lunr 之类的东西,Marionette 的事件聚合器(特别是使用 request-response )非常适合用于协调视图的集中式数据源。
Angular 更加结构化,它允许您非常快速地构建很酷的功能。它有一个陡峭的学习曲线,但我现在发现我正在理解 Angular(过去大约 4 周使用它来开发应用程序),我发现我可以完成许多相同的事情在不诉诸任何太骇人听闻的事情的情况下,在骨干上。
就像骨干木偶中的请求-响应对象一样,使用角度服务可以让您快速构建复杂的视图。您需要避免使用 Angular 对 $scope 数据进行复杂数据可视化的脏检查,以防止您的应用程序陷入困境,因此您为处理 Angular 数据而编写的代码最终看起来很像您的代码会写在骨干上。
我已经抵制了 Angular 的“魔法”有一段时间了,但由于所有内置指令、范围检查和其他好东西,我开始被你可以实现的开发速度所征服。Angular 仍然允许您在需要时探索其内部以加速您的代码。这种“挖掘”可能比在主干中花费更多的时间(因为代码库更复杂),但我发现在这个阶段损失的时间通常可以通过节省时间来弥补,避免常见的错误,如视图代码中的内存泄漏和编写样板像视图渲染和数据绑定这样的代码。
一年以来,我在 Angular 上使用 D3,我喜欢两者的结合。Angular 使用指令来创建新的和可重用的 HTML 元素。掌握了这些知识后,您就可以在 Angular 指令中封装 D3 可视化,而无需在控制器或其他地方使用 D3。之后,您可以在应用程序的任何地方重用该指令来可视化您的数据。当在一个由多个 Angular 开发人员组成的团队中工作时,团队的其他成员不需要了解任何有关 D3 的信息,因为您的 D3 代码只存在于指令中。
Angular 中的指令为您提供了一种灵活的数据处理方式。您可以选择数据是否保留在指令中(然后您将拥有静态可重用可视化),或者您将数据绑定到 Angular 应用程序中的控制器(然后您将拥有动态可重用可视化)。后者可以通过在指令中设置范围来实现
scope: { data: '=' /* bi-directional binding */ }
,
在控制器中设置数据
$scope.data = [23,44,22];
并加入您的 HTML 元素实例
<div your-new-d3-element data="data"></div>
.
而已!
此外,您可以在指令中使用 watcher 来观察控制器中的数据变化。Angular中可重用d3指令的一个很好的例子给出了这个例子:http ://bl.ocks.org/biovisualize/5372077
此外,您可以在本文中找到关于 Angular 设置的简单 D3:http: //goo.gl/hNS8k1 在此站点上,您可以找到更多介绍如何在 Angular 应用程序中使用 d3 插件(如鱼眼插件)或如何实现更复杂的Angular 中的 d3 可视化。
我曾经使用过Backbone+d3和Angular+d3一点点。
Backbone 存在内存泄漏问题,如果您使用 Backbone,那么垃圾收集应该是准确的。然而正如前面提到的木偶或卓别林可以很容易地解决这个问题。如果您想拥有轻巧快速的应用程序,我建议您将 React 引擎用于视图,将主干模型用于其他需求。
至于 Angular,它具有更严格的结构。但是,我相信这将与 Backbone 几乎相同的逻辑。Angular 负责架构和所需的一切,只需通过 refs 编写代码,它将是可维护的。与骨干不同,结构是您的选择。
我建议您比较路由、绑定、模型来选择正确的框架,而不是视图。
我总是选择骨干+ smths,通常是React。因为它灵活且易于管理应用程序视图。Fe 当我们发现 react 我们从主干转移到 react 来解决我们的内存泄漏问题。然而,applicarion 有大约 50 个视图,具有不同的数据可视化工具和许多控件。我们在两个月内逐步移动了视图。在角度上用同样的努力做同样的事情是很困难的。
我认为这些类型的问题并没有真正的正确答案 IMO,这就像问某人应该选择斯巴鲁还是丰田,而他们所需要做的就是从 a 到 b :) 无论如何,使用 AngularJS 和 D3目前,到目前为止一切顺利:)如果您确实选择使用 AngularJS,则有一个不错的AngularJS 指令用于 D3 和 NVD3 。
另外,查看这篇关于将 D3 与 AngularJS 结合起来的优秀文章。
快乐探索!