我使用 D3 創建了一個條形圖,但我希望當我的指標位于矩形上方時檢測該矩形并更改其顏色,例如:

因為我的指標在右邊第三個矩形的上方,所以會選擇那個。有沒有辦法做到這一點?
這是我當前的代碼:
const width = 620;
const height = 280;
const svg = d3.selectAll(".canvas")
.append('svg')
.style('display', 'block')
.attr('viewBox', `0 0 ${width} ${height}`)
.attr('preserveAspectRatio','xMinYMin')
const margin = {top:50, bottom:50, left: 50, right: 50}
const graphWidth = width - margin.right - margin.right
const graphHeight = height - margin.bottom - margin.top
const graph = svg.append('g')
.attr('width', graphWidth)
.attr('height', graphHeight)
.attr('transform', `translate(${margin.left},${margin.top})`)
const xAxisGroup = graph.append('g')
.attr('transform', `translate(0, ${graphHeight})`)
const yAxisGroup = graph.append('g')
d3.csv('./SixContinentFirst.csv').then(data => {
africaData = data.map(obj => {
return {infected: (obj.Africa || '0'), date: obj.Dates}
})
console.log(africaData)
const y = d3.scaleLinear()
.domain([0, d3.max(africaData, data => data.infected)])
.range([graphHeight,0])
const x = d3.scaleBand()
.domain(africaData.map(item => item.date))
.range([0,graphWidth])
.paddingInner(0.2)
.paddingOuter(0.2)
const rects = graph.selectAll('rect')
.data(africaData)
rects.enter()
.append('rect')
.attr('width', x.bandwidth)
.attr('height', d => graphHeight - y(d.infected))
.attr('fill', 'orange')
.attr('x', (d) => x(d.date))
.attr('y', d => y(d.infected))
.attr('rx', 8)
.attr('ry', 8)
// .on('mousemove', (d, i) => {
// console.log("Hover")
// })
const xAxis = d3.axisBottom(x)
.tickFormat((d,i) => i % 6 === 0 ? d : '')
let formatter = Intl.NumberFormat('en', { notation: 'compact' });
const yAxis = d3.axisRight(y)
.ticks(3)
.tickFormat(d => formatter.format( d))
xAxisGroup.call(xAxis)
yAxisGroup.call(yAxis)
.attr('transform', `translate(${graphWidth}, 0)`)
.call(g => g.select('.domain').remove())
.call(g => g.selectAll('line').remove())
.selectAll('text')
.attr("font-size", "10")
xAxisGroup
.call(g => g.select('.domain').remove())
.call(g => g.selectAll('line').remove())
.selectAll('text')
.attr("font-size", "10")
})
當我將“mousemove”事件添加到“rects”元素時,它只檢測到我何時直接懸停在 rect 上,而不是當我在它上方時。
uj5u.com熱心網友回復:
一種方法是繪制兩個rects - 一個填充整個graphHeight并且沒有填充(確保設定pointer-events為all),然后繪制原始矩形。然后,此“背景”rect可以回應滑鼠事件,您可以選擇“前景”矩形并更改屬性等。我使用了id基于索引的 s 來方便選擇。
要完成這項作業,您需要為每對rects (前景和背景)包含一個,然后您可以根據滑鼠是在矩形上還是在矩形上,以不同的方式處理滑鼠事件的事件(或者,如果您愿意,也可以相同):
const rects = graph.selectAll('rect')
.data(africaData)
.enter()
.append("g")
.attr("class", "rect-container");
// background rect
rects.append('rect')
// set properties and events
.on('mouseover', function(d, i) {
// handle event
})
.on('mouseout', function(d, i) {
// handle event
})
// foreground rect
rects.append('rect')
// set properties and events
.on('mouseover', function(d, i) {
// handle event
})
.on('mouseout', function(d, i) {
// handle event
})
根據您的原始代碼見下文,但有一些虛擬資料:
const width = 620;
const height = 280;
const svg = d3.selectAll(".canvas")
.append('svg')
.style('display', 'block')
.attr('viewBox', `0 0 ${width} ${height}`)
.attr('preserveAspectRatio','xMinYMin');
const margin = {top:20, bottom:20, left: 20, right: 20}
const graphWidth = width - margin.right - margin.right;
const graphHeight = height - margin.bottom - margin.top;
const graph = svg.append('g')
.attr('width', graphWidth)
.attr('height', graphHeight)
.attr('transform', `translate(${margin.left},${margin.top})`);
const xAxisGroup = graph.append('g')
.attr('transform', `translate(0, ${graphHeight})`);
const yAxisGroup = graph.append('g');
// data for this example
const data = [
{ Africa: 7, Dates: "Jan 2022" },
{ Africa: 1, Dates: "Feb 2022" },
{ Africa: 0, Dates: "Mar 2022" },
{ Africa: 11, Dates: "Apr 2022" },
{ Africa: 7, Dates: "May 2022" },
{ Africa: 7, Dates: "Jun 2022" },
{ Africa: 16, Dates: "Jul 2022" },
{ Africa: 2, Dates: "Aug 2022" },
{ Africa: 8, Dates: "Sep 2022" },
{ Africa: 3, Dates: "Oct 2022" },
{ Africa: 15, Dates: "Nov 2022" },
{ Africa: 12, Dates: "Dec 2022" },
];
// render viz
render(data);
//d3.csv('./SixContinentFirst.csv').then(data => {
function render(data) {
africaData = data.map(obj => {
return {infected: (obj.Africa || '0'), date: obj.Dates}
});
//console.log(africaData);
const y = d3.scaleLinear()
.domain([0, d3.max(africaData, data => data.infected)])
.range([graphHeight,0]);
const x = d3.scaleBand()
.domain(africaData.map(item => item.date))
.range([0,graphWidth])
.paddingInner(0.2)
.paddingOuter(0.2);
const rects = graph.selectAll('rect')
.data(africaData)
.enter()
.append("g")
.attr("class", "rect-container");
// background rect
rects.append('rect')
.attr('width', x.bandwidth)
.attr('height', d => graphHeight)
.attr('fill', 'none')
.attr('x', (d) => x(d.date))
.attr('y', d => 0)
.attr('pointer-events', 'all')
.on('mouseover', function(d, i) {
d3.select(`#bar_${i}`).attr('fill', 'red')
})
.on('mouseout', function(d, i) {
d3.select(`#bar_${i}`).attr('fill', 'orange')
})
// foreground rect
rects.append('rect')
.attr('width', x.bandwidth)
.attr('height', d => graphHeight - y(d.infected))
.attr('fill', 'orange')
.attr('id', (d, i) => `bar_${i}`)
.attr('class', "foreground-rect")
.attr('x', (d) => x(d.date))
.attr('y', d => y(d.infected))
.attr('rx', 8)
.attr('ry', 8)
.attr('pointer-events', 'all')
.on('mouseover', function(d, i) {
d3.select(`#bar_${i}`).attr('fill', 'green')
})
.on('mouseout', function(d, i) {
d3.select(`#bar_${i}`).attr('fill', 'orange')
})
const xAxis = d3.axisBottom(x)
.tickFormat((d,i) => i % 6 === 0 ? d : '');
let formatter = Intl.NumberFormat('en', { notation: 'compact' });
const yAxis = d3.axisRight(y)
.ticks(3)
.tickFormat(d => formatter.format( d));
xAxisGroup.call(xAxis);
yAxisGroup.call(yAxis)
.attr('transform', `translate(${graphWidth}, 0)`)
.call(g => g.select('.domain').remove())
.call(g => g.selectAll('line').remove())
.selectAll('text')
.attr("font-size", "10");
xAxisGroup
.call(g => g.select('.domain').remove())
.call(g => g.selectAll('line').remove())
.selectAll('text')
.attr("font-size", "10");
}
//)
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div class="canvas"></div>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/468941.html
標籤:javascript d3.js 图形 条形图
