Javascript Can';t使用D3使路径缓慢增长
使用d3图形库,我似乎不能让路径画得很慢,这样就可以看到它们在增长 在“折线图(展开)”部分有一个完美的例子,但没有给出该部分的代码。有人能帮我用D3代码来实现这一点吗 当我尝试附加delay()或duration()时(如下面的代码段中),路径仍然会立即绘制,并且该段之后的所有SVG代码都无法呈现Javascript Can';t使用D3使路径缓慢增长,javascript,animation,svg,d3.js,Javascript,Animation,Svg,D3.js,使用d3图形库,我似乎不能让路径画得很慢,这样就可以看到它们在增长 在“折线图(展开)”部分有一个完美的例子,但没有给出该部分的代码。有人能帮我用D3代码来实现这一点吗 当我尝试附加delay()或duration()时(如下面的代码段中),路径仍然会立即绘制,并且该段之后的所有SVG代码都无法呈现 var mpath = svg.append ('path'); mpath.attr ('d', 'M35 48 L22 48 L22 35 L22 22 L35 22 L
var mpath = svg.append ('path');
mpath.attr ('d', 'M35 48 L22 48 L22 35 L22 22 L35 22 L35 35 L48 35 L48 48')
.attr ('fill', 'none')
.attr ('stroke', 'blue')
.duration (1000);
根据您链接到的帖子,我给出了以下示例:
var i = 0,
svg = d3.select("#main");
String.prototype.repeat = function(times) {
return (new Array(times + 1)).join(this);
}
segments = [{x:35, y: 48}, {x: 22, y: 48}, {x: 22, y: 35}, {x: 34, y:35}, {x: 34, y:60}];
line = "M"+segments[0].x + " " + segments[0].y
new_line = line + (" L" + segments[0].x + " " + segments[0].y).repeat(segments.length);
var mpath = svg.append ('path').attr ('d',new_line )
.attr ('fill', 'none')
.attr ('stroke', 'blue')
for (i=0; i<segments.length; i++)
{
new_segment = " " + "L"+segments[i].x + " " + segments[i].y
new_line = line + new_segment.repeat(segments.length-i)
mpath.transition().attr('d',new_line).duration(1000).delay(i*1000);
line = line + new_segment
}
var i=0,
svg=d3。选择(“主”);
String.prototype.repeat=函数(次){
返回(新数组(次+1)).join(此);
}
段=[{x:35,y:48},{x:22,y:48},{x:22,y:35},{x:34,y:35},{x:34,y:60}];
line=“M”+段[0]。x+“”+段[0]。y
新直线=直线+(“L”+线段[0]。x+“”+线段[0]。y)。重复(线段.length);
var mpath=svg.append('path').attr('d',新行)
.attr('填充','无')
.attr('笔划','蓝色')
对于(i=0;i我相信“D3方式”是通过一个定制的tween函数来实现的。您可以在这里看到一个工作实现:
这假设您有一个名为line
的生成器,它使用d3.svg.line
设置来计算路径:
// add element and transition in
var path = svg.append('path')
.attr('class', 'line')
.attr('d', line(data[0]))
.transition()
.duration(1000)
.attrTween('d', pathTween);
function pathTween() {
var interpolate = d3.scale.quantile()
.domain([0,1])
.range(d3.range(1, data.length + 1));
return function(t) {
return line(data.slice(0, interpolate(t)));
};
}
这里的pathTween
函数返回一个插值器,该插值器获取给定的线段,该线段由我们通过转换的距离定义,并相应地更新路径
不过,值得注意的是,我怀疑您可以通过简单的方式获得更好的性能和更流畅的动画:放置一个白色矩形(如果您的背景很简单)或一个clipPath
(如果您的背景很复杂)在线条上方,并将其向右转换以显示下方的线条。在svg中设置线条动画时的常见模式是设置路径长度的笔划dasharray
,然后设置笔划dashoffset
的动画:
var totalLength = path.node().getTotalLength();
path
.attr("stroke-dasharray", totalLength + " " + totalLength)
.attr("stroke-dashoffset", totalLength)
.transition()
.duration(2000)
.ease("linear")
.attr("stroke-dashoffset", 0);
您可以在此处看到演示:
为该示例编写代码:…没关系,当我运行它时,我可以看到它的实现是白痴哇。三种不同的解决方案,但只能检查一种。谢谢你,nrabinowitz、Duopixel和btel!这当然看起来像d3方式,但如果你放慢动画速度,则会附加路径,而不是动画(至少在Chrome中)。谢谢,我很感激!是的,设置一个矩形的动画来显示线条可能会更好。在大多数情况下,简单的剪辑路径也会提供良好的性能,不清楚这是否比调整路径更好(试试看,实现可能会有点不同)@Duopixel-是的,这只是在逐点基础上添加下一个线段。但是您可以扩展tween函数,将下一个点添加为上一个点的副本,然后使用interpolateObject
或interpolateArray
沿路径线段添加tween(但对其他直线插值不起作用).P.S.谢谢关于JSBeautizer的提示。我现在可以在transitions_010.html文件中看到这些代码,你是对的——一系列杂乱的嵌套“next”子句。谢谢你,我很感激!这可能与d3.svg.area有关吗?到目前为止,我没有成功的建议:而不是path.node.getTotalLength()
您应该有path.attr('stroke-dashoffset',function(){返回this.getTotalLength();})
否则,如果在多个数据点上选择了路径
,则总长度
将仅为您正在绘制的第一条路径的长度。后续的路径
将以非常奇怪的方式进行动画制作。巧妙的技术。从我对代码的阅读来看,不可能使用它从路径上的任意点进行增长两个方向都向外,对吗?@GeorgeMauer我想如果你同时设置stroke-dasharray
和stroke-dashoffset
的动画是可能的,但我无法从我的头顶上理解。我建议打开一个新问题。