Всплывающая подсказка в d3 / карта топографа не работает - PullRequest
1 голос
/ 26 сентября 2019

У меня есть Карта 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);
    });
  });
});

1 Ответ

3 голосов
/ 26 сентября 2019

Проблема в том, что вы применяете заливку к сетке состояний.Давайте изменим заливку с rgba(0,0,0,0) на rgba(10,10,10,0.1):

enter image description here

Теперь должно быть понятно, почему взаимодействие мыши не работает в определенных областях: сетка заполняется поверх него.Независимо от того, что вы не можете видеть сетку из-за ее непрозрачности 0, она все равно перехватывает события мыши.

Сетка предназначена только для представления границ: это коллекция geojson lineStrings (см. здесь тоже).Сетка не предназначена для заполнения, она должна иметь только обводку.

Если вы измените заливку сетки на none или события указателя сетки на ноль, то карта будет работать, как и ожидалось..

...