- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
当我在我的 d3 应用程序中使用旋转 tick 函数时,整个应用程序变慢了。
例如:如果您取消注释行//var angle = 0;在下面jsfiddle它运行速度快 20 倍。
这是为什么?轮换是非常昂贵还是我做错了什么?
function tick() {
link.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
linktext.attr("transform", function(d) {
var xDiff = d.source.x - d.target.x;
var yDiff = d.source.y - d.target.y;
var angle = Math.atan2(yDiff, xDiff) * (180.0 / Math.PI);
//var angle = 0;
return "translate(" + (d.source.x + d.target.x) / 2 + ","
+ (d.source.y + d.target.y) / 2 + ")rotate(" + angle + ")";
});
node.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
}
注意:我修改了原始的 jsfiddle 发现 here
最佳答案
为了追查问题的根源,我试着让文本的各个方面相同/不同。参见 this version of your fiddle .请注意,每个文本元素的文本和 Angular 都不同(因此不可能进行优化)但是每个元素的 Angular 是恒定的——它不会在每次刻度时改变。
结果呢?一开始有点迟钝(当图形中有很多重叠时),但它很快就会在 30fps 以下变得流畅。
同样如此(最终帧速率略高于 30fps),即使文本内容每次更新都发生变化,如 this version .
这与 the usual rule of optimizing animation 相矛盾,改变转换应该比改变内容更有效。
根据 Chrome 帧速率检查器,大部分时间都花在了 your original fiddle 的每次重绘上。 (在我的电脑上时钟大约为 4fps)正在被“绘画设置”步骤占用——即计算图像的每个“层”。
This blog has a quick-and-easy recap of the different steps of a repaint .引用:
The following steps render the elements in the DOM into images on your screen:
Trigger - Elements are loaded into the DOM, or are modified in some way
Recalculate Styles - Styles are applied to elements (or re-calculated)
Layout - Elements are laid out geometrically, according to their positions on the screen
Paint Setup - The DOM is split up into render layers, which will be used to fill out the pixels for each element
Paint - Each layer is painted into a bitmap and is uploaded to the GPU as a texture by a software rasterizer
Composite Layers - The layers are composited together by the GPU and drawn to a final screen image
通常,转换可以在最后的“合成”步骤中由 GPU 高效完成(现代操作系统上的现代浏览器会自动将工作转移到 GPU)。
这可能不会发生的原因有两个。首先是这种优化甚至可能不适用于 SVG(尽管我很确定最新 Chrome 的默认设置是优化 SVG 转换)。然而,即使浏览器对 SVG 转换使用了一些 GPU 优化,您的 GPU 在内存耗尽之前也只能处理有限数量的层。有将近 200 个单独转换的文本元素(以及上下分层的未转换内容),这可能会成为瓶颈。参见 this HTML5Rocks post或 this MSDN article ,其中给出了一些会取消独立层组合的性能限制示例。
无论幕后发生了什么,最终结果都是您的 CPU 而不是 GPU 每次都在计算旋转并将文本分层在一起,这效率不高。
那么,您能做些什么呢?
我尝试通过使用矩阵变换来优化代码,而不是先计算 Angular ,然后让浏览器计算旋转 (see live version) ...但这并没有产生明显的区别。更改为简单的倾斜变换而不是旋转有一点帮助(帧速率高达 11fps),但这只是在滞后的动画之上添加了难看的文本。
不幸的是,看起来您真的不得不以一种或另一种方式妥协。一些选项:
隐藏文本直到强制布局停止,然后才计算旋转。 Working example
关键代码(Javascript):
var vis = d3.select(".intgraph").append("svg:svg")
.attr("width", w)
.attr("height", h)
.append("svg:g")
.on("click", function(){
if ( force.alpha() )
force.stop();
else
force.resume();
});
force.on("start", function(){
vis.classed("running", true);
})
.on("end", function () {
linktext.attr("transform", function (d) {
var xDiff = d.source.x - d.target.x,
xMid = d.source.x - xDiff / 2;
var yDiff = d.source.y - d.target.y,
yMid = d.source.y - yDiff / 2;
var hyp = Math.sqrt(xDiff * xDiff + yDiff * yDiff),
cos = xDiff / hyp,
sin = yDiff / hyp;
return "matrix(" +
[cos, sin, -sin, cos, xMid, yMid] + ")";
});
vis.classed("running", false);
});
CSS:
.running text {
display:none;
}
显示文本,但不旋转它(可选,将其旋转到强制布局停止时的位置,如上所述)。
关于javascript - d3 : rotations and force directed layouts,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23430115/
在JSON输出中,“步骤”中有一个字段“maneuver”。在此“向左转”,“向右转”,“向左转轻微”等。示例为here 在哪里可以找到“操纵”字段的定义以及可能的值列表?没有相关描述here 提前致
默认情况下,我们如何从Google Direction API建议的替代 route 获得从A点到B点的最短距离路线?默认情况下,它会根据当前交通状况为我们提供最短持续时间的路线。我已经注意到,如果您
我想知道“precompile(r) directive”和“preprocessor directive”是一回事吗?我对前者不熟悉,但只是听说过,并通过这个Google在互联网上找到了一些关于它的
对于我的项目,我目前正在开发自定义表单/输入指令。 例如,我有以下指令: angular.module('myApp').directive("textField", function() {
我用谷歌搜索了一下,但找不到任何详细说明如何制作动态包装内容的 Angular 指令的内容(例如 http://demos.telerik.com/kendo-ui/panelbar/angular
我正在尝试在另一个指令中使用一个指令。具体来说,我有一个模态指令,我想传递一个表单指令,并将充当模态的主体。 我的模态指令: angular.module('Storyboard').dir
我构建了一个模块化形式的小型演示,其中包含单独的输入指令。它还可以预览绑定(bind)到相同 Controller 和范围的表单值。 导致问题的输入指令是嵌入到表单内的输入:
HTML 指令 .directive('authorname', function() { return { restrict: 'E', scope: {
我有可以编译的 Angular 指令 至和 至Hello World! 我怎样才能把greeting在我的 HTML 中标记并将其编译为 print-greeting然后最后显示Hello World
标题中引用的脚注是什么意思?这是 6.10.3p11 的脚注 If there are sequences of preprocessing tokens within the list of arg
因此,电话号码始终是 ltr(从左到右)。 在多语言网站上工作,我需要在方向为 rtl 的文本段落中插入一个电话号码(带有“+”前缀和由“-”分隔的数字)(当然是针对相关语言) 所以我有这样的东西:
我有一个标题元素,我想显示 flex 列,这样我就可以将 .container div 垂直居中。这工作正常。然后我需要 .container 中的元素在 1200px 之间以均匀的间距连续 flex
如何将整个ng-repeat对象传递给指令(或如何将指令的作用域设置为ng-repeat项)? 我是新来的有角度的人,很难解决这个问题。 我有一个 Controller ,可以很好地呈现以下内容:
我需要将“...”放在文本前面,并在填充 div 时仅显示文本的最后一部分。 正常时不执行任何操作 C:\fakepath\996571_1398802860346752_209456547
我需要将“...”放在文本的前面,并且只显示它的最后一部分,当它填充 div 时。 正常的时候什么也不做 C:\fakepath\996571_1398802860346752_209456
我需要一个“粘性”指令,当它位于页面顶部时向元素添加一个 css 类,并且还指示其状态的变化。出于这个原因,我定义了一个范围,如 { onStickyChange: '&' }。现在我想在 angul
我对 ngSwitch 指令有点困惑——它是“属性指令”还是“结构指令”。 属性指令用“方括号”编写,如 [ngStyle]、[ngClass] 等(我们将其写为 [ngSwitch],将其称为“属性
Wi-Fi direct 的 Wiki 规范声称“只有一个 Wi-Fi 设备需要兼容 Wi-Fi Direct 才能建立点对点连接,在彼此之间直接传输数据,大大减少了设置”。但是从 android A
我有一个响应式模板,我正尝试将其与我的 Angularjs 应用程序一起使用。这也是我的第一个 Angular 应用程序,所以我知道我在未来有很多错误和重构。 我已经阅读了足够多的关于 Angular
首先,我这样做的方式可能不正确。但我会解释这个问题: 1) 我正在创建名为 的指令 2) 当点击第一个指令中的按钮时,我试图在运行时动态插入第二个指令 如下: var app = angu
我是一名优秀的程序员,十分优秀!