使用d3图形库,我似乎无法缓慢地绘制路径,以便可以看到它们成长。
此站点在"线图(展开)"部分中有一个完美的示例,但是该部分没有给出代码。有人可以帮助我使用可以实现这一目标的D3代码行吗?
当我尝试附加延迟()或持续时间()(例如在以下代码段中)时,该路径仍会立即绘制,并且此段未能呈现后的所有SVG代码。
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);
SVG中动画行时的常见模式正在设置路径长度的stroke-dasharray
,然后动画stroke-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);
您可以在这里看到一个演示:http://bl.ocks.org/4063326
我相信这样做的" d3方式"是具有自定义的补间函数。您可以在此处看到一个工作实现:http://jsfiddle.net/nrabinowitz/xytnd/
这假设您有一个使用d3.svg.line
设置的称为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
(如果您的背景很复杂)线,并过渡到右侧,以揭示下面的线。
根据您链接到的帖子,我想到了以下示例:
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
}
这有点丑陋,但是有效。您可以在JSFIDDLE上看到它