Я пытаюсь добавить всплывающие подсказки к моей гистограмме, поэтому соответствующая всплывающая подсказка с соответствующими данными (год и величина ВВП) отображается для каждого бара, когда мышь наведена на него, и сразу же удаляется после.
Я пытался реализовать решение этой проблемы двумя различными способами, но ни один из них, похоже, не работал.
1) Я пытался создать переменную всплывающей подсказки и прикрепить ее к каждой панели следующим образом:
let tooltip = d3.select('barchart').append('div').attr('id', 'tooltip');
barchart.selectAll('rect').data(dataset)
.enter().append('rect')
.attr('x', (d, i) => i * barWidth)
.attr('y', d => yScale(yValue(d)))
.attr('width', barWidth)
.attr('height', d => innerHeight - yScale(yValue(d)))
.attr('fill', 'steelblue')
.attr('class', 'bar')
.attr('data-date', d => xValue(d))
.attr('data-gdp', d => yValue(d))
.on('mouseover', (d, i) => {
tooltip
.attr('x', (d, i) => i * barWidth)
.attr('y', d => yScale(yValue(d)) - 30)
.attr('text', d => `${textValue(d)} \n$${yValue(d)} Billion`)
})
.on('mouseout', d => {tooltip.style('display', 'none');});
2) А также я попытался создать отдельную функцию мыши над этим способом:
let handleMouseOver = (d, i) => {
const tooltip = barchart.append('div').attr({
'id': 'tooltip',
'x': (d, i) => i * barWidth,
'y': d => yScale(yValue(d)) - 30,
'text': d => `${textValue(d)} \n$${yValue(d)} Billion`
});
};
barchart.selectAll('rect').data(dataset)
.enter().append('rect')
.attr('x', (d, i) => i * barWidth)
.attr('y', d => yScale(yValue(d)))
.attr('width', barWidth)
.attr('height', d => innerHeight - yScale(yValue(d)))
.attr('fill', 'steelblue')
.attr('class', 'bar')
.attr('data-date', d => xValue(d))
.attr('data-gdp', d => yValue(d))
.on('mouseover', (d, i) => handleMouseOver(d, i))
Однако ни один из вариантов не работает для меня. Не могли бы вы дать мне несколько предложений?
function addQuarterStringsToArr (dataset) {
for (let i=0; i < dataset.length; i++) {
switch (dataset[i][0].substring(5,7)) {
case '01' :
case '02' :
case '03' :
dataset[i].push(dataset[i][0].substring(0,4) + ' Q1');
break;
case '04' :
case '05' :
case '06' :
dataset[i].push(dataset[i][0].substring(0,4) + ' Q2');
break;
case '07' :
case '08' :
case '09' :
dataset[i].push(dataset[i][0].substring(0,4) + ' Q3');
break;
case '10' :
case '11' :
case '12' :
dataset[i].push(dataset[i][0].substring(0,4) + ' Q4');
break;
};
};
}
const render = dataset => {
const width = 960;
const height = 500;
const xValue = d => d[0];
const yValue = d => d[1];
const textValue = d => d[2];
const margin = { top: 40, right: 60, bottom: 40, left: 60 };
const innerWidth = width - margin.left - margin.right;
const innerHeight = height - margin.top - margin.bottom;
const barWidth = innerWidth / dataset.length;
const titleXAxisPos = innerWidth / 2;
const titleYAxisPos = 10;
// Initiate a svg canvas
const svg = d3.select('body')
.append('svg')
.style('height', height)
.style('width', width)
// Initiate a barchart
const barchart = svg.append('g')
.attr('transform', `translate(${margin.left}, ${margin.top})`);
barchart.append('text')
.attr('id', 'title')
.attr('x', titleXAxisPos)
.attr('y', titleYAxisPos)
.attr('text-anchor', 'middle')
.style('font-size', '1.5em')
.style('font-weight', 'bold')
.text('United States GDP')
// Establish scale range
const xScale = d3.scaleTime()
.domain([new Date(dataset[0][0]), new Date(dataset[dataset.length - 1][0])])
.range([0, innerWidth]);
const yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, yValue)])
.range([innerHeight, 0]);
const xAxis = d3.axisBottom(xScale).tickFormat(d3.timeFormat("%Y"));
const yAxis = d3.axisLeft(yScale);
barchart.append('g')
.attr('id', 'x-axis')
.attr('transform', `translate(0, ${innerHeight})`)
.call(xAxis);
barchart.append('g')
.attr('id', 'y-axis')
.call(yAxis);
/*
const tooltip = d => {
barchart.append('title')
.attr('id', 'tooltip')
.text(d => `${textValue(d)} \n$${yValue(d)} Billion`)
}
let handleMouseOver = (d, i) => {
const tooltip = barchart.append('div').attr({
'id': 'tooltip',
'x': (d, i) => i * barWidth,
'y': d => yScale(yValue(d)) - 30,
'text': d => `${textValue(d)} \n$${yValue(d)} Billion`
});
}; */
let tooltip = d3.select('barchart').append('div').attr('id', 'tooltip');
barchart.selectAll('rect').data(dataset)
.enter().append('rect')
.attr('x', (d, i) => i * barWidth)
.attr('y', d => yScale(yValue(d)))
.attr('width', barWidth)
.attr('height', d => innerHeight - yScale(yValue(d)))
.attr('fill', 'steelblue')
.attr('class', 'bar')
.attr('data-date', d => xValue(d))
.attr('data-gdp', d => yValue(d))
//.append('title')
//.attr('id', 'tooltip')
//.text(d => `${textValue(d)} \n$${yValue(d)} Billion`);
//.on('mouseover', d => tooltip(d))
//.on('mouseover', (d, i) => handleMouseOver(d, i))
.on('mouseover', (d, i) => {
tooltip
.attr('x', (d, i) => i * barWidth)
.attr('y', d => yScale(yValue(d)) - 30)
.attr('text', d => `${textValue(d)} \n$${yValue(d)} Billion`)
})
.on('mouseout', d => {tooltip.style('display', 'none');});
};
document.addEventListener('DOMContentLoaded', function() {
const request = new XMLHttpRequest();
request.open('GET', 'https://raw.githubusercontent.com/freeCodeCamp/ProjectReferenceData/master/GDP-data.json', true);
request.send();
request.onload = function () {
const json = JSON.parse(request.responseText);
let dataset = json.data;
addQuarterStringsToArr(dataset);
render(dataset);
};
});
body {
background-color: rgb(128,128,128);
font-family: monospace;
}
svg {
background-color: white;
/* width: 60vw;
height: 80vh; */
/* padding: 5vw; */
position: absolute;
top: 50%;
left: 50%;
-moz-transform: translateX(-50%) translateY(-50%);
-webkit-transform: translateX(-50%) translateY(-50%);
transform: translateX(-50%) translateY(-50%);
}
.bar:hover {
fill: white;
}
#tooltip {
background-color: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.0.0/d3.min.js"></script>
<body></body>