我的目标是建立一个交互式图表,显示图表旁边弧线的其他信息。下面的代码不干净,但功能齐全,几乎可以实现我想要的一切。
具体来说,它绘制一个圆弧饼图,当您将鼠标悬停在圆弧上时,它会照亮圆弧并从该圆弧的中心绘制一条线到右侧的数据区域,其中列出了花费和描述。
然而,代码似乎不优雅,它显示的数据点(文本)都是相同的。它似乎没有添加额外的数据元素来显示它们,或者它是IS但只是选择第一个显示它!
我没有打算复制的HTML只是一个带有单个div的空白网页:<div id="pie">1,2,3</div>
var format = d3.format(",.2f");
var data = [
{'spend': 15, 'description': 'Controlled'},
{'spend': 3, 'description': 'Data Usage'},
{'spend': 21, 'description': 'International Roaming'}
];
var kulor = d3.scale.ordinal()
.range(['#648631','#D84B4B','#A05AE0']);
var width = 160,
height = 80,
radius = height / 2 - 10, // how wide is the circle within the box?
innerRadius = radius - 10, // how thich is the donut (the -# is the thickness)
cornerRadius = 3, // how wide are the curves of each section
padAngle = .07, // distance between items (in angles)
startLine = [40, -25]; // where the description line starts
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(radius)
.cornerRadius(cornerRadius);
var pie = d3.layout.pie()
.padAngle(padAngle)
.value(function (d) {
return d.spend;
});
var arcs = d3.select('#pie').html('').append('svg')
.data([data])
.attr('width', width)
.attr('height', height)
.append('g')
// keep centered but left
.attr('transform', 'translate(' + height / 2 + ',' + height / 2 + ')');
arcs.selectAll('path')
.data(pie).enter()
.append('path')
.style('fill', function(d, i) { return kulor(i); })
.attr('d', arc);
arcs.selectAll('line')
.data(pie).enter()
.append('line')
.classed('slice', true)
.attr('lineNum', function(d,i){ return 'sl'+i; })
.attr('x1', function(d, i) {
return arc.centroid(d, i)[0];
})
.attr('y1', function(d, i) {
return arc.centroid(d, i)[1];
})
.attr('x2', startLine[0]).attr('y2', startLine[1])
.attr('stroke-width', 2).attr('stroke','#333')
.style('visibility', 'hidden');
// fixed line
arcs.append('line')
.classed('fixedLine', true)
.attr('x1', startLine[0]).attr('y1', startLine[1])
.attr('x2', 120).attr('y2', startLine[1])
.attr('stroke-width', 2).attr('stroke','#333')
.style('visibility', 'hidden');
// Spend
arcs.each(function(d, i) {
console.log(d[i].spend + " " + i);
arcs.append('text')
.classed('spend', true)
.text(function(d,i){
console.log(d);
return '$' + format(d[i].spend);
})
.attr('x', 80).attr('y', startLine[1] - 4)
.attr('font-size',12)
.attr('font-family','Helvetica, sans-serif')
.attr('text-anchor','middle')
.attr('font-weigt','bold')
.style('visibility', 'hidden');
})
// Spend Description
arcs.append('text')
.text(function(d,i){ return d[i].description; })
.attr('x', 80).attr('y', startLine[1] + 12)
.attr('font-size',12)
.attr('font-family','Helvetica, sans-serif')
.attr('text-anchor','middle')
.attr('font-weigt','bold')
.style('visibility', 'hidden');;
arcs.selectAll('path')
.on('mouseover', function(d, i) {
var index = i + 1;
var nodeSel = d3.select(this).style({opacity:'0.8'});
nodeSel.select('text').style({opacity:'1.0'});
d3.select('.slice:nth-of-type('+index+')').style('visibility', 'visible');
d3.select('.spend:nth-of-type('+index+')').style('visibility', 'visible');
d3.select('.fixedLine').style('visibility', 'visible');
d3.selectAll('text').style('visibility', 'visible');
})
.on('mouseout', function(d, i) {
var nodeSel = d3.select(this).style({opacity:'1.0'});
nodeSel.select('text').style({opacity:'0'});
arcs.selectAll('.slice').style('visibility', 'hidden');
arcs.selectAll('.fixedLine').style('visibility', 'hidden');
arcs.selectAll('text').style('visibility', 'hidden');
});
答案 0 :(得分:0)
问题1:
您不必添加与弧数一样多的文本。 所以这是错误的。
arcs.each(function(d, i) {
console.log(d[i].spend + " " + i);
arcs.append('text')
.classed('spend', true)
.text(function(d,i){
console.log(d);
return '$' + format(d[i].spend);
})
.attr('x', 80).attr('y', startLine[1] - 4)
.attr('font-size',12)
.attr('font-family','Helvetica, sans-serif')
.attr('text-anchor','middle')
.attr('font-weigt','bold')
.style('visibility', 'hidden');
})
正确的方法是添加一个像这样的文本DOM(并且该DOM给出鼠标悬停的描述)
arcs.append('text')
.classed('spend', true)
.attr('x', 80).attr('y', startLine[1] - 4)
.attr('font-size',12)
.attr('font-family','Helvetica, sans-serif')
.attr('text-anchor','middle')
.attr('font-weigt','bold')
.style('visibility', 'hidden');
问题2:
在制作text
DOM时,您无需设置text
:
.classed('spend', true)
.text(function(d,i){
console.log(d);
return '$' + format(d[i].spend);
})
您需要像这样添加鼠标描述
.on('mouseover', function(d, i) {
var index = i + 1;
var nodeSel = d3.select(this).style({opacity:'0.8'});
nodeSel.select('text').style({opacity:'1.0'});
d3.select('.slice:nth-of-type('+index+')').style('visibility', 'visible');
d3.select('.spend:nth-of-type('+index+')').style('visibility', 'visible');
d3.select('.fixedLine').style('visibility', 'visible');
d3.selectAll('text').style('visibility', 'visible');
//setting the description data to the text dom
d3.selectAll(".description").text(d.data.description);
//setting the spend data to the text dom
d3.selectAll(".spend").text('$' + format(d.data.spend))
});
工作代码here。