[D3] Add hovercard
The way to add hovercard is
- Append a div with class 'hovercard'
- in the tick function, positioning the hovercard with 'd3.event.pageX and pageY'
.hovercard { position: absolute; max-width: 400px; height: auto; padding: 5px; background-color: white; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; -webkit-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); -moz-box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); box-shadow: 4px 4px 10px rgba(0, 0, 0, 0.4); pointer-events: none; font: 12px sans-serif; }
const hovercard = d3.select('body') .append('div') .attr('class', 'hovercard') .style('opacity', 0) .style('width', 400);
function ticked() { // adjust nodes containers position svgNodes .attr('transform', d =>`translate(${d.x},${d.y})`) .call(d3.drag() .on('start', dragstarted) .on('drag', dragged) .on('end', dragended)); // Curve paths path .attr('d', (d) => { const curve = d.battle_number * .5; const dx = d.target.x - d.source.x; const dy = d.target.y - d.source.y; const dr = Math.sqrt(dx * dx * curve + dy * dy * curve); return `M${d.source.x},${d.source.y}A${dr},${dr} 0 0,1 ${d.target.x},${d.target.y}`; }); path.on('mouseover', d => { hovercard .transition() .duration(300) .delay(20) .style('opacity', 1); const tip = '<h2>' + d.name + '</h2>' + '<h4>' + d.source.name + ' attacked ' + d.target.name + ' and the outcome was a ' + d.attacker_outcome + '</h4>' + '<h3>Details</h3>' + '<strong> Attacker King: </strong>'+d.attacker_king + '<br/>'+ '<strong> Battle Type: </strong>'+d.battle_type + '<br/>'+ '<strong> Major Death?: </strong>'+d.major_death + '<br/>'+ '<strong> Major Capture?: </strong>'+d.major_capture + '<br/>'+ '<strong> Attacker Size: </strong>'+d.value + '<br/>'+ '<strong> Defender Size: </strong>'+d.defender_size + '<br/>'+ '<strong> Region / Location: </strong>'+d.region+ ' / ' + d.location + '<br/>'+ '<strong> Attacking Commander: </strong>'+d.attacker_commander + '<br/>'+ '<strong> Defending Commander: </strong>'+d.defender_commander; hovercard .html(tip) .style('left', d3.event.pageX + 'px') .style('top', d3.event.pageY + 'px'); }); path.on('mouseout', d => { hovercard .transition() .duration(500) .style('opacity', 0); }); } });
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2016-09-07 [Javascript] Maybe Functor
2015-09-07 [Flux] 3. Actions
2015-09-07 [RxJS] Aggregating Streams With Reduce And Scan using RxJS
2015-09-07 [RxJS] map vs flatMap
2015-09-07 [RxJS] Stream Processing With RxJS vs Array Higher-Order Functions
2015-09-07 [MODx] Solve cannot upload large file