D3 柱状图开发教程:一步一步实现数据可视化
以下是使用 d3 开发柱状图的基本步骤:
- 引入 d3 库和数据
首先需要在 HTML 文件中引入 d3 库,并且准备好要展示的数据。
<script src='https://d3js.org/d3.v6.min.js'></script>
<script>
const data = [
{ name: 'A', value: 20 },
{ name: 'B', value: 35 },
{ name: 'C', value: 10 },
{ name: 'D', value: 25 },
{ name: 'E', value: 15 }
];
</script>
- 创建 SVG 容器
使用 d3 创建一个 SVG 容器,用于承载柱状图。
const width = 600;
const height = 400;
const svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height);
- 创建比例尺和坐标轴
在 d3 中,可以使用比例尺将数据映射到坐标轴上。在柱状图中,通常使用线性比例尺。
const xScale = d3.scaleBand()
.domain(data.map(d => d.name))
.range([0, width])
.padding(0.2);
const yScale = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)])
.range([height, 0]);
const xAxis = d3.axisBottom(xScale);
const yAxis = d3.axisLeft(yScale);
使用创建好的比例尺和坐标轴,绘制 x 轴和 y 轴。
svg.append('g')
.attr('transform', `translate(0, ${height})`) .call(xAxis);
svg.append('g')
.call(yAxis);
- 绘制柱状图
使用数据和比例尺,绘制柱状图。在 d3 中,可以使用rect 元素绘制矩形,即柱状图。
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('x', d => xScale(d.name))
.attr('y', d => yScale(d.value))
.attr('width', xScale.bandwidth())
.attr('height', d => height - yScale(d.value))
.attr('fill', 'steelblue');
- 添加标签
为了让柱状图更加清晰,可以添加标签,标明每个柱子所代表的数据。
svg.selectAll('text')
.data(data)
.enter()
.append('text')
.text(d => d.value)
.attr('x', d => xScale(d.name) + xScale.bandwidth() / 2)
.attr('y', d => yScale(d.value) - 5)
.attr('text-anchor', 'middle')
.attr('font-size', '12px')
.attr('fill', 'white');
至此,一个简单的柱状图就完成了。
完整代码:
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>D3 Bar Chart</title>
<script src='https://d3js.org/d3.v6.min.js'></script>
</head>
<body>
<script>
const data = [
{ name: 'A', value: 20 },
{ name: 'B', value: 35 },
{ name: 'C', value: 10 },
{ name: 'D', value: 25 },
{ name: 'E', value: 15 }
];
const width = 600;
const height = 400;
const svg = d3.select('body')
.append('svg')
.attr('width', width)
.attr('height', height);
const xScale = d3.scaleBand()
.domain(data.map(d => d.name))
.range([0, width])
.padding(0.2);
const yScale = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)])
.range([height, 0]);
const xAxis = d3.axisBottom(xScale);
const yAxis = d3.axisLeft(yScale);
svg.append('g')
.attr('transform', `translate(0, ${height})`) .call(xAxis);
svg.append('g')
.call(yAxis);
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('x', d => xScale(d.name))
.attr('y', d => yScale(d.value))
.attr('width', xScale.bandwidth())
.attr('height', d => height - yScale(d.value))
.attr('fill', 'steelblue');
svg.selectAll('text')
.data(data)
.enter()
.append('text')
.text(d => d.value)
.attr('x', d => xScale(d.name) + xScale.bandwidth() / 2)
.attr('y', d => yScale(d.value) - 5)
.attr('text-anchor', 'middle')
.attr('font-size', '12px')
.attr('fill', 'white');
</script>
</body>
</html>
原文地址: https://www.cveoy.top/t/topic/mi8e 著作权归作者所有。请勿转载和采集!