【发布时间】:2015-12-04 11:50:19
【问题描述】:
我正在使用实时数据在网页上使用 SVG 绘制一些线条。为了管理我使用 Angular.js 的数据并管理我使用 D3.js 的可视化。
我设置了一个角度控制器来保存数据(行)。数据由一些点数组(带有 x/y 坐标的字典)组成。有些行在初始化时是已知的,有些则根据实时数据更新。
我设置了一个包含 SVG 元素的角度指令 ('topView')。对于初始化时的每一行,我将其添加为路径:
var routeLeftLine = container.select("#routes").append("path");
var routeLeftLineData = scope.val.route.left; // -> 1000+ points in there
routeLeftLine
.attr("d", lineFunction(routeLeftLineData))
.attr("stroke", "black")
.attr("stroke-width", 1)
.attr("fill", "none");
对于我想要不断更新的每一行 (1),我设置了一个角度指令,例如:
<surface-cable val="data.cable"></surface-cable>
data 是控制器上的数据对象,data.cable 是点数组。 该指令如下所示:
OCMSWeb.directive('surfaceCable', function ( /* dependencies */ ) {
return {
restrict: 'AE',
scope: {
val: '='
},
templateNamespace: 'svg',
replace: true,
template: '<g/>',
link: function (scope, element, attrs) {
var cableLine = d3.select(element[0]).append("path");
scope.$watch('val', function () {
var cableLineData = simplify(scope.val, 1, false); // size grows in time
cableLine
.attr("d", lineFunction(cableLineData))
.attr("stroke", "rgb(240,144,32)")
.attr("stroke-width", 1)
.attr("fill", "none");
}, true);
}
};
});
当我使用计时器更新数据时,该结构工作正常,更改会反映在 SVG 中。
当我增加一行中的点数(> 1000 ...我将来需要更多)时,问题就出现了(不变的线和更新的线都有这种效果)性能下降。线的更新变得非常缓慢,即使要重绘的元素还不包含很多元素。
我找不到原因。 SVG/d3/angular 会再次渲染 svg 中的所有元素吗?
我绑定数据的方式效率低吗?我应该一起跳过d3吗?
我试图分析 javascript 性能,大约 80-90% 的 CPU 时间似乎用于 angular $apply 的调用(我认为它会扫描 DOM 以查找更改?)。如果一个元素(行是 <path> 元素)有很多数据点,为什么 $apply 需要这么长时间?
【问题讨论】:
-
你能展示一下小提琴或stmg吗?
标签: javascript angularjs d3.js svg