我正在尝试通过从输入中获取数据来制作d3饼图。点击功能在第一次单击时无需转换即可工作。 当我第一次单击按钮饼图更新时,但没有过渡。下次它正常工作。
var input = document.querySelectorAll(".input-block__item")
var data = [input[0].value, input[1].value, input[2].value, input[3].value]
var width = 560,
height = 500,
radius = Math.min(width, height) / 2;
var color = d3.scaleOrdinal(d3.schemeAccent)
var arc = d3.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.pie()
.sort(null)
.value(function(d,i) { return d; });
var svg = d3.select(".pie-block").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var block = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc")
block.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data); });
block.data(pie(data))
.transition()
.duration(1000)
.ease(d3.easeLinear)
.attrTween("d", arc2Tween);
//update
function arc2Tween(d) {
var interp = d3.interpolate(this._current, d);
this._current = d;
return function(t) {
var tmp = interp(t);
return arc(tmp);
}
};
d3.select(".mybtn")
.on("click", function update() {
var data = [input[0].value, input[1].value, input[2].value, input[3].value]
block.select("path")
.data(pie(data))
.transition()
.duration(1000)
.ease(d3.easeLinear)
.attrTween("d", arc2Tween);
});
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<a href="#" class="mybtn">Show</a>
<div class="container">
<div class="input-block">
<input type="text" value="1" class="input-block__item input-block__item--1">
<input type="text" value="2" class="input-block__item input-block__item--2">
<input type="text" value="3" class="input-block__item input-block__item--3">
<input type="text" value="4" class="input-block__item input-block__item--4">
</div>
<div class="pie-block">
</div>
</div>
答案 0 :(得分:0)
此pen in CodePen应显示按预期工作的转换。说实话,我没有一个伟大的最佳实践来到这里。我只是注意到在原始代码片段中,数据绑定似乎在第一次按键单击时运行了两次:一次是原始数据,紧接着是新数据。
我尝试将更新逻辑分离到D3 general update pattern之后的函数。我的第一次尝试并没有真正起作用。我将var block
移回外部范围,并将enter
逻辑移回外部范围,然后它开始工作。
var input = document.querySelectorAll(".input-block__item");
var data = [input[0].value, input[1].value, input[2].value, input[3].value];
var width = 560,
height = 500,
radius = Math.min(width, height) / 2;
var color = d3.scaleOrdinal(d3.schemeAccent)
var arc = d3.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.pie()
.sort(null)
.value(function(d,i) { return d; });
var svg = d3.select(".pie-block").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
// join
var block = svg
.selectAll(".arc")
.data(pie(data));
// enter
block.enter()
.append("g")
.attr("class", "arc")
.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data); });
// initial data update
update(data);
function arc2Tween(d) {
var interp = d3.interpolate(this._current, d);
this._current = d;
return function(t) {
var tmp = interp(t);
return arc(tmp);
}
};
d3.select(".mybtn")
.on("click", function () {
update([input[0].value, input[1].value, input[2].value, input[3].value]);
});
function update(data) {
// join
block = svg
.selectAll(".arc")
.data(pie(data));
// update
block.select("path")
.transition()
.duration(1000)
.ease(d3.easeLinear)
.attrTween("d", arc2Tween);
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://d3js.org/d3-scale-chromatic.v1.min.js"></script>
<a href="#" class="mybtn">Show</a>
<div class="container">
<div class="input-block">
<input type="text" value="1" class="input-block__item input-block__item--1">
<input type="text" value="2" class="input-block__item input-block__item--2">
<input type="text" value="3" class="input-block__item input-block__item--3">
<input type="text" value="4" class="input-block__item input-block__item--4">
</div>
<div class="pie-block">
</div>
</div>