热力图与迷你图的联动Tooltip交互实现需求技术问询
Got it, let's get those hover interactions working between your heatmap and sparkline! Here's a step-by-step breakdown of how to modify your existing code to achieve both effects:
1. Show Red Dot on Sparkline When Hovering Heatmap Cell
First, we'll add mouseover/mouseout handlers to your heatmap rectangles. These will trigger adding/removing a red dot on the sparkline that maps to the hovered cell's data.
Modify your heatmap rect creation code like this:
var cells = svg.selectAll('rect') .data(data) .enter() .append('g') .append('rect') // ... keep your existing attr() for x, y, width, height, fill, etc. .on('mouseover', function(event, d) { // Optional: Highlight the hovered heatmap cell d3.select(this).style('opacity', 0.7); // Add a red dot to the sparkline at the corresponding data point // Replace xSpark/ySpark with your sparkline's scale functions // Replace sparklineSvg with your sparkline's SVG container selection sparklineSvg.append('circle') .attr('class', 'heatmap-hover-dot') .attr('cx', xSpark(d.xKey)) // Use the matching x field from your data .attr('cy', ySpark(d.yKey)) // Use the matching y field from your data .attr('r', 4) .attr('fill', '#ff3333'); }) .on('mouseout', function(event, d) { // Reset heatmap cell opacity d3.select(this).style('opacity', 1); // Remove the red dot from the sparkline sparklineSvg.selectAll('.heatmap-hover-dot').remove(); });
2. Highlight Heatmap Cell When Hovering Sparkline
Next, we'll add hover handlers to your sparkline elements (whether they're points, a path, or lines) to trigger highlighting the corresponding heatmap cell.
If your sparkline uses individual points (circles):
// Assuming you've created sparkline points like this: sparklineSvg.selectAll('.sparkline-point') .data(sparklineData) .enter() .append('circle') // ... your existing sparkline point attributes .on('mouseover', function(event, sparkData) { // Find and highlight the matching heatmap cell svg.selectAll('rect') .filter(function(heatData) { // Match using a shared identifier (e.g., id, timestamp, category) return heatData.uniqueId === sparkData.uniqueId; }) .style('opacity', 0.7); // Or use a border/fill color change for highlighting }) .on('mouseout', function(event, sparkData) { // Reset the heatmap cell's appearance svg.selectAll('rect') .filter(function(heatData) { return heatData.uniqueId === sparkData.uniqueId; }) .style('opacity', 1); });
If your sparkline is a continuous path (line):
For line sparklines, you'll need to find the closest data point to the mouse position using d3.bisector:
sparklineSvg.select('.sparkline-path') .on('mousemove', function(event) { // Get mouse position relative to the sparkline const [mouseX] = d3.pointer(event); // Use bisector to find the closest data point to the mouse const bisectX = d3.bisector(d => d.xKey).left; const closestIndex = bisectX(sparklineData, xSpark.invert(mouseX)); const closestData = sparklineData[closestIndex]; // Highlight the matching heatmap cell svg.selectAll('rect') .filter(d => d.uniqueId === closestData.uniqueId) .style('opacity', 0.7); }) .on('mouseout', function() { // Reset all heatmap cells svg.selectAll('rect').style('opacity', 1); });
Key Notes:
- Data Matching: Make sure your heatmap and sparkline data share a unique identifier (like
uniqueId,date, orcategory) so you can accurately pair cells with sparkline points. - Customization: Swap out
opacitychanges with border styles (e.g.,stroke: 'black',stroke-width: 2) or fill color adjustments if you prefer a different highlight effect. - Cleanup: Using a specific class for the sparkline red dot (like
.heatmap-hover-dot) ensures you only remove the hover dot, not other sparkline elements.
内容的提问来源于stack exchange,提问作者user7558372

