我无法使用 d3.js 在 3d 圆环图中添加放置标签
I am not able to add put labels in 3d donut chart using d3.js
我使用 codepen 上的代码创建了一个 D3 圆环图,但我无法向其添加标签。我希望在每个部分的侧面添加标签。为了创建这个圆环图,我使用了 D3.js:
这是我用过的代码:
<script type="text/javascript">
var dataset = [
{ name: 'Savings', count: 3250 },
{ name: 'Housing', count: 1707 },
{ name: 'Transportation', count: 377 },
{ name: 'Misc', count: 365 },
{ name: 'Insurance', count: 314 },
{ name: 'Utilities', count: 294 },
{ name: 'Student Loans', count: 262 },
{ name: 'Food', count: 250 },
{ name: 'Phone', count: 10 },
];
var total=0;
dataset.forEach(function(d){
total+= d.count;
});
var pie=d3.layout.pie()
.value(function(d){return d.count})
.sort(null);
var data_ready = pie(d3.entries(dataset))
var w=300,h=300;
var outerRadiusArc=w/2;
var innerRadiusArc=100;
var shadowWidth=10;
var outerRadiusArcShadow=innerRadiusArc+1;
var innerRadiusArcShadow=innerRadiusArc-shadowWidth;
var color = d3.scale.ordinal()
.range(['#f5e232', '#64eb34' , '#2d72e0', '#e3251b', '#d61be3', '#f0b00e', '#0ef0c3', '#e61240', '#db12e6']).domain(["Saving", "Housing", "Transportayion", "Misc", "Insurance", "Utilities", "Student Loan", "Food", "Phone"])
;
var svg=d3.select("#chart")
.append("svg")
.attr({
width:w,
height:h,
class:'shadow'
}).append('g')
.attr({
transform:'translate('+w/2+','+h/2+')'
});
var createChart=function(svg,outerRadius,innerRadius,fillFunction,className){
var arc=d3.svg.arc()
.innerRadius(outerRadius)
.outerRadius(innerRadius);
var path=svg.selectAll('.'+className)
.data(pie(dataset))
.enter()
.append('path')
.attr({
class:className,
d:arc,
fill:fillFunction
});
path.transition()
.duration(1000)
.attrTween('d', function(d) {
var interpolate = d3.interpolate({startAngle: 0, endAngle: 0}, d);
return function(t) {
return arc(interpolate(t));
};
});
};
createChart(svg,outerRadiusArc,innerRadiusArc,function(d,i){
return color(d.data.name);
},'path1');
createChart(svg,outerRadiusArcShadow,innerRadiusArcShadow,function(d,i){
var c=d3.hsl(color(d.data.name));
return d3.hsl((c.h+5), (c.s -.07), (c.l -.15));
},'path2');
var addText= function (text,y,size) {
svg.append('text')
.text(text)
.attr({
'text-anchor':'middle',
y:y
})
.style({
fill:'black',
'font-size':size,
});
};
var addTexttwo= function (text,x,y,size) {
svg.append('text')
.text(text)
.attr({
'text-anchor':'middle',
y:y,
x:x,
})
.style({
fill:'white',
'font-size':size,
});
};
var restOfTheData=function(){
addText(function(){
return ",830";
},40,'30px');
addText(function(){
return "Shine's";
},-20, '20px');
addText(function(){
return "Monthly Budget";
},0, '20px');
};
setTimeout(restOfTheData,1000);
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
</script>
我希望结果看起来像这样。甜甜圈侧面的标签
此代码将标签放在饼图周围:
const textRadius = d => outerRadiusArc + (d.data.count < 50 ? 15 : 5);
const textX = d => textRadius(d) * Math.sin((d.startAngle + d.endAngle) / 2);
const textY = d => textRadius(d) * -Math.cos((d.startAngle + d.endAngle) / 2);
const textAnchor = d => (d.startAngle + d.endAngle) / 2 > Math.PI ? 'end' : 'start';
svg.selectAll('text.label')
.data(pie(dataset))
.enter()
.append('text')
.classed('label', true)
.text(d => d.data.name)
.attr('x', textX)
.attr('y', textY)
.attr('text-anchor', textAnchor)
.attr('alignment-baseline', 'middle')
var dataset = [
{ name: 'Savings', count: 3250 },
{ name: 'Housing', count: 1707 },
{ name: 'Transportation', count: 377 },
{ name: 'Misc', count: 365 },
{ name: 'Insurance', count: 314 },
{ name: 'Utilities', count: 294 },
{ name: 'Student Loans', count: 262 },
{ name: 'Food', count: 250 },
{ name: 'Phone', count: 10 },
];
var total=0;
dataset.forEach(function(d){
total+= d.count;
});
var pie=d3.layout.pie()
.value(function(d){return d.count})
.sort(null);
var data_ready = pie(d3.entries(dataset))
var w=400,h=300;
var outerRadiusArc=120;
var innerRadiusArc=90;
var shadowWidth=10;
var outerRadiusArcShadow=innerRadiusArc+1;
var innerRadiusArcShadow=innerRadiusArc-shadowWidth;
var color = d3.scale.ordinal()
.range(['red', '#f5e232', 'orange' , '#2d72e0', '#e3251b', '#d61be3', '#f0b00e', '#0ef0c3', '#e61240', '#db12e6']).domain(["Saving", "Housing", "Transportayion", "Misc", "Insurance", "Utilities", "Student Loan", "Food", "Phone"])
;
var svg = d3.select("#chart")
.append("svg")
.attr({
width:w,
height:h,
class:'shadow'
}).append('g')
.attr({
transform:'translate('+w/2+','+h/2+')'
});
var createChart=function(svg,outerRadius,innerRadius,fillFunction,className){
var arc=d3.svg.arc()
.innerRadius(outerRadius)
.outerRadius(innerRadius);
var path=svg.selectAll('.'+className)
.data(pie(dataset))
.enter()
.append('path')
.attr({
class:className,
d:arc,
fill:fillFunction
});
path.transition()
.duration(1000)
.attrTween('d', function(d) {
var interpolate = d3.interpolate({startAngle: 0, endAngle: 0}, d);
return function(t) {
return arc(interpolate(t));
};
})
.each(d => {
console.log(d);
})
const textRadius = d => outerRadiusArc + (d.data.count < 50 ? 15 : 5);
const textX = d => textRadius(d) * Math.sin((d.startAngle + d.endAngle) / 2);
const textY = d => textRadius(d) * -Math.cos((d.startAngle + d.endAngle) / 2);
const textAnchor = d => (d.startAngle + d.endAngle) / 2 > Math.PI ? 'end' : 'start';
svg.selectAll('text.label')
.data(pie(dataset))
.enter()
.append('text')
.classed('label', true)
.text(d => d.data.name)
.attr('x', textX)
.attr('y', textY)
.attr('text-anchor', textAnchor)
.attr('alignment-baseline', 'middle')
/*
svg.selectAll('circle.point')
.data(pie(dataset))
.enter()
.append('circle')
.classed('point', true)
.attr('r', 3)
.attr('cx', textX)
.attr('cy', textY)
*/
};
createChart(svg,outerRadiusArc,innerRadiusArc,function(d,i){
return color(d.data.name);
},'path1');
createChart(svg,outerRadiusArcShadow,innerRadiusArcShadow,function(d,i){
var c=d3.hsl(color(d.data.name));
return d3.hsl((c.h+5), (c.s -.07), (c.l -.15));
},'path2');
var addText= function (text,y,size) {
svg.append('text')
.text(text)
.attr({
'text-anchor':'middle',
y:y
})
.style({
fill:'black',
'font-size':size,
});
};
var addTexttwo= function (text,x,y,size) {
svg.append('text')
.text(text)
.attr({
'text-anchor':'middle',
y:y,
x:x,
})
.style({
fill:'white',
'font-size':size,
});
};
var restOfTheData=function(){
addText(function(){
return ",830";
},40,'30px');
addText(function(){
return "Shine's";
},-20, '20px');
addText(function(){
return "Monthly Budget";
},0, '20px');
};
setTimeout(restOfTheData,1000);
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
.label {
font-family: 'Ubuntu';
font-size: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<div id="chart" />
我使用 codepen 上的代码创建了一个 D3 圆环图,但我无法向其添加标签。我希望在每个部分的侧面添加标签。为了创建这个圆环图,我使用了 D3.js:
这是我用过的代码:
<script type="text/javascript">
var dataset = [
{ name: 'Savings', count: 3250 },
{ name: 'Housing', count: 1707 },
{ name: 'Transportation', count: 377 },
{ name: 'Misc', count: 365 },
{ name: 'Insurance', count: 314 },
{ name: 'Utilities', count: 294 },
{ name: 'Student Loans', count: 262 },
{ name: 'Food', count: 250 },
{ name: 'Phone', count: 10 },
];
var total=0;
dataset.forEach(function(d){
total+= d.count;
});
var pie=d3.layout.pie()
.value(function(d){return d.count})
.sort(null);
var data_ready = pie(d3.entries(dataset))
var w=300,h=300;
var outerRadiusArc=w/2;
var innerRadiusArc=100;
var shadowWidth=10;
var outerRadiusArcShadow=innerRadiusArc+1;
var innerRadiusArcShadow=innerRadiusArc-shadowWidth;
var color = d3.scale.ordinal()
.range(['#f5e232', '#64eb34' , '#2d72e0', '#e3251b', '#d61be3', '#f0b00e', '#0ef0c3', '#e61240', '#db12e6']).domain(["Saving", "Housing", "Transportayion", "Misc", "Insurance", "Utilities", "Student Loan", "Food", "Phone"])
;
var svg=d3.select("#chart")
.append("svg")
.attr({
width:w,
height:h,
class:'shadow'
}).append('g')
.attr({
transform:'translate('+w/2+','+h/2+')'
});
var createChart=function(svg,outerRadius,innerRadius,fillFunction,className){
var arc=d3.svg.arc()
.innerRadius(outerRadius)
.outerRadius(innerRadius);
var path=svg.selectAll('.'+className)
.data(pie(dataset))
.enter()
.append('path')
.attr({
class:className,
d:arc,
fill:fillFunction
});
path.transition()
.duration(1000)
.attrTween('d', function(d) {
var interpolate = d3.interpolate({startAngle: 0, endAngle: 0}, d);
return function(t) {
return arc(interpolate(t));
};
});
};
createChart(svg,outerRadiusArc,innerRadiusArc,function(d,i){
return color(d.data.name);
},'path1');
createChart(svg,outerRadiusArcShadow,innerRadiusArcShadow,function(d,i){
var c=d3.hsl(color(d.data.name));
return d3.hsl((c.h+5), (c.s -.07), (c.l -.15));
},'path2');
var addText= function (text,y,size) {
svg.append('text')
.text(text)
.attr({
'text-anchor':'middle',
y:y
})
.style({
fill:'black',
'font-size':size,
});
};
var addTexttwo= function (text,x,y,size) {
svg.append('text')
.text(text)
.attr({
'text-anchor':'middle',
y:y,
x:x,
})
.style({
fill:'white',
'font-size':size,
});
};
var restOfTheData=function(){
addText(function(){
return ",830";
},40,'30px');
addText(function(){
return "Shine's";
},-20, '20px');
addText(function(){
return "Monthly Budget";
},0, '20px');
};
setTimeout(restOfTheData,1000);
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
</script>
我希望结果看起来像这样。甜甜圈侧面的标签
此代码将标签放在饼图周围:
const textRadius = d => outerRadiusArc + (d.data.count < 50 ? 15 : 5);
const textX = d => textRadius(d) * Math.sin((d.startAngle + d.endAngle) / 2);
const textY = d => textRadius(d) * -Math.cos((d.startAngle + d.endAngle) / 2);
const textAnchor = d => (d.startAngle + d.endAngle) / 2 > Math.PI ? 'end' : 'start';
svg.selectAll('text.label')
.data(pie(dataset))
.enter()
.append('text')
.classed('label', true)
.text(d => d.data.name)
.attr('x', textX)
.attr('y', textY)
.attr('text-anchor', textAnchor)
.attr('alignment-baseline', 'middle')
var dataset = [
{ name: 'Savings', count: 3250 },
{ name: 'Housing', count: 1707 },
{ name: 'Transportation', count: 377 },
{ name: 'Misc', count: 365 },
{ name: 'Insurance', count: 314 },
{ name: 'Utilities', count: 294 },
{ name: 'Student Loans', count: 262 },
{ name: 'Food', count: 250 },
{ name: 'Phone', count: 10 },
];
var total=0;
dataset.forEach(function(d){
total+= d.count;
});
var pie=d3.layout.pie()
.value(function(d){return d.count})
.sort(null);
var data_ready = pie(d3.entries(dataset))
var w=400,h=300;
var outerRadiusArc=120;
var innerRadiusArc=90;
var shadowWidth=10;
var outerRadiusArcShadow=innerRadiusArc+1;
var innerRadiusArcShadow=innerRadiusArc-shadowWidth;
var color = d3.scale.ordinal()
.range(['red', '#f5e232', 'orange' , '#2d72e0', '#e3251b', '#d61be3', '#f0b00e', '#0ef0c3', '#e61240', '#db12e6']).domain(["Saving", "Housing", "Transportayion", "Misc", "Insurance", "Utilities", "Student Loan", "Food", "Phone"])
;
var svg = d3.select("#chart")
.append("svg")
.attr({
width:w,
height:h,
class:'shadow'
}).append('g')
.attr({
transform:'translate('+w/2+','+h/2+')'
});
var createChart=function(svg,outerRadius,innerRadius,fillFunction,className){
var arc=d3.svg.arc()
.innerRadius(outerRadius)
.outerRadius(innerRadius);
var path=svg.selectAll('.'+className)
.data(pie(dataset))
.enter()
.append('path')
.attr({
class:className,
d:arc,
fill:fillFunction
});
path.transition()
.duration(1000)
.attrTween('d', function(d) {
var interpolate = d3.interpolate({startAngle: 0, endAngle: 0}, d);
return function(t) {
return arc(interpolate(t));
};
})
.each(d => {
console.log(d);
})
const textRadius = d => outerRadiusArc + (d.data.count < 50 ? 15 : 5);
const textX = d => textRadius(d) * Math.sin((d.startAngle + d.endAngle) / 2);
const textY = d => textRadius(d) * -Math.cos((d.startAngle + d.endAngle) / 2);
const textAnchor = d => (d.startAngle + d.endAngle) / 2 > Math.PI ? 'end' : 'start';
svg.selectAll('text.label')
.data(pie(dataset))
.enter()
.append('text')
.classed('label', true)
.text(d => d.data.name)
.attr('x', textX)
.attr('y', textY)
.attr('text-anchor', textAnchor)
.attr('alignment-baseline', 'middle')
/*
svg.selectAll('circle.point')
.data(pie(dataset))
.enter()
.append('circle')
.classed('point', true)
.attr('r', 3)
.attr('cx', textX)
.attr('cy', textY)
*/
};
createChart(svg,outerRadiusArc,innerRadiusArc,function(d,i){
return color(d.data.name);
},'path1');
createChart(svg,outerRadiusArcShadow,innerRadiusArcShadow,function(d,i){
var c=d3.hsl(color(d.data.name));
return d3.hsl((c.h+5), (c.s -.07), (c.l -.15));
},'path2');
var addText= function (text,y,size) {
svg.append('text')
.text(text)
.attr({
'text-anchor':'middle',
y:y
})
.style({
fill:'black',
'font-size':size,
});
};
var addTexttwo= function (text,x,y,size) {
svg.append('text')
.text(text)
.attr({
'text-anchor':'middle',
y:y,
x:x,
})
.style({
fill:'white',
'font-size':size,
});
};
var restOfTheData=function(){
addText(function(){
return ",830";
},40,'30px');
addText(function(){
return "Shine's";
},-20, '20px');
addText(function(){
return "Monthly Budget";
},0, '20px');
};
setTimeout(restOfTheData,1000);
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
.label {
font-family: 'Ubuntu';
font-size: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<div id="chart" />