【问题标题】:D3 mouseover event is not triggered on the bottom elementsD3 mouseover 事件不会在底部元素上触发
【发布时间】:2018-08-27 16:41:31
【问题描述】:

下面的代码与热图有关。我在 svg 中添加了一个工具提示,但是,鼠标悬停事件并未针对图表上的所有元素触发。最后一行没有显示工具提示(代表十二月)。

  • 我重新调整了 SVG 的大小,然后使用了填充和边距,但运气不佳。
  • 我也尝试过单独调用工具提示,但没有成功

有人能指出正确的方向吗?

实时应用点击Here

$(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')
            })

        }
     )
  })

【问题讨论】:

    标签: javascript jquery css d3.js mouseevent


    【解决方案1】:

    你必须调整yScale的域。

    您使用数字 0..11 调用它,但您希望有空间显示第 11 个月,因此域跨越到 12。

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

    要计算矩形的高度,请使用yScale

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

    您可以使用类似的技巧根据 X 的域计算矩形的宽度。

    【讨论】:

    • 谢谢@riov8。我看到并理解我的错误。
    【解决方案2】:

    您的 SVG 区域不够大,无法容纳这些 RECT 的最后一行,rect 的最后一行超出了事件区域。只需设置 SVG 的高度以容纳最后一行。

    您将范围设置为 0 高度,并将其用作 rect 的 y 属性,这意味着最后一行将越过 SVG 的区域,当您将鼠标悬停在最后一行区域时,它实际上只是将鼠标悬停在 svg 元素上,所以事件从 SVG 冒泡到外部 div ,内部的那些 rect 元素没有事件,所以没有 mouseover 事件处理程序触发

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-25
      • 2021-12-30
      • 1970-01-01
      • 2022-12-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多