How can I add interactivity to a bar chart in d3 using join? For example in following code (full code in on codesandbox ), how can I delete a bar when I click on it?
rectG
.selectAll('rect')
.data(data)
.join(
(enter) =>
enter
.append('rect')
.attr('width', xScale.bandwidth())
.attr('height', 0)
.attr('y', (d) => innerDimensions.height)
.attr('x', (d) => xScale(d.country))
.attr('fill', 'steelblue')
.attr('stroke', 'black')
.attr('stroke-width', 2)
.call((enter) =>
enter
.transition()
.duration(1000)
.attr('y', (d) => yScale(d.population))
.attr(
'height',
(d) => innerDimensions.height - yScale(d.population)
)
),
(update) => update.attr('fill', 'orange')
);
Here is a index.js
with a click callback that deletes a bar:
import * as d3 from "d3";
let _data = [
{
id: 0,
country: "China",
population: 1400000000
},
{
id: 1,
country: "India",
population: 1200000000
},
{
id: 2,
country: "USA",
population: 450000000
},
{
id: 3,
country: "Russia",
population: 145000000
}
];
const update = data => {
const dimensions = {
width: 600,
height: 600
};
const margins = {
left: 100,
top: 20,
right: 20,
bottom: 100
};
const innerDimensions = {
width: dimensions.width - margins.left - margins.right,
height: dimensions.height - margins.top - margins.bottom
};
const xScale = d3
.scaleBand()
.domain(data.map((d) => d.country))
.range([0, innerDimensions.width])
.padding(0.1);
const yScale = d3
.scaleLinear()
.domain([0, d3.max(data, (d) => d.population)])
.range([innerDimensions.height, 0]);
const xAxis = d3.axisBottom(xScale);
const yAxis = d3
.axisLeft(yScale)
.tickFormat((n) => d3.format("0.2s")(n).replace("G", "B"));
d3.select("#canvas").selectAll('svg').remove();
const svg = d3
.select("#canvas")
.append("svg")
.attr("width", dimensions.width)
.attr("height", dimensions.height);
const rectG = svg
.append("g")
.attr("width", innerDimensions.width)
.attr("height", innerDimensions.height)
.attr("transform", `translate(${margins.left}, ${margins.top})`);
const xAxisG = rectG
.append("g")
.attr("class", "x-axis")
.attr("transform", `translate(0,${innerDimensions.height})`)
.call(xAxis);
const yAxisG = rectG.append("g").attr("class", "y-axis").call(yAxis);
rectG
.selectAll("rect")
.data(data)
.join((enter) =>
enter
.append("rect")
.on('click', (e, d) => {
const newData = data.filter(item => item.id !== d.id);
update(newData);
})
.attr("width", xScale.bandwidth())
.attr("height", 0)
.attr("y", (d) => innerDimensions.height)
.attr("x", (d) => xScale(d.country))
.attr("fill", "steelblue")
.attr("stroke", "black")
.attr("stroke-width", 2)
.call((enter) =>
enter
.transition()
.duration(1000)
.attr("y", (d) => yScale(d.population))
.attr("height", (d) => innerDimensions.height - yScale(d.population))
)
);
}
update(_data);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.