我在这里有一个矮人-https://plnkr.co/edit/qDi8bm3xh3hdaV059AXX?p=preview
当鼠标悬停在条形图上时,它是带有工具提示的简单条形图。
在工具提示中,我要显示未用于构建栏的数据中的信息。
我可以在示例中执行此操作,但是可以创建html结构以将更多数据添加到工具提示中。
d3.selectAll('.bar').on("mouseover", ()=>{
d3.select('.chart-tooltip').style("display", null)
})
.on("mouseout", ()=>{
d3.select('.chart-tooltip').style("display", "none")
.transition()
.duration(500)
});
d3.selectAll('.bar').on("mousemove", (d)=>{
let html = d.day;
d3.select('.chart-tooltip')
.style("left", d3.event.pageX + 15 + "px")
.style("top", d3.event.pageY - 25 + "px")
.html(html)
});
答案 0 :(得分:1)
如果可以将新工具提示数据与要渲染的工具栏<->匹配,则可以使用d3选择器的索引来匹配数组中的数据,请参见示例:
const data_tooltip = [
{
text: 'BAR 1',
html: '<strong>BAR 1</strong>'
},
{
text: 'BAR 2',
html: '<strong>BAR 2</strong>'
}
];
d3.selectAll('.bar').on("mousemove", (d, index)=>{ // index iterator of your bar event
d3.select('.chart-tooltip')
.style("left", d3.event.pageX + 15 + "px")
.style("top", d3.event.pageY - 25 + "px")
.html(data_tooltip[index].html)
});
const w = 400;
const h = 300;
const margin = {
top: 20,
bottom: 60,
left: 40,
right: 20
}
const width = w - margin.left - margin.right
const height = h - margin.top - margin.bottom
const data = [
{
phase: 'One',
start: 118,
finish: 102,
day: 'Monday',
time: 'Morning'
},
{
phase: 'Two',
start: 100,
finish: 112,
day: 'Tuesday',
time: 'Afternoon'
}
];
const data_tooltip = [
{
text: 'BAR 1',
html: '<strong>BAR 1</strong>'
},
{
text: 'BAR 2',
html: '<strong>BAR 2</strong>'
}
];
const x = d3.scaleBand()
.range([0, width])
.padding(.33)
const y = d3.scaleLinear()
.rangeRound([height, 0]);
const svg = d3.select("body").append("svg")
.attr("id", "svg")
.attr("width", w)
.attr("height", h);
const chart = svg.append('g')
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("preserveAspectRatio", "xMinYMin meet");
const tooltip = d3.select('body').append("div")
.classed('tooltip chart-tooltip', true)
.style('display', 'none');
const y_axis = d3.axisLeft()
.scale(y)
.tickSize(-width)
const x_axis = d3.axisBottom()
.scale(x)
.tickSize(-height )
.tickPadding(10)
const update = (data) =>{
x.domain(data.map(function(d) {
return d.phase
}));
y.domain(
d3.extent(
d3.extent(data, (d) => {
return d.start+2;
})
.concat(d3.extent(data, (d) => {
return d.finish-6;
})
)
));
chart.append("g")
.classed('y-axis', true)
.call(y_axis)
chart.append("g")
.call(x_axis)
.classed('x-axis', true)
.attr("transform", "translate(0," + height + ")")
const bar = chart.selectAll(".bar")
.data(data)
bar.enter()
.append("rect")
.attr('class', 'bar')
.attr('data-arrow', (d, i) => {
return d.start > d.finish ? 'down' : 'up'
})
.attr("x", (d, i) => {
return x(d.phase)
})
.attr("width", (d, i) => {
return x.bandwidth()
})
.attr("y", (d, i) => {
if(d.start < d.finish){
return y(d.finish);
}else{
return y(d.start);
}
})
.attr("height", (d, i) => {
if(d.start < d.finish){
return y(d.start) - y(d.finish);
}else{
return y(d.finish) - y(d.start);
}
});
d3.selectAll('.bar').on("mouseover", ()=>{
d3.select('.chart-tooltip').style("display", null)
})
.on("mouseout", ()=>{
d3.select('.chart-tooltip').style("display", "none")
.transition()
.duration(500)
});
d3.selectAll('.bar').on("mousemove", (d, i)=>{
d3.select('.chart-tooltip')
.style("left", d3.event.pageX + 15 + "px")
.style("top", d3.event.pageY - 25 + "px")
.html(data_tooltip[i].html)
});
d3.selectAll('g.tick')
.filter((d) => d==100)
.attr('class', 'grid-100')
}
update(data)
body{
background:#f5f6f7;
}
h1, h2 {
font-family: Lato;
}
#svg{
background-color: white;
}
.bar{
shape-rendering: crispEdges;
fill: mediumvioletred;
}
.bar-label{
fill: white;
}
.bar-label{
text-anchor: end;
}
.grid line{
stroke: #bbb;
}
.grid .tick:nth-child(7) line{
stroke-width: 3;
stroke: #999;
}
.divide{
fill: lightgrey;
}
.bar-1{
fill: red;
}
.chart-tooltip{
background: lightgrey;
border-radius: 4px;
display: inline-block;
font-family: sans-serif;
font-size: 12px;
padding: 10px;
position: absolute;
width: auto;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<div id="app"></div>