簡體   English   中英

間隔內更新的第一個 d3 轉換未轉換

[英]First d3 transition on update inside interval is not transitioning

我有一個甜甜圈圖,它被用作顯示進度的一種方式。 我沒有辦法向您展示圓環圖,但代碼很簡單,可以復制和粘貼。

我添加了代碼來向您展示一個示例。 我嘗試了各種不合理的方法來使過渡第一次工作。 但由於某種原因,它仍然無法正常工作。 網上的所有例子都非常相似,所以我不太確定為什么會這樣。

 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>

如果我們查看您的補間 function 我們會發現一個問題:

    var i = d3.interpolate(this._current, a);
    this._current = i(0);

this.current在您第一次開始轉換時未定義 - 那么 D3 如何在未定義和 object 連續弧屬性之間進行插值? 它沒有。 導致您看到的非過渡。 附加弧時設置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>

為什么 undefined 和 object 之間的這種插值不會產生錯誤? 那么 D3-interpolate 將嘗試非常努力地進行插值。 在這種情況下,在 undefined 和 object 之間,它將使用 d3-interpolateObject,它將按如下方式進行插值:

對於 b 中的每個屬性,如果 a 中存在相應的屬性,則使用 interpolate 為這兩個元素創建一個通用插值器。 如果沒有這樣的屬性,則在模板中使用來自 b 的 static 值。 文檔

因此,由於未定義中沒有屬性,因此插值器僅對插值中的每個點使用 static 值,因此在第一次更新時缺少過渡:每個插值點都是相同的:端點值。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM