我是d3.js的新手任何人帮助我,我想要以中心总价值的圆环收入图表,两个标签分开外圈。但是,我不能在圆圈和中间总值之外再添加一个标签。 这是我的代码,
<script src="http://d3js.org/d3.v3.min.js"></script>
<div id="pie-chart"></div>
<script>
var div = d3.select("body").append("div").attr("class", "toolTip");
var w = 650;
var h = 400;
var r = 100;
var ir = 75;
var textOffset = 24;
var tweenDuration = 1050;
//OBJECTS TO BE POPULATED WITH DATA LATER
var lines, valueLabels, nameLabels;
var pieData = [];
var oldPieData = [];
var filteredPieData = [];
//D3 helper function to populate pie slice parameters from array data
var donut = d3.layout.pie().value(function(d){
return d.itemValue;
});
//D3 helper function to create colors from an ordinal scale
var color = d3.scale.category20c();
//D3 helper function to draw arcs, populates parameter "d" in path object
var arc = d3.svg.arc()
.startAngle(function(d){ return d.startAngle; })
.endAngle(function(d){ return d.endAngle; })
.innerRadius(ir)
.outerRadius(r);
///////////////////////////////////////////////////////////
// GENERATE FAKE DATA /////////////////////////////////////
///////////////////////////////////////////////////////////
var data;
var dataStructure = [
{
"data":[
{
"itemLabel":"Suv",
"itemValue":7165.0
},
{
"itemLabel":"Sedans",
"itemValue":2430.0
},
{
"itemLabel":"Hatchback",
"itemValue":1998.0
},
{
"itemLabel":"VAN",
"itemValue": 898.0
},
],
"label":"2007"
},
];
///////////////////////////////////////////////////////////
// CREATE VIS & GROUPS ////////////////////////////////////
///////////////////////////////////////////////////////////
var vis = d3.select("#pie-chart").append("svg:svg")
.attr("width", w)
.attr("height", h);
//GROUP FOR ARCS/PATHS
var arc_group = vis.append("svg:g")
.attr("class", "arc")
.attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");
//GROUP FOR LABELS
var label_group = vis.append("svg:g")
.attr("class", "label_group")
.attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");
//GROUP FOR CENTER TEXT
var center_group = vis.append("svg:g")
.attr("class", "center_group")
.attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");
//PLACEHOLDER GRAY CIRCLE
// var paths = arc_group.append("svg:circle")
// .attr("fill", "#EFEFEF")
// .attr("r", r);
///////////////////////////////////////////////////////////
// CENTER TEXT ////////////////////////////////////////////
///////////////////////////////////////////////////////////
//WHITE CIRCLE BEHIND LABELS
var whiteCircle = center_group.append("svg:circle")
.attr("fill", "white")
.attr("r", ir);
///////////////////////////////////////////////////////////
// STREAKER CONNECTION ////////////////////////////////////
///////////////////////////////////////////////////////////
// to run each time data is generated
function update(number) {
data = dataStructure[number].data;
oldPieData = filteredPieData;
pieData = donut(data);
var sliceProportion = 0; //size of this slice
filteredPieData = pieData.filter(filterData);
function filterData(element, index, array) {
element.name = data[index].itemLabel;
element.value = data[index].itemValue;
sliceProportion += element.value;
return (element.value > 0);
}
//DRAW ARC PATHS
paths = arc_group.selectAll("path").data(filteredPieData);
paths.enter().append("svg:path")
.attr("stroke", "white")
.attr("stroke-width", 0.5)
.attr("fill", function(d, i) { return color(i); })
.transition()
.duration(tweenDuration)
.attrTween("d", pieTween);
paths
.transition()
.duration(tweenDuration)
.attrTween("d", pieTween);
paths.exit()
.transition()
.duration(tweenDuration)
.attrTween("d", removePieTween)
.remove();
paths.on("mousemove", function(d){
div.style("left", d3.event.pageX+10+"px");
div.style("top", d3.event.pageY-25+"px");
div.style("display", "inline-block");
div.html((d.data.itemLabel)+"<br>"+(d.data.itemValue));
});
paths.on("mouseout", function(d){
div.style("display", "none");
});
//DRAW TICK MARK LINES FOR LABELS
lines = label_group.selectAll("line").data(filteredPieData);
lines.enter().append("svg:line")
.attr("x1", 0)
.attr("x2", 0)
.attr("y1", -r-3)
.attr("y2", -r-18)
.attr("stroke", "gray")
.attr("transform", function(d) {
return "rotate(" + (d.startAngle+d.endAngle)/2 * (180/Math.PI) + ")";
});
lines.transition()
.duration(tweenDuration)
.attr("transform", function(d) {
return "rotate(" + (d.startAngle+d.endAngle)/2 * (180/Math.PI) + ")";
});
lines.exit().remove();
//DRAW LABELS WITH PERCENTAGE VALUES
valueLabels = label_group.selectAll("text.value").data(filteredPieData)
.attr("dy", function(d){
if ((d.startAngle+d.endAngle)/2 > Math.PI/2 && (d.startAngle+d.endAngle)/2 < Math.PI*1.5 ) {
return 5;
} else {
return -7;
}
})
.attr("text-anchor", function(d){
if ( (d.startAngle+d.endAngle)/2 < Math.PI ){
return "beginning";
} else {
return "end";
}
})
.text(function(d){
var percentage = (d.value/sliceProportion)*100;
return percentage.toFixed(1) + "%";
});
valueLabels.enter().append("svg:text")
.attr("class", "value")
.attr("transform", function(d) {
return "translate(" + Math.cos(((d.startAngle+d.endAngle - Math.PI)/2)) * (r+textOffset) + "," + Math.sin((d.startAngle+d.endAngle - Math.PI)/2) * (r+textOffset) + ")";
})
.attr("dy", function(d){
if ((d.startAngle+d.endAngle)/2 > Math.PI/2 && (d.startAngle+d.endAngle)/2 < Math.PI*1.5 ) {
return 5;
} else {
return -7;
}
})
.attr("text-anchor", function(d){
if ( (d.startAngle+d.endAngle)/2 < Math.PI ){
return "beginning";
} else {
return "end";
}
}).text(function(d){
var percentage = (d.value/sliceProportion)*100;
return percentage.toFixed(1) + "%";
});
valueLabels.transition().duration(tweenDuration).attrTween("transform", textTween);
valueLabels.exit().remove();
//DRAW LABELS WITH ENTITY NAMES
nameLabels = label_group.selectAll("text.units").data(filteredPieData)
.attr("dy", function(d){
if ((d.startAngle+d.endAngle)/2 > Math.PI/2 && (d.startAngle+d.endAngle)/2 < Math.PI*1.5 ) {
return 17;
} else {
return 5;
}
})
.attr("text-anchor", function(d){
if ((d.startAngle+d.endAngle)/2 < Math.PI ) {
return "beginning";
} else {
return "end";
}
}).text(function(d){
return d.name;
});
nameLabels.enter().append("svg:text")
.attr("class", "units")
.attr("transform", function(d) {
return "translate(" + Math.cos(((d.startAngle+d.endAngle - Math.PI)/2)) * (r+textOffset) + "," + Math.sin((d.startAngle+d.endAngle - Math.PI)/2) * (r+textOffset) + ")";
})
.attr("dy", function(d){
if ((d.startAngle+d.endAngle)/2 > Math.PI/2 && (d.startAngle+d.endAngle)/2 < Math.PI*1.5 ) {
return 18;
} else {
return 5;
}
})
.attr("text-anchor", function(d){
if ((d.startAngle+d.endAngle)/2 < Math.PI ) {
return "beginning";
} else {
return "end";
}
}).text(function(d){
return d.name;
});
nameLabels.transition().duration(tweenDuration).attrTween("transform", textTween);
nameLabels.exit().remove();
}
///////////////////////////////////////////////////////////
// FUNCTIONS //////////////////////////////////////////////
///////////////////////////////////////////////////////////
// Interpolate the arcs in data space.
function pieTween(d, i) {
var s0;
var e0;
if(oldPieData[i]){
s0 = oldPieData[i].startAngle;
e0 = oldPieData[i].endAngle;
} else if (!(oldPieData[i]) && oldPieData[i-1]) {
s0 = oldPieData[i-1].endAngle;
e0 = oldPieData[i-1].endAngle;
} else if(!(oldPieData[i-1]) && oldPieData.length > 0){
s0 = oldPieData[oldPieData.length-1].endAngle;
e0 = oldPieData[oldPieData.length-1].endAngle;
} else {
s0 = 0;
e0 = 0;
}
var i = d3.interpolate({startAngle: s0, endAngle: e0}, {startAngle: d.startAngle, endAngle: d.endAngle});
return function(t) {
var b = i(t);
return arc(b);
};
}
function removePieTween(d, i) {
s0 = 2 * Math.PI;
e0 = 2 * Math.PI;
var i = d3.interpolate({startAngle: d.startAngle, endAngle: d.endAngle}, {startAngle: s0, endAngle: e0});
return function(t) {
var b = i(t);
return arc(b);
};
}
function textTween(d, i) {
var a;
if(oldPieData[i]){
a = (oldPieData[i].startAngle + oldPieData[i].endAngle - Math.PI)/2;
} else if (!(oldPieData[i]) && oldPieData[i-1]) {
a = (oldPieData[i-1].startAngle + oldPieData[i-1].endAngle - Math.PI)/2;
} else if(!(oldPieData[i-1]) && oldPieData.length > 0) {
a = (oldPieData[oldPieData.length-1].startAngle + oldPieData[oldPieData.length-1].endAngle - Math.PI)/2;
} else {
a = 0;
}
var b = (d.startAngle + d.endAngle - Math.PI)/2;
var fn = d3.interpolateNumber(a, b);
return function(t) {
var val = fn(t);
return "translate(" + Math.cos(val) * (r+textOffset) + "," + Math.sin(val) * (r+textOffset) + ")";
};
}
update(0);
</script>
css:
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: auto;
position: relative;
font-weight: 300;
}
#pie-chart {
background-color: #ffffff;
/*border: 1px solid gray;*/
font: 10px sans-serif;
height: 400px;
text-shadow: none;
width: 650px;
margin-left: auto;
margin-right:auto;
}
#pie-chart .total{
font-size: 18px;
font-weight: bold;
}
#pie-chart .units{
fill: gray;
font-size: 12px;
}
#pie-chart .label{
fill: #CCC;
font-size: 12px;
}
#pie-chart .value{
font-size: 14px;
}
#slider label {
position: absolute;
width: 20px;
margin-left: -20px;
text-align: center;
margin-top: 30px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.toolTip {
position: absolute;
display: none;
width: auto;
height: auto;
background: none repeat scroll 0 0 white;
border: 0 none;
border-radius: 8px 8px 8px 8px;
box-shadow: -3px 3px 15px #888888;
color: black;
font: 12px sans-serif;
padding: 5px;
text-align: center;
}
答案 0 :(得分:2)
var div = d3.select("body").append("div").attr("class", "toolTip");
var w = 650;
var h = 400;
var r = 100;
var ir = 75;
var textOffset = 24;
var tweenDuration = 1050;
//OBJECTS TO BE POPULATED WITH DATA LATER
var lines, valueLabels, nameLabels;
var pieData = [];
var oldPieData = [];
var filteredPieData = [];
//D3 helper function to populate pie slice parameters from array data
var donut = d3.layout.pie().value(function(d){
return d.itemValue;
});
//D3 helper function to create colors from an ordinal scale
var color = d3.scale.category20c();
//D3 helper function to draw arcs, populates parameter "d" in path object
var arc = d3.svg.arc()
.startAngle(function(d){ return d.startAngle; })
.endAngle(function(d){ return d.endAngle; })
.innerRadius(ir)
.outerRadius(r);
///////////////////////////////////////////////////////////
// GENERATE FAKE DATA /////////////////////////////////////
///////////////////////////////////////////////////////////
var data;
var dataStructure = [
{
"data":[
{
"itemLabel":"Suv",
"itemValue":7165.0
},
{
"itemLabel":"Sedans",
"itemValue":2430.0
},
{
"itemLabel":"Hatchback",
"itemValue":1998.0
},
{
"itemLabel":"VAN",
"itemValue": 898.0
},
],
"label":"2007"
},
];
///////////////////////////////////////////////////////////
// CREATE VIS & GROUPS ////////////////////////////////////
///////////////////////////////////////////////////////////
var vis = d3.select("#pie-chart").append("svg:svg")
.attr("width", w)
.attr("height", h);
//GROUP FOR ARCS/PATHS
var arc_group = vis.append("svg:g")
.attr("class", "arc")
.attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");
//GROUP FOR LABELS
var label_group = vis.append("svg:g")
.attr("class", "label_group")
.attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");
//GROUP FOR CENTER TEXT
var center_group = vis.append("svg:g")
.attr("class", "center_group")
.attr("transform", "translate(" + (w/2) + "," + (h/2) + ")");
//PLACEHOLDER GRAY CIRCLE
// var paths = arc_group.append("svg:circle")
// .attr("fill", "#EFEFEF")
// .attr("r", r);
///////////////////////////////////////////////////////////
// CENTER TEXT ////////////////////////////////////////////
///////////////////////////////////////////////////////////
//WHITE CIRCLE BEHIND LABELS
var whiteCircle = center_group.append("svg:circle")
.attr("fill", "white")
.attr("r", ir);
var centerText='';
///////////////////////////////////////////////////////////
// STREAKER CONNECTION ////////////////////////////////////
///////////////////////////////////////////////////////////
// to run each time data is generated
function update(number) {
data = dataStructure[number].data;
oldPieData = filteredPieData;
pieData = donut(data);
var sliceProportion = 0; //size of this slice
filteredPieData = pieData.filter(filterData);
function filterData(element, index, array) {
element.name = data[index].itemLabel;
element.value = data[index].itemValue;
sliceProportion += element.value;
return (element.value > 0);
}
//DRAW ARC PATHS
paths = arc_group.selectAll("path").data(filteredPieData);
paths.enter().append("svg:path")
.attr("stroke", "white")
.attr("stroke-width", 0.5)
.attr("fill", function(d, i) { return color(i); })
.transition()
.duration(tweenDuration)
.attrTween("d", pieTween);
paths
.transition()
.duration(tweenDuration)
.attrTween("d", pieTween);
paths.exit()
.transition()
.duration(tweenDuration)
.attrTween("d", removePieTween)
.remove();
paths.on("mousemove", function(d){
div.style("left", d3.event.pageX+10+"px");
div.style("top", d3.event.pageY-25+"px");
div.style("display", "inline-block");
div.html((d.data.itemLabel)+"<br>"+(d.data.itemValue));
});
paths.on("mouseout", function(d){
div.style("display", "none");
});
//DRAW TICK MARK LINES FOR LABELS
lines = label_group.selectAll("line").data(filteredPieData);
lines.enter().append("svg:line")
.attr("x1", 0)
.attr("x2", 0)
.attr("y1", -r-3)
.attr("y2", -r-18)
.attr("stroke", "gray")
.attr("transform", function(d) {
return "rotate(" + (d.startAngle+d.endAngle)/2 * (180/Math.PI) + ")";
});
lines.transition()
.duration(tweenDuration)
.attr("transform", function(d) {
return "rotate(" + (d.startAngle+d.endAngle)/2 * (180/Math.PI) + ")";
});
lines.exit().remove();
//DRAW LABELS WITH PERCENTAGE VALUES
valueLabels = label_group.selectAll("text.value").data(filteredPieData)
.attr("dy", function(d){
if ((d.startAngle+d.endAngle)/2 > Math.PI/2 && (d.startAngle+d.endAngle)/2 < Math.PI*1.5 ) {
return 5;
} else {
return -7;
}
})
.attr("text-anchor", function(d){
if ( (d.startAngle+d.endAngle)/2 < Math.PI ){
return "beginning";
} else {
return "end";
}
})
.text(function(d){
var percentage = (d.value/sliceProportion)*100;
return percentage.toFixed(1) + "%";
});
valueLabels.enter().append("svg:text")
.attr("class", "value")
.attr("transform", function(d) {
return "translate(" + Math.cos(((d.startAngle+d.endAngle - Math.PI)/2)) * (r+textOffset) + "," + Math.sin((d.startAngle+d.endAngle - Math.PI)/2) * (r+textOffset) + ")";
})
.attr("dy", function(d){
if ((d.startAngle+d.endAngle)/2 > Math.PI/2 && (d.startAngle+d.endAngle)/2 < Math.PI*1.5 ) {
return 5;
} else {
return -7;
}
})
.attr("text-anchor", function(d){
if ( (d.startAngle+d.endAngle)/2 < Math.PI ){
return "beginning";
} else {
return "end";
}
}).text(function(d){
var percentage = (d.value/sliceProportion)*100;
return "trips: "+percentage.toFixed(1);
});
valueLabels.transition().duration(tweenDuration).attrTween("transform", textTween);
valueLabels.exit().remove();
//DRAW LABELS WITH ENTITY NAMES
nameLabels = label_group.selectAll("text.units").data(filteredPieData)
.attr("dy", function(d){
if ((d.startAngle+d.endAngle)/2 > Math.PI/2 && (d.startAngle+d.endAngle)/2 < Math.PI*1.5 ) {
return 17;
} else {
return 5;
}
})
.attr("text-anchor", function(d){
if ((d.startAngle+d.endAngle)/2 < Math.PI ) {
return "beginning";
} else {
return "end";
}
}).text(function(d){
return d.name;
});
nameLabels.enter().append("svg:text")
.attr("class", "units")
.attr("transform", function(d) {
return "translate(" + Math.cos(((d.startAngle+d.endAngle - Math.PI)/2)) * (r+textOffset) + "," + Math.sin((d.startAngle+d.endAngle - Math.PI)/2) * (r+textOffset) + ")";
})
.attr("dy", function(d){
if ((d.startAngle+d.endAngle)/2 > Math.PI/2 && (d.startAngle+d.endAngle)/2 < Math.PI*1.5 ) {
return 18;
} else {
return 5;
}
})
.attr("text-anchor", function(d){
if ((d.startAngle+d.endAngle)/2 < Math.PI ) {
return "beginning";
} else {
return "end";
}
}).text(function(d){
return d.name;
});
nameLabels.transition().duration(tweenDuration).attrTween("transform", textTween);
nameLabels.exit().remove();
var total = 0;
pieData.forEach(function(d){ total+=(d.value*1); });
center_group.selectAll('text').data([total]).enter().append('text').text(function(d){
return d;
}).attr('class','value').attr('dy', 8).attr('text-anchor', 'end').attr('transform', 'translate(20, 0)');
}
///////////////////////////////////////////////////////////
// FUNCTIONS //////////////////////////////////////////////
///////////////////////////////////////////////////////////
// Interpolate the arcs in data space.
function pieTween(d, i) {
var s0;
var e0;
if(oldPieData[i]){
s0 = oldPieData[i].startAngle;
e0 = oldPieData[i].endAngle;
} else if (!(oldPieData[i]) && oldPieData[i-1]) {
s0 = oldPieData[i-1].endAngle;
e0 = oldPieData[i-1].endAngle;
} else if(!(oldPieData[i-1]) && oldPieData.length > 0){
s0 = oldPieData[oldPieData.length-1].endAngle;
e0 = oldPieData[oldPieData.length-1].endAngle;
} else {
s0 = 0;
e0 = 0;
}
var i = d3.interpolate({startAngle: s0, endAngle: e0}, {startAngle: d.startAngle, endAngle: d.endAngle});
return function(t) {
var b = i(t);
return arc(b);
};
}
function removePieTween(d, i) {
s0 = 2 * Math.PI;
e0 = 2 * Math.PI;
var i = d3.interpolate({startAngle: d.startAngle, endAngle: d.endAngle}, {startAngle: s0, endAngle: e0});
return function(t) {
var b = i(t);
return arc(b);
};
}
function textTween(d, i) {
var a;
if(oldPieData[i]){
a = (oldPieData[i].startAngle + oldPieData[i].endAngle - Math.PI)/2;
} else if (!(oldPieData[i]) && oldPieData[i-1]) {
a = (oldPieData[i-1].startAngle + oldPieData[i-1].endAngle - Math.PI)/2;
} else if(!(oldPieData[i-1]) && oldPieData.length > 0) {
a = (oldPieData[oldPieData.length-1].startAngle + oldPieData[oldPieData.length-1].endAngle - Math.PI)/2;
} else {
a = 0;
}
var b = (d.startAngle + d.endAngle - Math.PI)/2;
var fn = d3.interpolateNumber(a, b);
return function(t) {
var val = fn(t);
return "translate(" + Math.cos(val) * (r+textOffset) + "," + Math.sin(val) * (r+textOffset) + ")";
};
}
update(0);
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: auto;
position: relative;
font-weight: 300;
}
#pie-chart {
background-color: #ffffff;
/*border: 1px solid gray;*/
font: 10px sans-serif;
height: 400px;
text-shadow: none;
width: 650px;
margin-left: auto;
margin-right:auto;
}
#pie-chart .total{
font-size: 18px;
font-weight: bold;
}
#pie-chart .units{
fill: gray;
font-size: 12px;
}
#pie-chart .label{
fill: #CCC;
font-size: 12px;
}
#pie-chart .value{
font-size: 14px;
}
#slider label {
position: absolute;
width: 20px;
margin-left: -20px;
text-align: center;
margin-top: 30px;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
}
.toolTip {
position: absolute;
display: none;
width: auto;
height: auto;
background: none repeat scroll 0 0 white;
border: 0 none;
border-radius: 8px 8px 8px 8px;
box-shadow: -3px 3px 15px #888888;
color: black;
font: 12px sans-serif;
padding: 5px;
text-align: center;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="pie-chart"></div>
现在查看代码。 我想你在找这个,,, 如果没有问我更多。