我有3个饼图加载动画。 每个图表中都有一个文本,百分比数字,一个图表加载后跟随动画并开始计数从0%到总计%
我能够在一个饼图中显示文本,但是当我从3个饼图中调整使用的代码时,我找不到显示3个文本的方法。 我循环使用3 div并且输出3%的数字,我可以在控制台中看到正确的百分比数字,但是在饼图中没有显示任何内容:/
我是d3的新手,所以它可能比我能看到的要容易得多。
app.numbers = {
calcPerc : function(percent) {
return [percent, 100-percent];
},
drawDonutChart : function(el, percent, width, height, text_y) {
width = typeof width !== undefined ? width : 290; //width
height = typeof height !== undefined ? height : 290; //height
text_y = typeof text_y !== undefined ? text_y : "-.10em";
var radius = Math.min(width, height) / 2;
var pie = d3.pie().sort(null);
var dataset = {
lower: this.calcPerc(0),
upper: this.calcPerc(percent)
}
//this.percents = percent;
this.arc = d3.arc()
.innerRadius(radius - 20)
.outerRadius(radius);
var svg = d3.select(el).append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var path = svg.selectAll("path")
.data(pie(dataset.lower))
.enter().append("path")
.attr("class", function(d, i) { return "color" + i })
.attr("d", this.arc)
.each(function(d) { this._currentArc = d; }); // store the initial values
// add text in the center of the donut
this.text = svg.append('text')
.attr("text-anchor", "middle")
.attr("dy", text_y)
.attr("d", percent)
if (typeof(percent) === "string") {
this.text.text(percent);
} else {
var self = this;
var timeout = setTimeout( function () {
clearTimeout(timeout);
path = path.data(pie(dataset.upper)); // update the data
path.transition().ease(d3.easeExp).duration('500').attrTween("d", function(a){
var progress = 0;
var format = d3.format(".0%");
// Store the displayed angles in _currentArc.
// Then, interpolate from _currentArc to the new angles.
// During the transition, _currentArc is updated in-place by d3.interpolate.
var i = d3.interpolate(this._currentArc, a);
var i2 = d3.interpolate(progress, percent);
this._currentArc = i(0);
return function(t) {
$(self.text).each(function(){
$(this).text( format(i2(t) / 100) );
});
return self.arc(i(t));
};
}); // redraw the arcs
}, 200);
}
},
init : function(){
$('.donut').each( function() {
var percent = $(this).data('donut');
app.numbers.drawDonutChart(
this,
percent,
190,
190,
".35em"
);
})
}
}
}
// initialize pie on scroll
window.onscroll = function() {
app.numbers.init();
}
HTML:
<section class="row numbers section-bkg section-bkg--blue">
<div class="container">
<div class="col-xs-12 col-sm-4">
<div class="donut" data-donut="42"></div>
</div>
<div class="col-xs-12 col-sm-4">
<div class="donut" data-donut="12"></div>
</div>
<div class="col-xs-12 col-sm-4">
<div class="donut" data-donut="86"></div>
</div>
</div>
</section>
知道我应该如何显示文字? 我很确定问题出在这里:
$(self.text).each(function(){
$(this).text( format(i2(t) / 100) );
});
答案 0 :(得分:0)
尽管混合jQuery和D3永远不是一个好主意(尽量避免它),但似乎这不是问题。问题似乎是您使用之前分配的self
来更改工厂内的文本。
一个解决方案(没有太多改变你的代码,当然有更好的方法来重构它)是根据当前的<path>
获取文本:
var self2 = this;//this is the transitioning path
return function(t) {
d3.select(self2.parentNode).select("text").text(format(i2(t) / 100));
return self.arc(i(t));
};
这是你的代码(没有jQuery):
var app = {};
var color = d3.scaleOrdinal(d3.schemeCategory10)
app.numbers = {
calcPerc: function(percent) {
return [percent, 100 - percent];
},
drawDonutChart: function(el, percent, width, height, text_y) {
width = typeof width !== undefined ? width : 290; //width
height = typeof height !== undefined ? height : 290; //height
text_y = typeof text_y !== undefined ? text_y : "-.10em";
var radius = Math.min(width, height) / 2;
var pie = d3.pie().sort(null);
var dataset = {
lower: this.calcPerc(0),
upper: this.calcPerc(percent)
}
//this.percents = percent;
this.arc = d3.arc()
.innerRadius(radius - 20)
.outerRadius(radius);
var svg = d3.select(el).append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var path = svg.selectAll("path")
.data(pie(dataset.lower))
.enter().append("path")
.attr("fill", function(d, i) {
return color(i)
})
.attr("d", this.arc)
.each(function(d) {
this._currentArc = d;
}); // store the initial values
// add text in the center of the donut
this.text = svg.append('text')
.attr("text-anchor", "middle")
.attr("dy", text_y)
.attr("d", percent)
this.text.text(percent);
var self = this;
path = path.data(pie(dataset.upper)); // update the data
path.transition().ease(d3.easeExp).duration(1000).attrTween("d", function(a) {
var progress = 0;
var format = d3.format(".0%");
// Store the displayed angles in _currentArc.
// Then, interpolate from _currentArc to the new angles.
// During the transition, _currentArc is updated in-place by d3.interpolate.
var i = d3.interpolate(this._currentArc, a);
var i2 = d3.interpolate(progress, percent);
this._currentArc = i(0);
var self2 = this;
return function(t) {
d3.select(self2.parentNode).select("text").text(format(i2(t) / 100));
return self.arc(i(t));
};
}); // redraw the arcs
},
init: function() {
d3.selectAll('.donut').each(function() {
var percent = d3.select(this).node().dataset.donut;
app.numbers.drawDonutChart(
this,
percent,
190,
190,
".35em"
);
})
}
}
app.numbers.init();
&#13;
<script src="https://d3js.org/d3.v4.min.js"></script>
<section class="row numbers section-bkg section-bkg--blue">
<div class="container">
<div class="col-xs-12 col-sm-4">
<div class="donut" data-donut="42"></div>
</div>
<div class="col-xs-12 col-sm-4">
<div class="donut" data-donut="12"></div>
</div>
<div class="col-xs-12 col-sm-4">
<div class="donut" data-donut="86"></div>
</div>
</div>
</section>
&#13;