所以我已经离开并使用它作为教程实现了与this类似的东西。但是,当它达到关于工具提示的点时,我想做一些稍微不同的事情,我真的想使用d3-tip。所以我花了很多时间学习如何使用d3-tip但似乎我看到的每个人都在定义元素,然后将mouseover和mouseout事件附加到它们以便显示工具提示。我不相信我能做到这一点,因为我使用之前根据鼠标在图表上的位置绘制圆圈的方法。所以我想知道如何让d3-tip与这个实现一起工作,或者它是否可能?
以下是我的代码:
var margin = {
top: 20,
left: 50,
right: 50,
bottom: 50
},
width = $element.innerWidth() - margin.left - margin.right,
height = 0.2 * width;
var parseTime = d3.timeParse('%m/%d/%Y');
data.forEach(function(d) {
d.date = parseTime(d.date);
d.price = +d.price;
});
data.sort(function(a, b) {
return d3.ascending(a.date, b.date);
});
var formatDate = d3.timeFormat('%b %-d / %Y');
var bisectDate = d3.bisector(function(d) { return d.date; }).left;
var x = d3.scaleTime()
.domain(d3.extent(data, function(d, i) {
return d.date;
}))
.range([0, width]);
var y = d3.scaleLinear()
.domain(d3.extent(data, function(d, i) {
return d.price;
}))
.range([height, 0]);
var xAxis = d3.axisBottom(x)
.tickSizeOuter(0);
var yAxis = d3.axisLeft(y)
.ticks(5)
.tickSizeOuter(0);
var area = d3.area()
.x(function(d) { return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.price); });
var line = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.price); });
var tip = d3.tip()
.attr('class', 'd3-tip')
.offset([-10, 0])
.html(function(d) {
return 'Closing: ' + d.price +
'<br />' +
'Date: ' + formatDate(d.date);
});
var svg = d3.select('#priceChart')
.append('svg')
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
svg.call(tip);
svg.append('g')
.attr('class', 'x axis')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
svg.append('g')
.attr('class', 'y axis')
.call(yAxis);
var areaSvg = svg.append('g');
areaSvg.append('path')
.attr('class', 'area')
.attr('d', area(data))
.style('opacity', 0.3);
var lineSvg = svg.append('g');
lineSvg.append('path')
.attr('class', 'line')
.attr('d', line(data));
var focus = svg.append('g')
.style('display', 'none');
focus.append('line')
.attr('class', 'x dash')
.attr('y1', 0)
.attr('y2', height);
focus.append('line')
.attr('class', 'y dash')
.attr('x1', width)
.attr('x2', width);
focus.append('circle')
.attr('class', 'y circle')
.attr('r', 5);
svg.append('rect')
.attr('width', width)
.attr('height', height)
.style('fill', 'none')
.style('pointer-events', 'all')
.on('mouseover', function() { focus.style('display', null); })
.on('mouseout', function() { focus.style('display', 'none'); })
.on('mousemove', mousemove);
function mousemove() {
var x0 = x.invert(d3.mouse(this)[0]),
i = bisectDate(data, x0, 1),
d0 = data[i - 1],
d1 = data[i],
d = x0 - d0.date > d1.date - x0 ? d1 : d0;
focus.select('circle.y')
.attr('transform', 'translate(' + x(d.date) + ',' + y(d.price) + ')');
focus.select('.x')
.attr('transform', 'translate(' + x(d.date) + ',' + y(d.price) + ')')
.attr('y2', height - y(d.price));
focus.select('.y')
.attr('transform', 'translate(' + width * -1 + ',' + y(d.price) + ')')
.attr('x2', width + width);
}
另外,我已经有了这个jsFiddle here,它显示了我目前所有的工作。我已经把所有东西都安排到位,这一切都很好,减去实际显示的工具提示。
答案 0 :(得分:3)
我改变了你的小提琴,以便显示工具提示并相应地更新文本:
.on('mouseover', function(d) {
focus.style('display', null);
if(d!=undefined){
tip.show(d);// give the tip the data it needs to show
}
})
.on('mouseout', function() {
focus.style('display', 'none');
tip.hide();
})
我还改变了mousemove功能来更新提示
function mousemove() {
var x0 = x.invert(d3.mouse(this)[0]),
i = bisectDate(data, x0, 1),
d0 = data[i - 1],
d1 = data[i],
d = x0 - d0.date > d1.date - x0 ? d1 : d0;
focus.select('circle.y')
.attr('transform', 'translate(' + x(d.date) + ',' + y(d.price) + ')');
focus.select('.x')
.attr('transform', 'translate(' + x(d.date) + ',' + y(d.price) + ')')
.attr('y2', height - y(d.price));
focus.select('.y')
.attr('transform', 'translate(' + width * -1 + ',' + y(d.price) + ')')
.attr('x2', width + width);
// we need to update the offset so that the tip shows correctly
tip.offset([y(d.price) - 20, x(d.date) - (width/2)] ) // [top, left]
tip.show(d);
}
还更新了css:
.d3-tip:after {
box-sizing: border-box;
display: inline;
font-size: 15px;
width: 1%;
line-height: 4;
color: rgba(0, 0, 0, 0.8);
content: "\25BC";
position: absolute;
text-align: center;
pointer-events: none;
left: 45%;
}
https://jsfiddle.net/mkaran/5t3ycyxs/1/
虽然可能有更好的方法。希望这有帮助!祝你好运!