D3.js 是一个非常强大的 JavaScript 库,用于处理数据和创建复杂的可视化。堆叠条形图是一种常见的可视化类型,用于显示不同类别的数据随时间或其他变量的变化。下面是一个使用 D3.js 创建堆叠条形图的基本步骤:
首先,你需要准备要可视化的数据。堆叠条形图通常需要一个二维数组,其中每个子数组代表一个类别,子数组中的元素代表该类别在不同时间点或条件下的值。
const data = [
{category: 'A', values: [10, 20, 30]},
{category: 'B', values: [15, 25, 35]},
{category: 'C', values: [5, 15, 25]}
];
在 HTML 中创建一个 SVG 元素,用于绘制堆叠条形图。
<svg width="600" height="400"></svg>
使用 D3.js 的比例尺(scales)和轴(axes)来映射数据和视图。
const margin = {top: 20, right: 30, bottom: 40, left: 40};
const width = +svg.attr('width') - margin.left - margin.right;
const height = +svg.attr('height') - margin.top - margin.bottom;
const x = d3.scaleBand()
.rangeRound([0, width])
.padding(0.1);
const y = d3.scaleLinear()
.rangeRound([height, 0]);
const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
使用 D3.js 的堆叠布局(stack layout)来处理数据。
const stack = d3.stack()
.keys(data.map(d => d.category))
.order(d3.stackOrderNone)
.offset(d3.stackOffsetNone);
const series = stack(data.map(d => d.values));
遍历堆叠后的数据,为每个类别绘制条形。
const barWidth = x.bandwidth() / data.length;
g.selectAll('.series')
.data(series)
.enter().append('g')
.attr('fill', 'steelblue')
.selectAll('rect')
.data(d => d)
.enter().append('rect')
.attr('x', (d, i) => x(i) + i * barWidth)
.attr('y', d => y(d[1]))
.attr('height', d => y(d[0]) - y(d[1]))
.attr('width', barWidth);
最后,添加 x 轴和 y 轴标签。
g.append('g')
.attr('class', 'x axis')
.attr('transform', `translate(0,${height})`)
.call(d3.axisBottom(x));
g.append('g')
.attr('class', 'y axis')
.call(d3.axisLeft(y).ticks(10, '%'));
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Stacked Bar Chart with D3.js</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
</head>
<body>
<svg width="600" height="400"></svg>
<script>
const svg = d3.select('svg');
const margin = {top: 20, right: 30, bottom: 40, left: 40};
const width = +svg.attr('width') - margin.left - margin.right;
const height = +svg.attr('height') - margin.top - margin.bottom;
const x = d3.scaleBand()
.rangeRound([0, width])
.padding(0.1);
const y = d3.scaleLinear()
.rangeRound([height, 0]);
const g = svg.append('g')
.attr('transform', `translate(${margin.left},${margin.top})`);
const data = [
{category: 'A', values: [10, 20, 30]},
{category: 'B', values: [15, 25, 35]},
{category: 'C', values: [5, 15, 25]}
];
const stack = d3.stack()
.keys(data.map(d => d.category))
.order(d3.stackOrderNone)
.offset(d3.stackOffsetNone);
const series = stack(data.map(d => d.values));
const barWidth = x.bandwidth() / data.length;
g.selectAll('.series')
.data(series)
.enter().append('g')
.attr('fill', 'steelblue')
.selectAll('rect')
.data(d => d)
.enter().append('rect')
.attr('x', (d, i) => x(i) + i * barWidth)
.attr('y', d => y(d[1]))
.attr('height', d => y(d[0]) - y(d[1]))
.attr('width', barWidth);
g.append('g')
.attr('class', 'x axis')
.attr('transform', `translate(0,${height})`)
.call(d3.axisBottom(x));
g.append('g')
.attr('class', 'y axis')
.call(d3.axisLeft(y).ticks(10, '%'));
</script>
</body>
</html>
这个示例展示了如何使用 D3.js 创建一个简单的堆叠条形图。你可以根据需要调整数据和样式。
领取专属 10元无门槛券
手把手带您无忧上云