我正在做freecodecamp choropleth地图项目:https://www.freecodecamp.org/learn/data-visualization/data-visualization-projects/visualize-data-with-a-choropleth-map
这是一张包含教育数据的美国县地图。
除了我的工具提示,一切都正常。在鼠标悬停时,工具提示应该显示县名称、百分比等。实际上,无论鼠标悬停在地图中的哪个县,都会显示一个县的信息。
如果我附加一个d3标题工具提示,数据将正确显示。我相信这与我引用的数据集不是.data(dataset).enter()
调用中指定的数据集有关。请参阅下面我的代码选择,问题代码在底部附近注释。谢谢
// Fetch the population/education dataset and feed it into a function that will merge it with the map dataset
fetch("https://cdn.freecodecamp.org/testable-projects-fcc/data/choropleth_map/for_user_education.json")
.then(resp => resp.json())
.then(popData => dataMerge(popData))
// Merge datasets -- this fetch is for the map geometry data
function dataMerge(popData) {
fetch("https://cdn.freecodecamp.org/testable-projects-fcc/data/choropleth_map/counties.json")
.then(resp => resp.json())
.then(geoData => {
const counties = geoData.objects.counties.geometries;
popData.forEach(elem => {
let fips = elem.fips;
for(let i=0; i<counties.length; i++) {
let id = counties[i].id;
if(id === fips) {
counties[i] = Object.assign(counties[i], elem);
break;
}
}
})
return geoData;
})
.then(geoData => svgGenerate(geoData))
}
// Generate the svg
function svgGenerate(data) {
let geojson = topojson.feature(data, data.objects.counties);
let statesjson = topojson.feature(data, data.objects.states)
// let projection = d3.geoAlbers();
const path = d3.geoPath();
const canvas = svg.append('g')
// .attr('padding', padding)
canvas.selectAll('path')
.data(geojson.features)
.enter()
.append('path')
.attr('d', path)
.attr('class', 'county')
// since I'm using the geojson.features data, I must pull the county data explicitly.
.attr('data-fips', (d,i)=>data.objects.counties.geometries[i].fips)
.attr('data-education', (d,i)=>data.objects.counties.geometries[i].bachelorsOrHigher)
.attr('fill', (d,i) => {
const percentage = data.objects.counties.geometries[i].bachelorsOrHigher
if(percentage<10) return 'rgb(255, 255, 255)'
else if(percentage<20) return 'rgb(223, 254, 240)'
else if(percentage<30) return 'rgb(187, 255, 226)'
else if(percentage<40) return 'rgb(131, 255, 202)'
else if(percentage<50) return 'rgb(0, 255, 146)'
else if(percentage<60) return 'rgb(5, 215, 126)'
else if(percentage<70) return 'rgb(1, 99, 57)'
else return 'black'
})
.attr('transform', 'translate(160,30)')
// ****** HERE IS WHAT FAILS *******
.on('mouseenter', (e,d) => {
tooltip.style('visibility','visible')
.style('left', event.pageX+'px')
.style('bottom', h-event.pageY+300+'px')
.html((d,i) => `${data.objects.counties.geometries[i].area_name}<br/>${data.objects.counties.geometries[i].bachelorsOrHigher}%`)
.attr('data-education',(d,i)=>data.objects.counties.geometries[i].bachelorsOrHigher)
})
.on('mouseout', (e,d) => {
tooltip.style('visibility','hidden')
})
.append('title')
.text((d,i)=>data.objects.counties.geometries[i].fips)
我终于解决了这个问题。在.on('mouseover', ...)
中,从数据集接收的索引始终为0——d变量仅引用触发鼠标事件的元素的数据。我最终给了每个元素一个自定义的";索引";属性,然后使用let index = e.target.getAttribute('index')
从函数内部检索