为 D3 React 中的每个栏设置栏颜色
Setting bar color for each bar in D3 React
我正在尝试制作一个条形图,每个条形都有不同的颜色。我已经根据答案尝试了几种方法来实现这一点,但出于某种原因,我似乎无法更改单个栏的颜色。我正在使用的代码会更改每个条形的颜色。如何设置多种颜色?
这是我试过的代码:
import React, { useEffect, useRef, useState } from 'react';
import * as d3 from 'd3';
import './BarChart.css';
const dataSet = [
{ category: 'Validation Pricing', quantity: 85 },
{ category: 'KC Validation', quantity: 15 }
];
const BarChart = () => {
const d3Chart = useRef();
const [dimensions, setDimensions] = useState({
width: window.innerWidth,
height: window.innerHeight
});
const update = useRef(false);
useEffect(() => {
// Listen for any resize event update
window.addEventListener('resize', () => {
setDimensions({
width: window.innerWidth,
height: window.innerHeight
});
// if resize, remove the previous chart
if (update.current) {
d3.selectAll('g').remove();
} else {
update.current = true;
}
});
DrawChart(dataSet, dimensions);
}, [dimensions]);
const margin = { top: 50, right: 30, bottom: 30, left: 60 };
const DrawChart = (data, dimensions) => {
console.log(dimensions);
const chartWidth = parseInt(d3.select('#d3RenewalChart').style('width')) - margin.left - margin.right;
const chartHeight = parseInt(d3.select('#d3RenewalChart').style('height')) - margin.top - margin.bottom;
const colors = ['#7fc97f', '#beaed4', '#fdc086', '#ffff99', '#386cb0', '#f0027f', '#bf5b17', '#666666'];
const svg = d3
.select(d3Chart.current)
.attr('width', chartWidth + margin.left + margin.right)
.attr('height', chartHeight + margin.top + margin.bottom);
const x = d3
.scaleBand()
.domain(d3.range(data.length))
.range([margin.left, chartWidth + margin.right])
.padding(0.1);
svg.append('g')
.attr('transform', 'translate(0,' + chartHeight + ')')
.call(
d3
.axisBottom(x)
.tickFormat((i) => data[i].category)
.tickSizeOuter(0)
);
const max = d3.max(data, function (d) {
return d.quantity;
});
const y = d3.scaleLinear().domain([0, 100]).range([chartHeight, margin.top]);
svg.append('g')
.attr('transform', 'translate(' + margin.left + ',0)')
.call(d3.axisLeft(y));
svg.append('g')
.attr('fill', function (d, i, j) {
console.log(d, j, i);
return colors[i];
})
.selectAll('rect')
.data(data)
.join('rect')
.attr('x', (d, i) => x(i))
.attr('y', (d) => y(d.quantity))
.attr('height', (d) => y(0) - y(d.quantity))
.attr('width', x.bandwidth());
};
return (
<div id="d3RenewalChart">
<svg ref={d3Chart}></svg>
</div>
);
};
export default BarChart;
首先你设置父g的填充颜色:
svg.append('g')
.attr('fill', function (d, i, j) {
console.log(d, j, i);
return colors[i];
})
你只附加一个 g
所以上面的代码运行一次。更重要的是,父元素g
的填充被子元素继承:
Transformations applied to the <g> element are performed on its
child elements, and its attributes are inherited by its children. (docs).
然后,在设置 g 的样式后,向其附加一些矩形:
[g].selectAll('rect')
.data(data)
.join('rect')
.attr('x', (d, i) => x(i))
.attr('y', (d) => y(d.quantity))
.attr('height', (d) => y(0) - y(d.quantity))
.attr('width', x.bandwidth());
但是,您没有对这些矩形应用填充:所以它们继承了父 g
填充,应该始终是 colors[0]
,这就是它们完全相同的原因。
而是在追加新的矩形后应用填充逻辑:
svg.append('g')
.selectAll('rect')
.data(data)
.join('rect')
.attr('x', (d, i) => x(i))
.attr('y', (d) => y(d.quantity))
.attr('height', (d) => y(0) - y(d.quantity))
.attr('width', x.bandwidth())
.attr('fill', function (d, i) {
return colors[i];
})
我正在尝试制作一个条形图,每个条形都有不同的颜色。我已经根据答案尝试了几种方法来实现这一点,但出于某种原因,我似乎无法更改单个栏的颜色。我正在使用的代码会更改每个条形的颜色。如何设置多种颜色?
这是我试过的代码:
import React, { useEffect, useRef, useState } from 'react';
import * as d3 from 'd3';
import './BarChart.css';
const dataSet = [
{ category: 'Validation Pricing', quantity: 85 },
{ category: 'KC Validation', quantity: 15 }
];
const BarChart = () => {
const d3Chart = useRef();
const [dimensions, setDimensions] = useState({
width: window.innerWidth,
height: window.innerHeight
});
const update = useRef(false);
useEffect(() => {
// Listen for any resize event update
window.addEventListener('resize', () => {
setDimensions({
width: window.innerWidth,
height: window.innerHeight
});
// if resize, remove the previous chart
if (update.current) {
d3.selectAll('g').remove();
} else {
update.current = true;
}
});
DrawChart(dataSet, dimensions);
}, [dimensions]);
const margin = { top: 50, right: 30, bottom: 30, left: 60 };
const DrawChart = (data, dimensions) => {
console.log(dimensions);
const chartWidth = parseInt(d3.select('#d3RenewalChart').style('width')) - margin.left - margin.right;
const chartHeight = parseInt(d3.select('#d3RenewalChart').style('height')) - margin.top - margin.bottom;
const colors = ['#7fc97f', '#beaed4', '#fdc086', '#ffff99', '#386cb0', '#f0027f', '#bf5b17', '#666666'];
const svg = d3
.select(d3Chart.current)
.attr('width', chartWidth + margin.left + margin.right)
.attr('height', chartHeight + margin.top + margin.bottom);
const x = d3
.scaleBand()
.domain(d3.range(data.length))
.range([margin.left, chartWidth + margin.right])
.padding(0.1);
svg.append('g')
.attr('transform', 'translate(0,' + chartHeight + ')')
.call(
d3
.axisBottom(x)
.tickFormat((i) => data[i].category)
.tickSizeOuter(0)
);
const max = d3.max(data, function (d) {
return d.quantity;
});
const y = d3.scaleLinear().domain([0, 100]).range([chartHeight, margin.top]);
svg.append('g')
.attr('transform', 'translate(' + margin.left + ',0)')
.call(d3.axisLeft(y));
svg.append('g')
.attr('fill', function (d, i, j) {
console.log(d, j, i);
return colors[i];
})
.selectAll('rect')
.data(data)
.join('rect')
.attr('x', (d, i) => x(i))
.attr('y', (d) => y(d.quantity))
.attr('height', (d) => y(0) - y(d.quantity))
.attr('width', x.bandwidth());
};
return (
<div id="d3RenewalChart">
<svg ref={d3Chart}></svg>
</div>
);
};
export default BarChart;
首先你设置父g的填充颜色:
svg.append('g')
.attr('fill', function (d, i, j) {
console.log(d, j, i);
return colors[i];
})
你只附加一个 g
所以上面的代码运行一次。更重要的是,父元素g
的填充被子元素继承:
Transformations applied to the <g> element are performed on its child elements, and its attributes are inherited by its children. (docs).
然后,在设置 g 的样式后,向其附加一些矩形:
[g].selectAll('rect')
.data(data)
.join('rect')
.attr('x', (d, i) => x(i))
.attr('y', (d) => y(d.quantity))
.attr('height', (d) => y(0) - y(d.quantity))
.attr('width', x.bandwidth());
但是,您没有对这些矩形应用填充:所以它们继承了父 g
填充,应该始终是 colors[0]
,这就是它们完全相同的原因。
而是在追加新的矩形后应用填充逻辑:
svg.append('g')
.selectAll('rect')
.data(data)
.join('rect')
.attr('x', (d, i) => x(i))
.attr('y', (d) => y(d.quantity))
.attr('height', (d) => y(0) - y(d.quantity))
.attr('width', x.bandwidth())
.attr('fill', function (d, i) {
return colors[i];
})