我是很新的D3,並通過努力把事情做好了工作。我正在嘗試配置此示例here以適當更新新數據和轉換。如何在更新d3.js圖表之前乾淨地刪除數據?
下面是代碼筆我已經配置(點擊提交更新) http://codepen.io/anon/pen/pbjLRW?editors=1010
從我可以收集,使用.exit的一些變化()需要一個乾淨的數據轉換,但看完後一些教程我仍然很難知道它是如何工作的。我已經看到了在調用draw函數之前簡單地移除容器的例子,但是在我的經驗有限的情況下,它會在更改數據時導致閃爍,所以我不確定這是否是最佳實踐?
現在,我不知道爲什麼數據是不是在我codepen正確更新,但我主要關注的是試圖獲得過渡權。理想情況下,我想知道如何在更改數據時移動針頭,因此它會從90> 40例如90而不是90> 0> 40.
但是,我一定會找出原因一旦點擊鏈接的codepen中的提交,它就不會在同一位置重繪自己。
這裏是我的更新功能;
function updateGuage() {
d3.selectAll("text").remove()
d3.selectAll('.needle').remove()
chart.remove()
name = "qwerty";
value = "25";
drawGuage();
}
初始繪製;
function drawGuage() {
percToDeg = function(perc) {
return perc * 360;
};
percToRad = function(perc) {
return degToRad(percToDeg(perc));
};
degToRad = function(deg) {
return deg * Math.PI/180;
};
// Create SVG element
svg = el.append('svg').attr('width', width + margin.left + margin.right).attr('height', height + margin.top + margin.bottom);
// Add layer for the panel
chart = svg.append('g').attr('transform', "translate(" + ((width + margin.left)/2) + ", " + ((height + margin.top)/2) + ")");
chart.append('path').attr('class', "arc chart-first");
chart.append('path').attr('class', "arc chart-second");
chart.append('path').attr('class', "arc chart-third");
arc3 = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth)
arc2 = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth)
arc1 = d3.svg.arc().outerRadius(radius - chartInset).innerRadius(radius - chartInset - barWidth)
repaintGauge = function() {
perc = 0.5;
var next_start = totalPercent;
arcStartRad = percToRad(next_start);
arcEndRad = arcStartRad + percToRad(perc/3);
next_start += perc/3;
arc1.startAngle(arcStartRad).endAngle(arcEndRad);
arcStartRad = percToRad(next_start);
arcEndRad = arcStartRad + percToRad(perc/3);
next_start += perc/3;
arc2.startAngle(arcStartRad + padRad).endAngle(arcEndRad);
arcStartRad = percToRad(next_start);
arcEndRad = arcStartRad + percToRad(perc/3);
arc3.startAngle(arcStartRad + padRad).endAngle(arcEndRad);
chart.select(".chart-first").attr('d', arc1);
chart.select(".chart-second").attr('d', arc2);
chart.select(".chart-third").attr('d', arc3);
}
/////////
var texts = svg.selectAll("text")
.data(dataset)
.enter();
texts.append("text")
.text(function() {
return dataset[0].metric;
})
.attr('id', "Name")
.attr('transform', "translate(" + ((width + margin.left)/6) + ", " + ((height + margin.top)/1.5) + ")")
.attr("font-size", 25)
.style("fill", "#000000");
var trX = 180 - 210 * Math.cos(percToRad(percent/2));
var trY = 195 - 210 * Math.sin(percToRad(percent/2));
// (180, 195) are the coordinates of the center of the gauge.
displayValue = function() {
texts.append("text")
.text(function() {
return dataset[0].value;
})
.attr('id', "Value")
.attr('transform', "translate(" + trX + ", " + trY + ")")
.attr("font-size", 18)
.style("fill", '#000000');
}
texts.append("text")
.text(function() {
return 0;
})
.attr('id', 'scale0')
.attr('transform', "translate(" + ((width + margin.left)/100) + ", " + ((height + margin.top)/2) + ")")
.attr("font-size", 15)
.style("fill", "#000000");
texts.append("text")
.text(function() {
return gaugeMaxValue/2;
})
.attr('id', 'scale10')
.attr('transform', "translate(" + ((width + margin.left)/2.15) + ", " + ((height + margin.top)/30) + ")")
.attr("font-size", 15)
.style("fill", "#000000");
texts.append("text")
.text(function() {
return gaugeMaxValue;
})
.attr('id', 'scale20')
.attr('transform', "translate(" + ((width + margin.left)/1.03) + ", " + ((height + margin.top)/2) + ")")
.attr("font-size", 15)
.style("fill", "#000000");
var Needle = (function() {
//Helper function that returns the `d` value for moving the needle
var recalcPointerPos = function(perc) {
var centerX, centerY, leftX, leftY, rightX, rightY, thetaRad, topX, topY;
thetaRad = percToRad(perc/2);
centerX = 0;
centerY = 0;
topX = centerX - this.len * Math.cos(thetaRad);
topY = centerY - this.len * Math.sin(thetaRad);
leftX = centerX - this.radius * Math.cos(thetaRad - Math.PI/2);
leftY = centerY - this.radius * Math.sin(thetaRad - Math.PI/2);
rightX = centerX - this.radius * Math.cos(thetaRad + Math.PI/2);
rightY = centerY - this.radius * Math.sin(thetaRad + Math.PI/2);
return "M " + leftX + " " + leftY + " L " + topX + " " + topY + " L " + rightX + " " + rightY;
};
function Needle(el) {
this.el = el;
this.len = width/2.5;
this.radius = this.len/8;
}
Needle.prototype.render = function() {
this.el.append('circle').attr('class', 'needle-center').attr('cx', 0).attr('cy', 0).attr('r', this.radius);
return this.el.append('path').attr('class', 'needle').attr('id', 'client-needle').attr('d', recalcPointerPos.call(this, 0));
};
Needle.prototype.moveTo = function(perc) {
var self,
oldValue = this.perc || 0;
this.perc = perc;
self = this;
// Reset pointer position
this.el.transition().delay(100).ease('quad').duration(200).select('.needle').tween('reset-progress', function() {
return function(percentOfPercent) {
var progress = (1 - percentOfPercent) * oldValue;
repaintGauge(progress);
return d3.select(this).attr('d', recalcPointerPos.call(self, progress));
};
});
this.el.transition().delay(300).ease('bounce').duration(1500).select('.needle').tween('progress', function() {
return function(percentOfPercent) {
var progress = percentOfPercent * perc;
repaintGauge(progress);
return d3.select(this).attr('d', recalcPointerPos.call(self, progress));
};
});
};
return Needle;
})();
needle = new Needle(chart);
needle.render();
needle.moveTo(percent);
setTimeout(displayValue, 1350);
}
任何幫助/建議是非常讚賞,
感謝
我不明白你如何/爲什麼要調用.exit()。remove();與您要求數據輸入的功能相同? – since095