D3 js 如何获取特定于数据的工具提示以在悬停时显示?
D3 js How do I get data specific tooltips to display on-hover?
我的目标是制作一个交互式图表,在图表旁边的弧线上显示附加信息。下面的代码不干净,但可以正常工作并且(几乎)完成了我想要的一切。
具体来说,它会绘制一个圆弧饼图,当您将鼠标悬停在圆弧上时,圆弧会变亮,并从圆弧的中心到右侧的数据区域绘制一条线,其中有支出和描述已列出。
然而,代码似乎不够优雅,它显示的数据点(文本)都是同一个。它似乎没有添加额外的数据元素来显示它们,或者它只是选择第一个显示!
我懒得复制的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');
});
问题 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
text
DOM:
.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.
我的目标是制作一个交互式图表,在图表旁边的弧线上显示附加信息。下面的代码不干净,但可以正常工作并且(几乎)完成了我想要的一切。
具体来说,它会绘制一个圆弧饼图,当您将鼠标悬停在圆弧上时,圆弧会变亮,并从圆弧的中心到右侧的数据区域绘制一条线,其中有支出和描述已列出。
然而,代码似乎不够优雅,它显示的数据点(文本)都是同一个。它似乎没有添加额外的数据元素来显示它们,或者它只是选择第一个显示!
我懒得复制的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');
});
问题 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
text
DOM:
.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.