如何在D3地图的鼠标悬停事件中显示多类数值?
搞定D3地图悬停同时显示价格与评分的问题
嘿,我瞅了你的代码,核心问题在于数据存储方式不对,还有tooltip的交互逻辑没写完整。现在你用valueHash存price和points时,同一个国家名的键会被后面的值覆盖,而且没给地图元素加鼠标悬停事件来展示多字段信息。我来一步步帮你修正:
1. 先把数据存对:每个国家对应一个包含price和points的对象
你原来的valueHash会让points覆盖price,改成对象结构就能同时存两个值了:
var valueHash = {}; data.forEach(function(d) { valueHash[d[MAP_KEY]] = { price: +d[MAP_VALUE], points: +d[MAP_VALUE2] }; });
2. 给国家路径加完整的鼠标悬停事件,用来展示tooltip
你原来的代码只到设置fill样式,没写鼠标事件,这部分是关键。给每个国家路径加上mouseover、mousemove、mouseout事件,就能控制tooltip显示内容和位置:
country.enter().insert("path") .attr("class", "country") .attr("d", path) .attr("id", function(d,i) { return d.id; }) .style("fill", function(d) { // 这里我用price来设置颜色,你也可以换成points var countryData = valueHash[d.properties.name]; if (countryData) { var colorIndex = quantize(countryData.price); var color = colors[colorIndex].getColors(); return `rgb(${color.r}, ${color.g}, ${color.b})`; } return "#ccc"; // 没有数据的国家用灰色填充 }) .on("mouseover", function(d) { var countryData = valueHash[d.properties.name]; if (!countryData) return; // 没有数据就不显示tooltip // 构建tooltip的HTML内容,同时展示两个字段 var tooltipContent = ` <div class="tooltip_key">${d.properties.name}</div> <div>平均价格: <span class="tooltip_value">${countryData.price}</span></div> <div>平均评分: <span class="tooltip_value">${countryData.points}</span></div> `; $("#tooltip-container").html(tooltipContent).show(); }) .on("mousemove", function() { // 让tooltip跟着鼠标移动,避免挡住地图 $("#tooltip-container").css({ top: d3.event.pageY + 15 + "px", left: d3.event.pageX + 15 + "px" }); }) .on("mouseout", function() { $("#tooltip-container").hide(); });
3. 修正颜色比例尺(可选,看你想用哪个字段做颜色区分)
如果你想用price来区分颜色,比例尺的domain要基于price的范围,原来的写法有问题,改成这样:
var quantize = d3.scale.quantize() .domain([ d3.min(data, function(d){ return +d[MAP_VALUE]; }), // MAP_VALUE是price d3.max(data, function(d){ return +d[MAP_VALUE]; }) ]) .range(d3.range(COLOR_COUNTS).map(function(i) { return i; }));
要是想用points做颜色区分,把上面的MAP_VALUE换成MAP_VALUE2就行。
小提醒
你的CSV里的国家名称必须和地图里的d.properties.name完全匹配,不然会找不到对应数据哦~
内容的提问来源于stack exchange,提问作者MetalCat
相关产品推荐
相关产品推荐

