我开发了一个Web应用程序,我需要在其中可视化数据 我使用AngularJS进行模块化设计,分离视图,数据和逻辑 我正在使用D3.js创建SVG元素的数据可视化。
AngularJS和D3.js中的每一个都能很好地工作,但我觉得通过以这种分离方式一起使用它们我做错了。
我的Web应用程序由HTML元素和SVG元素组成,两者都是从相同的数据集生成的。然而,我使用两种不同的工具来创建和操作UI(Angular用于动态构建界面,D3用于动态构建图形)。
HTML和SVG元素都需要允许与用户进行交互。
我正在使用Angular控制器包装我的SVG图形。在控制器内部,我使用D3直接构建和操作SVG。当有很多交互,动画和数据发生变化时 - 这很快变得非常麻烦和繁琐。
我创建this simple fiddle作为我目前如何做事的简化示例。
以itemsGraphCtrl
控制器为例,使用D3在Angular控制器中创建图形。
/* ... */
.controller("itemsGraphCtrl", function($scope, dataStore) {
$scope.data = dataStore.data;
var canvas = d3.select(".canvas");
//enter:
canvas.selectAll('circle').data($scope.data)
.enter().append('circle')
.attr('cx', function(d, i) {
return i * 30 + 10;
})
.attr('cy', 50)
.attr('r', 5)
.style('fill', 'white')
.style('stroke', 1)
.on('click', function(d) {
$scope.$apply(function() {
d.selected = !d.selected;
});
});
function update() {
canvas.selectAll('circle').data($scope.data)
.style('fill', function(d) {
return d.selected ? 'black' : 'white';
});
}
$scope.$watch('data', update, true);
});
这似乎不像做事的“角度方式”。
我们将非常感谢任何建议/指南/改进/图书馆/其他解决方案。
答案 0 :(得分:2)
我建议先使用this article建议的模式或d3.chart等库,将D3图表制作成可重复使用的对象。
将D3图表封装在自己的对象中后,可以将它们包装在指令中。当您发现图表如何与应用程序的其余部分进行交互时,您将开始在图表对象本身上构建API;例如,图表对象可能会在单击圆圈时触发事件。然后,您可以在指令包装器中挂钩此API。这样,您就可以将D3对象集成到Angular代码中,就像使用任何其他GUI组件或插件一样。
获得图表后,您的指令可能如下所示:
.directive('bubbleChart', function() {
var chart = d3.charts.bubble();
return {
restrict: 'E',
scope: {
data: '=',
emptyMessage: '@'
},
link: function(scope, element, attrs) {
chart.emptyMessage(scope.emptyMessage);
scope.$watch('data', function(data) {
d3.select(element[0])
.datum(data)
.call(chart);
});
}
};
})
您可以向chart
对象添加其他选项,或让用户通过属性设置选项。