D3 鼠标悬停事件未在底部元素上触发
D3 mouseover event is not triggered on the bottom elements
下面的代码与热图有关。我向 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')
})
}
)
})
您的 SVG 区域不够大,无法容纳那些 RECT 的最后一行,矩形的最后一行不在事件范围内 area.Just 设置 SVG 的高度以容纳最后一行。
你设置范围从 0-height,并将它用作 rect 的 y 属性,这意味着最后一行将越过 SVG 的区域,当你将鼠标悬停在最后一行区域上时,它实际上只将鼠标悬停在 svg 元素上,所以事件从 SVG 冒泡到外部 div ,没有来自内部那些 rect 元素的事件,所以没有触发鼠标悬停事件处理程序
您必须调整 yScale
的域。
您用数字 0..11 调用它,但您希望有空间显示第 11 个月,因此域跨度为 12。
let yScale = d3
.scaleLinear()
.domain([ 12, 0 ])
.range([height , 0]);
要计算矩形的高度,请使用 yScale
.attr('height', yScale(1)-yScale(0))
您可以使用类似的技巧根据 X 的域计算矩形的宽度。
下面的代码与热图有关。我向 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')
})
}
)
})
您的 SVG 区域不够大,无法容纳那些 RECT 的最后一行,矩形的最后一行不在事件范围内 area.Just 设置 SVG 的高度以容纳最后一行。
你设置范围从 0-height,并将它用作 rect 的 y 属性,这意味着最后一行将越过 SVG 的区域,当你将鼠标悬停在最后一行区域上时,它实际上只将鼠标悬停在 svg 元素上,所以事件从 SVG 冒泡到外部 div ,没有来自内部那些 rect 元素的事件,所以没有触发鼠标悬停事件处理程序
您必须调整 yScale
的域。
您用数字 0..11 调用它,但您希望有空间显示第 11 个月,因此域跨度为 12。
let yScale = d3
.scaleLinear()
.domain([ 12, 0 ])
.range([height , 0]);
要计算矩形的高度,请使用 yScale
.attr('height', yScale(1)-yScale(0))
您可以使用类似的技巧根据 X 的域计算矩形的宽度。