我到处都在寻找解决方案,我已经尝试了所有方法,但无济于事!
当我单击以更新数据和饼图时,过渡无法正常工作,并且打印错误(错误:属性d:预期的弧形标志(“ 0”或“ 1”))超过100次。有人可以帮我吗?
这是代码的开头:
// set the dimensions and margins of the graph
var width = 320
height = 450
margin = 40
// The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin.
var radius = Math.min(width, height) / 2 - margin
// append the svg object to the div called 'my_dataviz'
var svg = d3.select("#recipe-graph")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
// create 2 data_set
//Aromatic Profile
//a: woody, b: floral, c: resinous, d: herbaceus, e: citrus, f: minty,
var data1 = {a:56.2, b: 25, c:18.8} //woody, floral, resinous
var data2 = {b: 31.2, d: 50, e:18.8} //floral, herbaceus, citus
var data3 = {d: 33.3, e:11.1, f: 55.6} //herbaceous, citrus, minty
var data4 = {b: 56.2, c: 43.8} //floral, resinous
var data5 = {b: 82.6, e: 17.4} //floral, citrus
// set the color scale
var color = d3.scaleOrdinal()
.domain(["a", "b", "c", "d", "e", "f"])
.range(d3.schemeDark2);
我相信问题出在下面。 (我正在使用最新的d3.js库)
// A function that create / update the plot for a given variable:
function update(data) {
// Compute the position of each group on the pie:
var pie = d3.pie()
.value(function(d) {return d.value; })
.sort(function(a, b) { console.log(a) ; return d3.ascending(a.key, b.key);} ) // This make sure that group order remains the same in the pie chart
var data_ready = pie(d3.entries(data))
// map to data
var u = svg.selectAll("path")
.data(data_ready)
// Build the pie chart: Basically, each part of the pie is a path that we build using the arc function.
u
.enter()
.append('path')
.merge(u)
.transition()
.duration(1000)
.attr('d', d3.arc()
.innerRadius(0)
.outerRadius(radius)
)
.attr('fill', function(d){ return(color(d.data.key)) })
.attr("stroke", "white")
.style("stroke-width", "2px")
.style("opacity", 1)
// remove the group that is not present anymore
u
.exit()
.remove()
}
// Initialize the plot with the first dataset
update(data1)
//Change Recipe according to button selected
function selectCategory(category, results) {
var postResults = document.getElementById(results);
postResults.innerHTML = category;
}
这在D3 API中没有很好的记录,但是您将找到几个如何在线转换弧的示例。您面临的最大问题(以及所导致错误的原因)是d
属性是一个长而复杂的字符串,而transition.attr
提供的默认插值器d3.interpolateString
却没有不知道如何插值。
解决方案是将attrTween
与自定义插值器一起使用。为此,您必须保存每个元素的先前基准。为此,我喜欢使用局部变量:
var local = d3.local();
selection.each(function(d) {
local.set(this, d)
})
然后,在attrTween
中:
transition.attrTween('d', function(d) {
var i = d3.interpolate(local.get(this), d);
local.set(this, i(0));
return function(t) {
return arc(i(t));
};
})
这是您的代码,从data1
转换为data2
:
// set the dimensions and margins of the graph
var width = 320
height = 450
margin = 40
// The radius of the pieplot is half the width or half the height (smallest one). I subtract a bit of margin.
var radius = Math.min(width, height) / 2 - margin
var local = d3.local();
// append the svg object to the div called 'my_dataviz'
var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
// create 2 data_set
//Aromatic Profile
//a: woody, b: floral, c: resinous, d: herbaceus, e: citrus, f: minty,
var data1 = {
a: 56.2,
b: 25,
c: 18.8
} //woody, floral, resinous
var data2 = {
b: 31.2,
d: 50,
e: 18.8
} //floral, herbaceus, citus
var data3 = {
d: 33.3,
e: 11.1,
f: 55.6
} //herbaceous, citrus, minty
var data4 = {
b: 56.2,
c: 43.8
} //floral, resinous
var data5 = {
b: 82.6,
e: 17.4
} //floral, citrus
// set the color scale
var color = d3.scaleOrdinal()
.domain(["a", "b", "c", "d", "e", "f"])
.range(d3.schemeDark2);
var arc = d3.arc()
.innerRadius(0)
.outerRadius(radius)
// A function that create / update the plot for a given variable:
function update(data) {
// Compute the position of each group on the pie:
var pie = d3.pie()
.value(function(d) {
return d.value;
})
.sort(function(a, b) {
return d3.ascending(a.key, b.key);
}) // This make sure that group order remains the same in the pie chart
var data_ready = pie(d3.entries(data))
// map to data
var u = svg.selectAll("path")
.data(data_ready)
// Build the pie chart: Basically, each part of the pie is a path that we build using the arc function.
u
.enter()
.append('path')
.each(function(d) {
local.set(this, d)
})
.merge(u)
.transition()
.duration(1000)
.attrTween('d', function(d) {
var i = d3.interpolate(local.get(this), d);
local.set(this, i(0));
return function(t) {
return arc(i(t));
};
})
.attr('fill', function(d) {
return (color(d.data.key))
})
.attr("stroke", "white")
.style("stroke-width", "2px")
.style("opacity", 1)
// remove the group that is not present anymore
u
.exit()
.remove()
}
// Initialize the plot with the first dataset
update(data1)
d3.timeout(function() {
update(data2)
}, 1000);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>