1
我有以下的餅圖有一個非常漂亮的轉型:確保過渡完成
http://plnkr.co/edit/b4uLimUSZzxiPzAkNpBt?p=preview
餅圖的代碼如下:
function addPieChart(meas, dataFile) {
var width = 400,
height = 400,
radius = Math.min(width, height)/2.1,
color = d3.scale.ordinal()
.range(["#016da9", "#4c96d5"])
.domain([0, 1]);
//check if the svg already exists
var plot = d3.select("#svgPIEChart")
if (plot.empty()) {
var vis = d3.select("#pieChart")
.append("svg") //create the SVG element
.attr({
id: "svgPIEChart"
})
} else {
var vis = d3.select("#svgPIEChart")
vis.selectAll("*").remove();
};
//svg element
vis.attr({
//set the width and height of our visualization (these will be attributes of the <svg> tag
width: width,
height: height
});
//group of the svg element
var svg = vis
.append("g")
.attr({
'transform': "translate(" + width/2 + "," + height * .52 + ")"
});
var arc = d3.svg.arc()
.startAngle(function(d) {
return d.x;
})
.endAngle(function(d) {
return d.x + d.dx;
})
.outerRadius(function(d) {
return (d.y + d.dy)/(radius);
})
.innerRadius(function(d) {
return d.y/(radius);
});
d3.text(dataFile, function(text) {
var csv = d3.csv.parseRows(text);
var json = buildHierarchy(csv);
// it seems d3.layout.partition() can be either squares or arcs
var partition = d3.layout.partition()
.sort(null)
.size([2 * Math.PI, radius * radius])
.value(function(d) {
return d.Revenue;
});
var path = svg.data([json]).selectAll(".theArc")
.data(partition.nodes)
.enter()
.append("path")
.attr("class", "theArc") //<<<<<<<<<<new jq
.attr("id", function(d, i) {
return "theArc_" + i;
}) //Give each slice a unique ID //<<<<<<<<<<new jq
.attr("display", function(d) {
return d.depth ? null : "none";
})
.attr("d", arc)
.style("stroke", "#fff")
.style("fill", function(d) {
return color((d.children ? d : d.parent).name);
})
.attr("fill-rule", "evenodd")
.style("opacity", 1)
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.on("click", up)
.each(stash);
// path.each(stash).on("click", up)
//this is a start>>>>>
path
.append("title") //mouseover title showing the figures
.text(function(d) {
return d.name + ": " + formatAsShortInteger(d.Revenue);
});
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
svg.data([json]).selectAll(".theTxts")
.data(partition.nodes)
.enter()
.append("text")
.attr("class", "theTxts")
.attr("dx", 10) //Move the text from the start angle of the arc
.attr("dy", 15) //Move the text down
.append("textPath")
.attr("class", "foo")
.attr("xlink:href", function(d, i) {
return "#theArc_" + i;
})
.text(function(d) {
if ((d.name != 'root') && ((d.name != 'B T') || (currentMeasure != 'W'))) {
return d.name;
}
})
.on("click", up) //<<<new jq;
svg.append("text")
.attr({
x: "0",
y: "0",
'class': "title",
"id": "titleX",
'text-anchor': "middle"
})
.text(currentMeasure + " split")
//>>
.append("tspan")
.attr({
dy: "1.1em",
x: 0,
'text-anchor': "middle"
})
.text("for " + latestMth)
.attr("class", "title");
d3.selectAll("input").on("change", function change() {
value = createValueFunc(this.value);
currentMeasure = this.value;
var path2 = svg.data([json]).selectAll(".theArc");
path2
.data(partition.value(value).nodes)
.transition()
.duration(1500)
.attrTween("d", arcTween)
//to update the tooltips
svg.selectAll("title")
.text(function(d) {
return d.name + ": " + formatAsShortInteger(value(d));
});
svg.selectAll("textPath")
.text(function(d) {
if ((d.name != 'root') && ((d.name != 'B T') || (currentMeasure != 'W'))) {
return d.name;
}
});
// the following deletes what was originally created and then recreates the text
svg.selectAll("#titleX").remove();
svg.append("text")
.attr({
x: "0",
y: "0",
'class': "title",
"id": "titleX",
'text-anchor': "middle"
})
.text(currentMeasure + " split")
.append("tspan")
.attr({
dy: "1.1em",
x: 0,
'text-anchor': "middle"
})
.text("for " + latestMth)
.attr("class", "title");
addProdTitl();
updateTOPbarChart(currentGrp, currentMeasure, currentColr);
updateBOTbarChart(currentGrp, currentMeasure, currentColr);
});
function mouseover() {
d3.select(this)
.transition()
.duration(200)
.style("opacity", 0.9);
};
function mouseout() {
d3.select(this)
.transition()
.duration(200)
.style("opacity", 1);
};
// update bar chart when user selects piece of the pie chart
function up(d, i) {
currentGrp = d.name;
// (d.children ? d : d.parent).name
currentColr = color((d.children ? d : d.parent).name); // color(d.name);
addProdTitl();
updateTOPbarChart(d.name, currentMeasure, currentColr); //color(d.name));
updateBOTbarChart(d.name, currentMeasure, currentColr); //color(d.name));
};
// Stash the old values for transition.
function stash(d) {
d.x0 = d.x;
d.dx0 = d.dx;
};
// Interpolate the arcs in data space.
function arcTween(a) {
var i = d3.interpolate({
x: a.x0,
dx: a.dx0
}, a);
return function(t) {
var b = i(t);
a.x0 = b.x;
a.dx0 = b.dx;
return arc(b);
};
};
});
};
如果更改的選擇單選按鈕,然後單擊該部分未完成其轉換的餅圖部分,因爲我認爲它決定需要轉到其「開」事件。
如何確保過渡完成? (並且餅圖不會執行pac-man模仿)
(調升),這是極好的。現在丟失的一小部分功能是,當我將鼠標懸停在切片上時,最初呈現視覺效果時,不透明度不會轉變爲指示光標懸停在其上。在事件'selectAll(「input」)。on(「change」)後面,發生了這種功能返回,即一旦用戶點擊單選按鈕,我可以在某處添加一行代碼,這樣當視覺初始化時事件到單選按鈕被觸發,以確保不透明度過渡到位? – whytheq
是的,錯過了那個部分,我已經編輯了我的答案,最初需要附加聽衆(就像以前那樣)。稍後改變無線電價值,在轉換開始時分離聆聽者,轉換後聆聽者返回。 – Cyril
酷 - 您是否需要在視覺第一次呈現時強制更改代碼中的無線電值 - 或僅僅需要添加回我的聽衆?(...我想問的原因是,有很多代碼行,所以只需檢查是否添加了任何代碼行,我可能會發現,除了在代碼段中指定的代碼行以上) – whytheq