我已准备好D3径向图组件以显示某些目标的百分比值。当开始将前景圆从0绘制到chartPercentage(例如70%)时,添加平滑过渡效果会很棒。
问题是 - 如何使用下面附带的代码准备转换/延迟/持续时间效果?
我想要实现的第二个想法是使用从0到chartValue的动画计算圆内的值(径向内容)。如何准备这样的解决方案?
谢谢!
const chartPercentage = 70;
const chartValue = 1.1242
const radius = 75;
const border = 7;
const padding = 0;
const width = 400;
const height = 400;
const twoPi = Math.PI * 2;
const boxSize = (radius + padding) * 2;
let svg;
function setArc() {
return d3.arc()
.startAngle(0)
.innerRadius(radius)
.outerRadius(radius - border)
.cornerRadius(50);
}
function draw() {
svg = d3.select(".chart").append("svg")
.attr('width', width)
.attr('height', height);
svg.append("foreignObject")
.attr("width", boxSize)
.attr("height", boxSize)
.append("xhtml:div")
.attr('class', 'radial-wrapper')
.html(`<div class="radial-content">${chartValue}</div>`);
const field = svg.append('g')
.attr('transform', 'translate(' + boxSize / 2 + ',' + boxSize / 2 + ')');
const meter = field.append('g')
.attr('class', 'progress-meter');
const background = meter.append("path")
.datum({endAngle: twoPi})
.attr('class', 'background')
.attr('fill', '#2D2E2F')
.attr('fill-opacity', 0.1)
.attr("d", setArc());
const foreground = meter.append("path")
.datum({endAngle: (chartPercentage/100) * twoPi})
.attr('class', 'foreground')
.attr('fill', 'red')
.attr('fill-opacity', 1)
.attr('d', setArc());
}
draw();
body { margin:30px;position:fixed;top:0;right:0;bottom:0;left:0; }
.radial-wrapper{ display: flex; align-items: center; justify-content: center;width: 100%; height: 100%;}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="chart"></div>
答案 0 :(得分:1)
为属性补间创建一个函数。
function arcTween(a) {
var j = {"endAngle":0};//start angle
var i = d3.interpolateObject(j, a);
return function(t) {
d3.select(".radial-content").text(d3.format(".4n")(chartValue*t));
return arc(i(t));
};
}
在上面的功能中
d3.select(".radial-content").text(d3.format(".4n")(chartValue*t));
这将在转换运行时更改径向内容中的文本(并以格式输出)。
现在将补间函数添加到前台路径。
const foreground = meter.append("path")
.datum({
endAngle: (chartPercentage / 100) * twoPi
})
.attr('class', 'foreground')
.attr('fill', 'red')
.attr('fill-opacity', 1)
.transition().duration(750).attrTween("d", arcTween);
工作代码here
答案 1 :(得分:1)
我重写了你的代码。如果需要为某些属性设置动画,则应使用attrTween
而不是attr
方法。
const chartPercentage = 70;
const chartValue = 1.1242
const radius = 75;
const border = 7;
const padding = 0;
const width = 400;
const height = 400;
const twoPi = Math.PI * 2;
const boxSize = (radius + padding) * 2;
let svg;
const setArc = d3.arc()
.startAngle(0)
.innerRadius(radius)
.outerRadius(radius - border)
.cornerRadius(50);
const arcParams = {};
function draw() {
svg = d3.select(".chart").append("svg")
.attr('width', width)
.attr('height', height);
svg.append("foreignObject")
.attr("width", boxSize)
.attr("height", boxSize)
.append("xhtml:div")
.attr('class', 'radial-wrapper')
.html(`<div class="radial-content"></div>`);
const field = svg.append('g')
.attr('transform', 'translate(' + boxSize / 2 + ',' + boxSize / 2 + ')');
const meter = field.append('g')
.attr('class', 'progress-meter');
const background = meter
.append("path")
.attr('class', 'background')
.attr('fill', '#2D2E2F')
.attr('fill-opacity', 0.1)
.attr("d", setArc({ endAngle: twoPi }));
const foreground = meter
.append("path")
.transition()
.ease(d3.easeBounce)
.duration(1500)
.attr('class', 'foreground')
.attr('fill', 'red')
.attr('fill-opacity', 1)
.attrTween("d", function() {
return arcTween({ endAngle: 0 }, chartPercentage/100 )
})
}
function arcTween(d, new_score) {
var new_startAngle = 0
var new_endAngle = new_startAngle + new_score * 2 * Math.PI
var interpolate_start = d3.interpolate(d.startAngle, new_startAngle)
var interpolate_end = d3.interpolate(d.endAngle, new_endAngle)
return function(t) {
d.endAngle = interpolate_end(t)
d3.select('.radial-content')
.text((d.endAngle / new_endAngle * chartValue).toFixed(4));
return setArc(d)
}
}
draw();
body {
margin: 30px;
position: fixed;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.radial-wrapper {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div class="chart"></div>