我是D3的新手,我正在尝试创建BarChart组件。 在 exit()和 remove()函数下面的代码中,它们不起作用,并且每次绘制新图表而不是用新值更新条形图。
我尝试使用这条线 selectAll('svg> g')。remove(); ,但它会重绘整个图表 数据更新的时间。
我还尝试在 useEffect 之外创建SVG,但是它不起作用。
import React, { useEffect, useRef } from 'react';
import {
select,
selectAll,
max,
scaleLinear,
scaleBand
} from 'd3';
import { BarChartContainer } from './BarChart.style';
const DEFAULT_MARGIN = { top: 25, right: 20, bottom: 20, left: 55 };
const BAR_PADDING_RATIO = 0.25;
const ALL_BARS_CLASS = 'bars';
const BarChart = ({ dataset, onBarClick, size }) => {
const svgRef = useRef(null);
const margin = DEFAULT_MARGIN;
const width = size.width - margin.left - margin.right;
const height = size.height - margin.top - margin.bottom;
const getXScale = () =>
scaleLinear()
.domain([0, max(dataset, d => d.value)])
.range([0, width]);
const getYScale = () =>
scaleBand()
.domain(dataset.map(d => d.label))
.range([0, height])
.padding(BAR_PADDING_RATIO);
const drawBars = (svg, xScale, yScale) => {
// HORIZONTAL BARS
const bars = svg.append('g').attr('class', ALL_BARS_CLASS);
const rects = bars.selectAll('rect').data(dataset);
rects
.exit()
.transition()
.duration(700)
.attr('width', 0)
.attr('x', 0)
.remove();
// UPDATE
rects
.transition()
.duration(700)
.attr('x', 0)
.attr('y', d => yScale(d.label))
.attr('width', d => xScale(d.value))
.attr('height', yScale.bandwidth())
.attr('fill', 'blue');
rects
.enter()
.append('rect')
.attr('class','bar')
.attr('x', 1)
.attr('y', d => yScale(d.label))
.attr('height', yScale.bandwidth())
.transition()
.duration(700)
.attr('width', d => xScale(d.value))
.attr('fill', 'green')
};
useEffect(
() => {
// remove all nested groups and redraw the chart when data changes
// selectAll('svg > g').remove();
// include the SVG and nested g element in which to plot the visualization
const svg = select(svgRef.current)
.attr('viewBox', `0 0 ${size.width + margin.left} ${size.height + margin.top}`)
.append('g')
.attr('transform', 'translate(85, 15)');
// SCALES
const xScale = getXScale();
const yScale = getYScale();
// BARS
drawBars(svg, xScale, yScale);
},
[JSON.stringify(dataset)]
);
return (
<BarChartContainer>
<svg ref={svgRef} />
</BarChartContainer>
);
};
export default BarChart;