我一直在尝试向d3树的节点添加工具提示。我已经看过这个example,并且我的代码是基于该示例的:
nodeEnter.append('rect')
...
.on('mouseover', function (d) {
var foHeight = rect_height;
var foWidth = rect_width;
var t = 50, k = 15;
var tip = {'w': (3/4 * t), 'h': k};
var anchor = {'w': 100/3, 'h': 100/3};
var fo = svg.append('foreignObject')
.attr('x', 0)
.attr('y', 0)
.attr('width', rect_width)
.attr('height', rect_height)
.attr('class', 'svg-tooltip');
var div = fo.append('xhtml:div')
.append('div')
.attr('class', 'tooltip');
console.log('div is :');
console.log(div);
div.append('p').html(function() {
console.log('dev append d is');
console.log(d);
if(d.data.tooltip || d.data.name) {
console.log('we have tooltip or name.');
console.log('name is' + d.data.name);
return '<div style="z-index:2 ; width: '
+ (125) + 'px; height: '
+ (42) + 'px;" class="node-text wordwrap" title="' + (d.data.tooltip || d.data.name) + '">'
+ '</div>';
}
});
fo.attr('height', 200);
svg.insert('polygon', '.svg-tooltip')
.attr({
'points': "0,0 0," + foHeight + " " + foWidth + "," + foHeight + " " + foWidth + ",0 " + (t) + ",0 " + tip.w + "," + (-tip.h) + " " + (t/2) + ",0",
'height': foHeight + tip.h,
'width': foWidth,
'fill': '#D8D8D8',
'opacity': 0.75,
'transform': 'translate(' + (anchor.w - tip.w) + ',' + (anchor.h + tip.h) + ')'
})
})
.on('mouseout', function(d) {
console.log('mouse out of ' + d.data.name);
svg.selectAll('.svg-tooltip').remove();
svg.selectAll('polygon').remove();
});
当我将鼠标放在一个节点上时,在开发人员的控制台中看到此输出...
div is :
Selection {_groups: Array(1), _parents: Array(1)}
dev append d is
Node {data: {…}, height: 0, depth: 2, parent: Node, x: 150, …}
have tooltip or name.
name isquoting-es-stg1-001
...,但没有工具提示出现。我在做什么错了?
谢谢!
答案 0 :(得分:2)
此处的代码存在一些问题。该示例最不容易适应,因为:
anchor = {'w': width/3, 'h': height/3}
)首先,我们想知道工具提示应该放在哪里,
.on('mouseover', function (d) {
// Get highlight rectangle:
var rect = d3.select(this); // the selected rect.
// Get bottom middle of rectangle:
var x = +rect.attr("x") + rectWidth/2;
var y = +rect.attr("y") + rectHeight;
...
这将获得鼠标悬停的矩形底部边缘的中间。
我们需要将其应用于异物(包含文本)和多边形(包含阴影+形状-可以在不带svg多边形的纯css中完成):
// for the foreign object:
var fo = svg.append('foreignObject')
.attr('x', x)
.attr('y', y)
// And for the polygon:
.attr("transform","translate("+[x-tip.w,y+tip.h/2]+")");
如果我们将.attr()出现的位置替换为具有单个.attr(“ property”,value)行或使用d3.selection-multi和.attrs()的对象,那么我们应该可以使用。
最后,foWidth和foHeight可能与rectWidth和rectHeight并不相同,否则任何大于矩形的工具提示都会被截断。 尽管,您确实将异物的宽度覆盖为200,所以它不是rectWidth
我相信这些都是我在下面所做的所有更改:
var rectWidth = 28;
var rectHeight = 28;
var svg = d3.select("body")
.append("svg")
.attr("height", 300);
var data = d3.range(16);
var color = d3.interpolateBlues;
var nodeEnter = svg.selectAll(null)
.data(data)
.enter()
.append("rect")
.attr("x", function(d,i) {
return i%4 * (rectWidth+2);
})
.attr("y", function(d,i) {
return Math.floor(i/4) * (rectHeight+2);
})
.attr("width",rectWidth)
.attr("height",rectHeight)
.attr("fill", function(d,i) {
return color((Math.floor(i/4)+1) * (i%4+1) /16)
})
.on('mouseover', function (d) {
// Get highlight rectangle:
var rect = d3.select(this); // the selected rect.
// Get bottom middle of rectangle:
var x = +rect.attr("x") + rectWidth/2;
var y = +rect.attr("y") + rectHeight;
// Dimensions of foreign object:
var foHeight = 50;
var foWidth = 200;
// tooltip triangle info:
var t = 50, k = 15;
var tip = {'w': (3/4 * t), 'h': k};
//Foreign object:
var fo = svg.append('foreignObject')
.attr('x', x)
.attr('y', y)
.attr('width', foWidth)
.attr('height', foHeight)
.attr('class', 'svg-tooltip')
// FO's Div:
var div = fo.append('xhtml:div')
.append('div')
.attr("class","tooltip");
// Div's p:
div.append('p').html(function() {
return "This is square: " + d;
})
// SVG polygon that creates the background for the FO:
svg.insert('polygon', '.svg-tooltip')
.attr('points', "0,0 0," + foHeight + " " + foWidth + "," + foHeight + " " + foWidth + ",0 " + (t) + ",0 " + tip.w + "," + (-tip.h) + " " + (t/2) + ",0")
.attr('height', foHeight)
.attr('width',foWidth)
.attr('fill','#D8D8D8')
.attr('opacity',0.75)
.attr('transform',"translate("+[x-tip.w,y+tip.h/2]+")")
}).on('mouseout', function() {
svg.selectAll('.svg-tooltip').remove();
svg.selectAll('polygon').remove();
})
svg {
display: block;
margin: 0 auto;
}
.svg-tooltip {
pointer-events: none;
}
.tooltip {
padding: 10px;
color: #4A22FF;
}
.lead {
font-style: italic;
}
p {
margin: 5px 0px;
}
polygon {
pointer-events: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
但是,基于异物/ svg的工具提示有局限性。除非在接近SVG底部时工具提示从底部锚定,否则可能会被切除。将div(不是包含div的异物)放置在鼠标所在的SVG上的工具提示将对此提供帮助。 D3noob对此有很好的example。