gpt4 book ai didi

javascript - 间隔内更新的第一个 d3 转换未转换

转载 作者:行者123 更新时间:2023-12-03 16:47:12 28 4
gpt4 key购买 nike

我有一个 donut chart ,它被用作显示进度的一种方式。我没有办法向您展示圆环图,但代码很简单,可以复制和粘贴。
我添加了代码来向您展示一个示例。我尝试了各种不合理的方法来使过渡第一次工作。但由于某种原因,它仍然无法正常工作。网上的所有例子都非常相似,所以我不太确定为什么会这样。

    var data = [95, 5];
var pie = d3.pie().sort(null);
var svg = d3.select("svg"),
width = svg.attr("width"),
height = svg.attr("height"),
radius = Math.min(width, height) / 2;
var arc = d3.arc()
.innerRadius(60)
.outerRadius(radius);

function createdonut() {
g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
//Inner SVG Circle
svg.append("svg:circle")
.attr("cx", width / 2)
.attr("cy", height / 2)
.attr("r", 60)
.style("fill", "#ead4d4")
.append("g");
var color = d3.scaleOrdinal(['#4daf4a', '#377eb8', '#ff7f00', '#984ea3', '#e41a1c']);

//Generate groups

var arcs = g.selectAll("arc")
.data(pie(data))
.enter()
.append("g")
.attr("class", "arc")

//Draw arc paths
arcs.append("path")
.attr("fill", function (d, i) {
return color(i);
})
.attr("d", arc)
.on('mouseover', mouseover);

function mouseover(d, i) {
$('#percentage').html(i.data + ' units');
}
}
function updateDoNut(update) {
data[0] = data[0] - update;
data[1] = data[1] + update;

var path = d3.select("svg").selectAll("path").data(pie(data));

/*path.enter().append("path")
.attr("fill", function (d, i) {
return color[i];
})
.attr("d", arc);*/

path.transition().duration(100).attrTween("d", arcTween);
}
function arcTween(a) {
var i = d3.interpolate(this._current, a);
this._current = i(0);
return function (t) {
return arc(i(t));
};
}

createdonut();
//updateDoNut(0);
var inter = setInterval(function () { updateDoNut(5); }, 3000);
<script src="https://d3js.org/d3.v6.min.js"></script>
<div id="my_dataviz">
<svg width="300" height="200"> </svg>
<div id="percentage">0 units</div>
</div>

最佳答案

如果我们查看您的补间函数,我们会发现一个问题:

    var i = d3.interpolate(this._current, a);
this._current = i(0);
this.current当您第一次开始转换时未定义 - 那么 D3 如何在未定义和包含弧属性的对象之间进行插值?它没有。导致您看到的非过渡。设置 this._current附加弧时:
 arcs.append("path")
.attr("fill", function (d, i) {
return color(i);
})
.attr("d", arc)
.each(function(d) {
this._current = d;
})
.on('mouseover', mouseover);
现在,当您更新圆时,插值器有一个有效的起点,您应该会看到一个过渡:

var data = [95, 5];
var pie = d3.pie().sort(null);
var svg = d3.select("svg"),
width = svg.attr("width"),
height = svg.attr("height"),
radius = Math.min(width, height) / 2;
var arc = d3.arc()
.innerRadius(60)
.outerRadius(radius);

function createdonut() {
g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
//Inner SVG Circle
svg.append("svg:circle")
.attr("cx", width / 2)
.attr("cy", height / 2)
.attr("r", 60)
.style("fill", "#ead4d4")
.append("g");
var color = d3.scaleOrdinal(['#4daf4a', '#377eb8', '#ff7f00', '#984ea3', '#e41a1c']);

//Generate groups

var arcs = g.selectAll("arc")
.data(pie(data))
.enter()
.append("g")
.attr("class", "arc")

//Draw arc paths
arcs.append("path")
.attr("fill", function (d, i) {
return color(i);
})
.attr("d", arc)
.each(function(d) {
this._current = d;
})
.on('mouseover', mouseover);

function mouseover(d, i) {
$('#percentage').html(i.data + ' units');
}
}
function updateDoNut(update) {
data[0] = data[0] - update;
data[1] = data[1] + update;

var path = d3.select("svg").selectAll("path").data(pie(data));
path.transition().duration(2000).attrTween("d", arcTween);
}
function arcTween(a) {

var i = d3.interpolate(this._current, a);
this._current = i(0);
return function (t) {
return arc(i(t));
};
}

createdonut();
//updateDoNut(0);
var inter = setInterval(function () { updateDoNut(5); }, 3000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://d3js.org/d3.v6.min.js"></script>
<div id="my_dataviz">
<svg width="300" height="200"> </svg>
<div id="percentage">0 units</div>
</div>

为什么未定义和对象之间的这种插值不会产生错误?那么 D3-interpolate 将尝试非常努力地进行插值。在这种情况下,在 undefined 和一个对象之间,它将使用 d3-interpolateObject,它将按如下方式进行插值:

For each property in b, if there exists a corresponding property in a,a generic interpolator is created for the two elements usinginterpolate. If there is no such property, the static value from b isused in the template. (docs)


因此,由于未定义中没有属性,因此插值器仅对插值中的每个点使用静态值,因此在第一次更新时缺少转换:每个插值点都是相同的:端点值。

关于javascript - 间隔内更新的第一个 d3 转换未转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65361266/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com