Событие наведения мыши D3 не вызывается на нижних элементах - PullRequest
0 голосов
/ 27 августа 2018

Код ниже относится к тепловой карте. Я добавил всплывающую подсказку в svg, однако событие mouseover не запускается для всех элементов на графике. Подсказка не отображается для последней строки (представляет декабрьские месяцы).

  • Я изменил размер SVG, затем поиграл с отступом и полем, не повезло.
  • Я тоже пытался вызывать всплывающую подсказку безуспешно

Может ли кто-нибудь указать мне правильное направление?

Для живого приложения Нажмите Здесь

$(document).ready(function() {
$.getJSON(
    'https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/global-temperature.json',


    function(data) {

            const width = 900
            const height = 600
          let dataset = []
            const baseTemp = data.baseTemperature

            data.monthlyVariance.forEach((entry) => {
                dataset.push([ entry.year, entry.month - 1, entry.variance ])
            })

            const maxYear = (d3.max(dataset, d => d[0]) + 2)
            const minYear = d3.min(dataset, d => d[0])
            const colorDomain = [ 1,2,3,4,5,6,7,8,9,10,11,12,13 ]
            const colorRange = [
                '#3d86d3',
                '#47a9c1',
                '#58d3c5',
                '#3fc18b',
                '#3fc162',
                '#86ba50',
                '#7fc141',
                '#98c43a',
                '#a9c140',
                '#c4b121',
                '#d1801d',
                '#d1491b',
                '#d1361b'
         ]

            let xScale = d3
                .scaleLinear()
                .domain([ minYear, maxYear ])
                .range([ 0, width ])

            let yScale = d3
                .scaleLinear()
                .domain([ 11 , 0 ])
                .range([ height  , 0 ])

            let colorScale = d3.scaleQuantile()
                .domain(colorDomain)
                .range(colorRange)

        let monthFormatter = d3.timeFormat('%B')
            let  tickFormatter = (month) => {
                return monthFormatter(new Date(minYear, month))
            }
            const xAxis = d3.axisBottom(xScale).tickFormat(d3.format('d'))
            const yAxis = d3.axisLeft(yScale).tickFormat(tickFormatter).tickSize([ 0 ])

            var tooltip = d3
                .select('.chart')
                .append('div')
                .attr('id', 'tooltip')

            let svg = d3.select('.chart')
                .append('svg')
                .attr('width', width)
                .attr('height', height)
                .style('padding', '40 20 140 150')

            svg
                .selectAll('rect')
        .data(dataset)
        .enter()
        .append('rect')
        .attr('x', d => xScale(d[0]))
        .attr('y', d => yScale(d[1]))
                .attr('width', 4)
                .attr('height', (height/10))
                .attr('class', 'cell')
                .attr('fill', d => {
                     return colorScale(Math.floor(baseTemp + d[2]))
                })
              .attr('data-year', d => d[0])
                .attr('data-month', d => d[1])
                .attr('data-temp', d => (d[2] + baseTemp))
                .on('mouseover', (d) => {
                    tooltip
                        .transition()
                        .style('opacity', 1)
                        .style('visibility', 'visible')
                    tooltip
                        .attr('data-year', d[0])
                        .html(d[0] + ', ' + monthFormatter(new Date(d[0],d[1]))+'</br>')
                        .style('left', (d3.event.pageX + 10) + 'px')
                        .style('top', (d3.event.pageY + 10) + 'px')
                })

            svg.on('mouseout', () => {
                tooltip.transition().style('visibility', 'hidden')
            })

        }
     )
  })

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Вы должны настроить домен yScale.

вы звоните по номеру 0..11, но хотите, чтобы было место для отображения месяца 11, поэтому домен расширяется до 12.

  let yScale = d3
    .scaleLinear()
    .domain([ 12, 0 ])
    .range([height , 0]);

Для расчета высоты прямоугольников используйте yScale

    .attr('height', yScale(1)-yScale(0))

Вы можете использовать аналогичный прием для вычисления ширины прямоугольника на основе области X.

0 голосов
/ 27 августа 2018

Ваша область SVG недостаточно велика, чтобы удерживать последний ряд этих RECT, последний ряд прямоугольника находится вне области события. Просто установите высоту SVG для хранения последнего ряда.

Вы устанавливаете диапазон от 0-height и используете его как y attr для rect, что означает, что последняя строка будет проходить над областью SVG, когда при наведении указателя мыши на эту последнюю строку строки, это фактически только элемент mouseover svg, поэтому событие всплывает из SVG во внешний div, событие из этих прямоугольных элементов отсутствует, поэтому обработчик события mouseover не сработал

...