我正在努力教自己如何在d3.js中进行交互式可视化,目前正在通过Elijah Meeks的D3.js In Action进行工作。我正在尝试使用三个按钮使他的饼图示例交互。我的补间做错了 - 我正在尝试保存当前显示的馅饼,以便转换到它和新选择的馅饼之间。但是,我当前的馅饼一直在重置为最初的馅饼。我认为这可能很简单,但我无法弄清楚我做错了什么。
有人可以告诉我要改变什么来使我的过渡工作吗?为了证明这个问题:
$ awk 'index($0,"/*"){f=1} index($0,"*/"){f=0} !f && /alex/{print}' file
alex is a nice man
.as-console-wrapper { max-height: 20% !important;}
答案 0 :(得分:1)
选择后,您永远不会将currentPie
的状态设置为新状态。我已经为转换添加了.on('end',
处理程序来设置此状态:
.on('end', function(){
currentPie = newPie;
});
运行代码:
<html>
<head>
<script src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<div id="viz">
<button id="0"> Stat 1 </button>
<button id="1"> Stat 2 </button>
<button id="2"> Stat 3 </button>
<br />
<svg style="width:1000px;height:500px;border:1px lightgray solid;"></svg>
</div>
<script>
var obj = [{name: "a",stat1: 10,stat2: 20,stat3: 30,},
{name: "b",stat1: 30,stat2: 20,stat3: 10,},
{name: "c",stat1: 15,stat2: 25,stat3: 50,}];
function piechart(data){
var currentPie = 0; //Initialize to stat1
var fillScale = d3.scaleOrdinal(d3.schemeCategory10);
var pieChart = d3.pie().sort(null);
var newArc = d3.arc().innerRadius(50).outerRadius(100);
// Create each pie chart
pieChart.value(d => d.stat1);
var stat1Pie = pieChart(data);
pieChart.value(d => d.stat2);
var stat2Pie = pieChart(data);
pieChart.value(d => d.stat3);
var stat3Pie = pieChart(data);
// Embed slices on each name
data.forEach( (d,i) => {
var slices = [stat1Pie[i], stat2Pie[i], stat3Pie[i]];
d.slices = slices;
});
d3.select("svg")
.append("g")
.attr("transform", "translate(250, 250)")
.selectAll("path")
.data(data)
.enter()
.append("path")
.attr("d", d => newArc(d.slices[currentPie]))
.attr("fill", (d,i) => fillScale(i))
.attr("stroke", "black")
.attr("stroke-width", "2px");
function transPie(d) {
var newPie = +this.id;
console.log("Transition from pie " +currentPie+ " to pie " + newPie);
d3.selectAll("path")
.transition()
.delay(500)
.duration(1500)
.attrTween("d", tweenPies)
.on('end', function(){
currentPie = newPie;
})
function tweenPies(d, i) {
console.log(i + ":start tween function \n current pie = " + currentPie + "\n new pie = "+newPie);
var currentAngleStart = d.slices[currentPie].startAngle;
var newAngleStart = d.slices[newPie].startAngle;
var currentAngleEnd = d.slices[currentPie].endAngle;
var newAngleEnd = d.slices[newPie].endAngle;
return t => {
var interpolateStartAngle = d3.interpolate(currentAngleStart, newAngleStart);
var interpolateEndAngle = d3.interpolate(currentAngleEnd, newAngleEnd);
d.startAngle = interpolateStartAngle(t);
d.endAngle = interpolateEndAngle(t);
return newArc(d);
};
};
};
d3.selectAll("button").on("click", transPie);
};
piechart(obj);
</script>
</body>
</html>
&#13;