У меня есть Карта Choropleth , где подсказка работает для большей части ее, но центральные штаты теперь показывают подсказку ... в лицо, они даже не запускают функцию обратного вызова mouseout вообще(протестировано с командой console.log).
Сначала я использовал d3-tip, но это не сработало, и это был первый раз, когда я пытался, поэтому я подумал, что могу сделать что-то не такпоэтому я решил реализовать стандартный div, который переключается между display: none
и display: block
, и когда он все еще не работал, я добавил команду console.log, чтобы посмотреть, работает ли функция обратного вызова вообще, и это не так,В основном это проблема Канзаса, но у некоторых округов в соседних штатах тоже есть проблемы.и я знаю, что это не проблема с набором данных, потому что приведенный пример , который извлекает из того же набора данных, работает нормально.
Вот css для всплывающей подсказки:
#tooltip{
display: none;
background-color: rgba(32,32,32,1);
position: absolute;
border-radius: 10px;
padding: 10px;
width: 200px;
height: 40px;
color: white
}
и код JS:
$(function(){
//svg setup
const svgPadding = 60;
const svgWidth = 1000;
const svgHeight = 600;
var svg = d3.select('body')
.append('svg')
.attr('width', svgWidth)
.attr('height', svgHeight)
.attr('id', 'map');
function createChart(topData, eduData){
//scales
var colorScale = d3.scaleSequential(d3.interpolateBlues);
var unitScale = d3.scaleLinear()
.domain(d3.extent(eduData.map(e => e.bachelorsOrHigher)))
.range([0,1])
//map
var path = d3.geoPath();
svg.selectAll('.county')
.data(topojson.feature(topData, topData.objects.counties).features)
.enter()
.append('path')
.attr('class', 'county')
.attr('d', path)
.attr('data-fips', d=>d.id)
.attr('eduIndex', d => eduData.map(e => e.fips).indexOf(d.id))
.attr('data-education', function(){
var index = d3.select(this).attr('eduIndex');
if (index == -1)return 0;
return eduData[
d3.select(this).
attr('eduIndex')
]
.bachelorsOrHigher
})
.attr('fill', function(){
var value = d3.select(this).attr('data-education');
return colorScale(unitScale(value));
})
.attr('stroke', function(){
return d3.select(this).attr('fill');
})
.on('mouseover', function(d){
var index = d3.select(this).attr('eduIndex');
var education = d3.select(this).attr('data-education');
var county = index == -1 ? 'unknown' : eduData[index].area_name;
console.log(county)
var tooltip = d3.select('#tooltip')
.style('left', d3.event.pageX + 10 + 'px')
.style('top', d3.event.pageY + 10 + 'px')
.style('display', 'block')
.attr('data-education', education)
.html(`${county}: ${education}`)
})
.on('mouseout', ()=>d3.select('#tooltip').style('display', 'none'));
svg.append('path')
.datum(topojson.mesh(topData, topData.objects.states, (a,b)=>a.id!=b.id))
.attr('d', path)
.attr('fill', 'rgba(0,0,0,0)')
.attr('stroke', 'black')
.attr('stroke-width', 0.4)
//legend scale
const legendWidth = 0.5 * svgWidth;
const legendHeight = 30;
const numCells = 1000;
const cellWidth = legendWidth/numCells;
const legendUnitScale = d3.scaleLinear()
.domain([0, legendWidth])
.range([0,1]);
//legend
var legend = svg.append('svg')
.attr('id', 'legend')
.attr('width', legendWidth)
.attr('height', legendHeight)
.attr('x', 0.5 * svgWidth)
.attr('y', 0)
for (let i = 0; i < numCells; i++){
legend.append('rect')
.attr('x', i * cellWidth)
.attr('width', cellWidth)
.attr('height', legendHeight - 10)
.attr('fill', colorScale(legendUnitScale(i*cellWidth)))
}
}
//json requests
d3.json('https://raw.githubusercontent.com/no-stack-dub-sack/testable-projects-fcc/master/src/data/choropleth_map/counties.json')
.then(function(topData){
d3.json('https://raw.githubusercontent.com/no-stack-dub-sack/testable-projects-fcc/master/src/data/choropleth_map/for_user_education.json')
.then(function(eduData){
createChart(topData, eduData);
});
});
});