跳到主要内容

完整示例:创建一个柱状图

现在我们已经学习了 D3.js 的基础知识,让我们将它们结合在一起,创建一个完整的交互式柱状图。

数据准备

假设我们有一组关于不同产品销售额的数据:

const data = [
{name: "苹果", value: 10},
{name: "香蕉", value: 20},
{name: "橙子", value: 30},
{name: "葡萄", value: 40},
{name: "西瓜", value: 50}
];

设置画布

我们将创建一个画布,并定义页边距 (Margins),以便为比例尺和坐标轴留出空间。

const margin = {top: 20, right: 30, bottom: 40, left: 40};
const width = 800 - margin.left - margin.right;
const height = 400 - margin.top - margin.bottom;

const svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);

定义比例尺

比例尺用于将数据映射到 SVG 的坐标系中。

const xScale = d3.scaleBand()
.domain(data.map(d => d.name))
.range([0, width])
.padding(0.1);

const yScale = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)])
.nice()
.range([height, 0]); // 反向映射,因为 SVG y 坐标从上向下增加

绘制坐标轴

svg.append("g")
.attr("transform", `translate(0, ${height})`)
.call(d3.axisBottom(xScale));

svg.append("g")
.call(d3.axisLeft(yScale));

绘制矩形(条形)

我们将使用 join() 生命周期方法,并添加一个简单的过渡效果。

svg.selectAll(".bar")
.data(data)
.join("rect") // 数据绑定
.attr("class", "bar")
.attr("x", d => xScale(d.name))
.attr("y", height) // 初始位置在底部
.attr("width", xScale.bandwidth())
.attr("height", 0) // 初始高度为 0
.style("fill", "steelblue")
.transition() // 添加过渡
.duration(800)
.attr("y", d => yScale(d.value)) // 最终 y 坐标
.attr("height", d => height - yScale(d.value)); // 最终高度

添加交互

当用户鼠标悬停时,条形颜色发生变化:

svg.selectAll(".bar")
.on("mouseover", function(event, d) {
d3.select(this)
.style("fill", "orange");
})
.on("mouseout", function(event, d) {
d3.select(this)
.style("fill", "steelblue");
});

恭喜!通过将之前学到的所有概念组合在一起,您已经成功创建了一个可以交互的可视化图表。D3.js 的强大功能远不止这些,您可以继续探索复杂的数据变换和高度定制化的动画。