只是想知道是否可以用d3做这样的事情?
当您点击某个饼图切片时,切片会单击?
到目前为止创建饼图只是想知道我是否可以添加此功能
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
}
.arc path {
stroke: #fff;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var width = 960,
height = 500,
radius = Math.min(width, height) / 2;
var color = d3.scale.ordinal()
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);
var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(0);
var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d.population; });
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
d3.csv("data.csv", function(error, data) {
data.forEach(function(d) {
d.population = +d.population;
});
var g = svg.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.age); });
g.append("text")
.attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.data.age; });
});
</script>
数据来自csv文件。
由于
答案 0 :(得分:11)
您可以增加饼图的圆弧半径以突出显示。 JSFiddle
var arcOver = d3.svg.arc()
.outerRadius(r + 10);
g.append("path")
.attr("d", arc)
.style("fill", function(d) { return color(d.data.age); })
.on("mouseenter", function(d) {
d3.select(this)
.attr("stroke","white")
.transition()
.duration(1000)
.attr("d", arcOver)
.attr("stroke-width",6);
})
.on("mouseleave", function(d) {
d3.select(this).transition()
.attr("d", arc)
.attr("stroke","none");
});
答案 1 :(得分:2)
我更喜欢更改 Radius 而不是笔画,因为它可以为您提供流畅,更好的动画......
使用这样的函数:
function pathEnter() {
t = d3.select(this);
t.transition()
.attr('d', pathIn);
}
运行以下代码以查看互动:
<!DOCTYPE html>
<meta charset="utf-8">
<style>
.arc text {
font: 10px sans-serif;
text-anchor: middle;
}
.arc path {
stroke: #fff;
}
</style>
<svg width="520" height="280"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg = d3.select("svg"),
width = +svg.attr("width"),
height = +svg.attr("height"),
radius = Math.min(width, height) / 2 - 20,
g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var color = d3.scaleOrdinal(d3.schemeCategory10);
var pie = d3.pie()
.sort(null)
.value(function(d) {
return d.population;
});
var path = d3.arc()
.outerRadius(radius)
.innerRadius(0);
var pathIn = d3.arc()
.outerRadius(radius + 6)
.innerRadius(0);
function pathEnter() {
t = d3.select(this);
t.transition()
.attr('d', pathIn);
}
function pathOut() {
t = d3.select(this);
t.transition()
.attr('d', path);
}
var label = d3.arc()
.outerRadius(radius - 40)
.innerRadius(radius - 40);
data = [{
age: '<5',
population: '2704659'
},
{
age: '5-13',
population: '4499890'
},
{
age: '14-17',
population: '2159981'
},
{
age: '18-24',
population: '3853788'
},
{
age: '25-44',
population: '14106543'
},
{
age: '45-64',
population: '8819342'
},
{
age: '≥65',
population: '612463'
},
];
data.population = +data.population;
var arc = g.selectAll(".arc")
.data(pie(data))
.enter().append("g")
.attr("class", "arc");
arc.append("path")
.attr("d", path)
.on('mouseenter', pathEnter)
.on('mouseout', pathOut)
.attr("fill", function(d) {
return color(d.data.age);
});
arc.append("text")
.attr("transform", function(d) {
return "translate(" + label.centroid(d) + ")";
})
.attr("dy", "0.35em")
.text(function(d) {
return d.data.age;
});
</script>
&#13;
答案 2 :(得分:2)
使用属性 transform =&#34; translate(x,y)&#34; 可以实际移动每个切片。
http://jsfiddle.net/qkHK6/3306/
以@Gilsha的答案为基础(我知道这个问题已经过时了,但我认为我已将此答案用于存档目的)...
g.append("path")
.attr("d", arc)
.attr("opacity", "1.0")
.on("mouseenter", function (d) {
var arcOver = d3.arc()
.outerRadius(radius).innerRadius(0).startAngle(d.startAngle + 0.01).endAngle(d.endAngle - 0.01);
var transformText = getTranslate(d.startAngle + 0.01, d.endAngle - 0.01, 20);
d3.select(this)
.attr("d", arcOver)
.transition()
.duration(200).ease(d3.easeBack)
.attr("transform", transformText)
.attr("style", "fill: rgb(102, 102, 102)");
})
.on("mouseleave", function (d) {
d3.select(this)
.attr("d", arc)
.transition().ease(d3.easeBack)
.duration(600)
.attr("transform", "translate(0,0)")
.attr("style", "fill: " + color(d.data));
})
.style("fill", function (d) { return color(d.data); });
同样 d3.arc()来自版本4.
以下助手方法:
getTranslate = function (startAngle, endAngle, distance) {
var xTranslate, yTranslate;
var startQ = getQuadrant(startAngle);
var endQ = getQuadrant(endAngle);
//Assume there are 7 possibilities since last slice always ends at Tau or 12 o'clock when doing a d.endAngle
switch (true) {
case (startQ == 1 && endQ == 1):
xTranslate = distance * 0.5;
yTranslate = distance * -1.5;
break;
case (startQ == 1 && endQ == 4):
xTranslate = distance * 1.5;
yTranslate = distance * 0.5;
break;
case (startQ == 4 && endQ == 4):
xTranslate = distance * 0.5;
yTranslate = distance * 1.5;
break;
case (startQ == 4 && endQ == 3):
xTranslate = distance * -0.5;
yTranslate = distance * 1.5;
break;
case (startQ == 3 && endQ == 3):
xTranslate = distance * -1.5;
yTranslate = distance * 0.5;
break;
case (startQ == 3 && endQ == 2):
xTranslate = distance * -1.5;
yTranslate = distance * -0.5;
break;
case (startQ == 2 && endQ == 2):
xTranslate = distance * -0.5;
yTranslate = distance * -1.5;
break;
}
return "translate(" + xTranslate + "," + yTranslate + ")";
}
getQuadrant = function (angle) {
switch (true) {
case angle < (Math.PI * 0.5):
return 1;
break;
case angle >= (Math.PI * 1.5):
return 2;
break;
case ((Math.PI < angle) && angle <= (Math.PI * 1.5)):
return 3;
break;
default:
return 4;
}
}