我有以下原型代码。它是一个下拉列表,其中包含用于更改饼图的关键值,它可以正常工作。但在我的实际代码中,我需要通过键选择而不是数据的索引。看起来应该很容易,我只是想念它。所以要重申:代码使用下拉列表的索引,我需要它来使用实际键[下拉列表的值]。
有问题的代码是使用更改功能的地方。
// fake data
// data.tsv
//region fruit count
//East Apples 53245
//West Apples 28479
//South Apples 19697
//North Apples 24037
//Central Apples 40245
//East Oranges 200
//South Oranges 200
//Central Oranges 200
var width = 960,
height = 500,
radius = Math.min(width, height) / 2;
var color = d3.scale.category20();
var pie = d3.layout.pie()
.value(function(d) { return d.count; })
.sort(null);
var arc = d3.svg.arc()
.innerRadius(radius - 100)
.outerRadius(radius - 20);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var path = svg.selectAll("path");
d3.tsv("data.tsv", type, function(error, data) {
var regionsByFruit = d3.nest()
.key(function(d) { return d.fruit; })
.entries(data)
.reverse();
var select = d3.select("form").append("div")
.append("select")
.on("change", function() {
change(regionsByFruit[d3.event.target.selectedIndex]); })
.selectAll("option")
.data(regionsByFruit)
.enter()
.append("option");
select.selectAll("option")
//.attr("type", "radio")
.attr("name", "fruit")
.attr("value", function(d) { return d.key; })
.filter(function(d, i) { return !i; });
select.append("span")
.text(function(d) { return d.key; });
function change(region) {
var data0 = path.data(),
data1 = pie(region.values);
path = path.data(data1, key);
path.enter().append("path")
.each(function(d, i) { this._current = findNeighborArc(i, data0, data1, key) || d; })
.attr("fill", function(d) { return color(d.data.region); })
.append("title")
.text(function(d) { return d.data.region; });
path.exit()
.datum(function(d, i) { return findNeighborArc(i, data1, data0, key) || d; })
.transition()
.duration(750)
.attrTween("d", arcTween)
.remove();
path.transition()
.duration(750)
.attrTween("d", arcTween);
}
});
function key(d) {
return d.data.region;
}
function type(d) {
d.count = +d.count;
return d;
}
function findNeighborArc(i, data0, data1, key) {
var d;
return (d = findPreceding(i, data0, data1, key)) ? {startAngle: d.endAngle, endAngle: d.endAngle}
: (d = findFollowing(i, data0, data1, key)) ? {startAngle: d.startAngle, endAngle: d.startAngle}
: null;
}
// Find the element in data0 that joins the highest preceding element in data1.
function findPreceding(i, data0, data1, key) {
var m = data0.length;
while (--i >= 0) {
var k = key(data1[i]);
for (var j = 0; j < m; ++j) {
if (key(data0[j]) === k) return data0[j];
}
}
}
// Find the element in data0 that joins the lowest following element in data1.
function findFollowing(i, data0, data1, key) {
var n = data1.length, m = data0.length;
while (++i < n) {
var k = key(data1[i]);
for (var j = 0; j < m; ++j) {
if (key(data0[j]) === k) return data0[j];
}
}
}
function arcTween(d) {
var i = d3.interpolate(this._current, d);
this._current = i(0);
return function(t) { return arc(i(t)); };
}
ody {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: auto;
position: relative;
width: 960px;
}
text {
font: 10px sans-serif;
}
form {
position: absolute;
right: 10px;
top: 10px;
}
input {
margin: 0 7px;
}
<!DOCTYPE html>
<meta charset="utf-8">
<form></form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
答案 0 :(得分:1)
我无法运行您提供的代码,但我设法调整它以实现我认为您想要的。我采取的方法如下:
var select = d3.select("form").append("div")
.append("select")
.on('change', updatePie) // run this fn when select value changes
function updatePie(d, i) {
var selectedFruit = this.value; // get the value of the selected option which is your key
var newData = regionsByFruit.filter(function(value) { // filter data so you only get the data with the given key
return value.key === selectedFruit;
});
// Update data in elements
var updatee = svg.selectAll(".arc").data(pie(newData[0].values));
// Do exit, update and addition of nodes logic
}