javascript - 修复 d3.js v4 工具提示位置
问题描述
我一直在尝试使用 d3 v4 插件在我的网页中显示两个图表
我一直在关注一些关于工具提示用法的示例,但我遇到了一个问题:在第一个图表中,工具提示显示在正确的位置(条形上方),但在底部图表中,工具提示似乎进入了页面底部。
这是一个非常简单的例子:https ://jsfiddle.net/xvs98vru/
HTML
<div class="container">
<div class="row">
<div class="col-md-12">
<div id="chart1" class="c"></div>
</div>
<div class="col-md-12">
<div id="chart2" class="c"></div>
</div>
</div>
</div>
CSS
body { padding: 20px; }
.c {
height: 300px;
width: 400px;
margin-bottom: 10px;
}
.tooltipx {
pointer-events: none;
position: absolute;
display: none;
min-width: 50px;
height: auto;
background: none repeat scroll 0 0 #ffffff;
padding: 4px 10px 4px 10px;
border-radius: 4px;
text-align: left;
line-height: 1.3;
color: #5B6770;
box-shadow: 0px 3px 9px rgba(0, 0, 0, .15);
}
JS
(function() {
var mrg = { t:10, r:20, b:30, l:20 };
var data = [
{ id: 1, amount: 6 },
{ id: 2, amount: 5 },
{ id: 3, amount: 2 },
{ id: 4, amount: 8 }
];
function loadChart(container) {
var width = 400 - mrg.l - mrg.r;
var height = 300 - mrg.t - mrg.b;
var color = d3.scaleOrdinal(d3.schemeCategory10);
var tooltip = d3.select(container).append("div")
.attr("class", "tooltipx")
.style("opacity", 0);
var x = d3.scaleBand().range([0, width]).padding(0.1);
var y = d3.scaleLinear().range([height, 0]);
x.domain([1, 2, 3, 4]);
y.domain([0, 10]);
var svg = d3.select(container).append("svg")
.attr("width", width + mrg.l + mrg.r)
.attr("height", height + mrg.t + mrg.b)
.append("g")
.attr("transform", "translate(" + mrg.l + "," + mrg.t + ")");
svg.selectAll(".bar")
.data(data)
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", function(n) { return x(n.id); })
.attr("y", function(n) { return y(n.amount); })
.attr("width", x.bandwidth())
.attr("height", function(n) { return height - y(n.amount); })
.attr("fill", function(n, i) { return color(i); })
.on("mousemove", function(n) {
tooltip
.style("opacity", 1)
.style("left", d3.event.pageX + "px")
.style("top", d3.event.pageY + "px")
.style("display", "inline-block")
.html("<span>Hola</span>")
})
.on("mouseout", function(n) { tooltip.style("opacity", 0); });
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
svg.append("g").call(d3.axisLeft(y));
}
function init() {
loadChart("#chart1");
loadChart("#chart2");
}
init();
}());
感谢您的支持
问候
解决方案
由于您使用pageX
andpageY
来定位工具提示,因此不要将它们附加到每个选定的 div ...而不是那样,将它们附加到<body>
:
var tooltip = d3.select("body").append("div")
这是您的代码,仅进行了该更改:
(function() {
var mrg = {
t: 10,
r: 20,
b: 30,
l: 20
};
var data = [{
id: 1,
amount: 6
},
{
id: 2,
amount: 5
},
{
id: 3,
amount: 2
},
{
id: 4,
amount: 8
}
];
function loadChart(container) {
var width = 400 - mrg.l - mrg.r;
var height = 300 - mrg.t - mrg.b;
var color = d3.scaleOrdinal(d3.schemeCategory10);
var tooltip = d3.select("body").append("div")
.attr("class", "tooltipx")
.style("opacity", 0);
var x = d3.scaleBand().range([0, width]).padding(0.1);
var y = d3.scaleLinear().range([height, 0]);
x.domain([1, 2, 3, 4]);
y.domain([0, 10]);
var svg = d3.select(container).append("svg")
.attr("width", width + mrg.l + mrg.r)
.attr("height", height + mrg.t + mrg.b)
.append("g")
.attr("transform", "translate(" + mrg.l + "," + mrg.t + ")");
svg.selectAll(".bar")
.data(data)
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", function(n) {
return x(n.id);
})
.attr("y", function(n) {
return y(n.amount);
})
.attr("width", x.bandwidth())
.attr("height", function(n) {
return height - y(n.amount);
})
.attr("fill", function(n, i) {
return color(i);
})
.on("mousemove", function(n) {
tooltip
.style("opacity", 1)
.style("left", d3.event.pageX + "px")
.style("top", d3.event.pageY + "px")
.style("display", "inline-block")
.html("<span>Hola</span>")
})
.on("mouseout", function(n) {
tooltip.style("opacity", 0);
});
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
svg.append("g").call(d3.axisLeft(y));
}
function init() {
loadChart("#chart1");
loadChart("#chart2");
}
init();
}());
body {
padding: 20px;
}
.c {
height: 300px;
width: 400px;
margin-bottom: 10px;
}
.tooltipx {
pointer-events: none;
position: absolute;
display: none;
min-width: 50px;
height: auto;
background: none repeat scroll 0 0 #ffffff;
padding: 4px 10px 4px 10px;
border-radius: 4px;
text-align: left;
line-height: 1.3;
color: #5B6770;
box-shadow: 0px 3px 9px rgba(0, 0, 0, .15);
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<div class="container">
<div class="row">
<div class="col-md-12">
<div id="chart1" class="c"></div>
</div>
<div class="col-md-12">
<div id="chart2" class="c"></div>
</div>
</div>
</div>