前面写了一篇 【d3.js入门】 基本散点图,这次我们在这个面积图基础上添加一些动画效果。
好,废话多说,我们继续绘制换一个散点图。
首先,我们创建一个 div
元素,并将其添加到 body
里:
let dom = document.createElement('div');
document.body.appendChild(dom);
接下来,生成一些随机的数据,并设置画布和轴的配置信息:
let dataset = [];
for (let i = 0; i < 30; i++) {
let x = Math.random();
let y = Math.floor(Math.random() * 90 + 10);
dataset.push([x, y]);
}
let padding = 30;
let svgWidth = 600;
let svgHeight = 400;
let xScale = d3.scaleLinear()
.domain([0, 1])
.range([padding, svgWidth - padding]);
let yScale = d3.scaleLinear()
.domain([0, 100])
.range([svgHeight - padding, padding]);
然后,创建 svg
元素,并设置它的宽度、高度和边框样式:
let svg = d3.select(dom)
.append("svg")
.attr("width", svgWidth)
.attr("height", svgHeight)
.style('border', '1px solid #999999');
接下来,为每个数据点绘制圆点,设置其属性包括半径大小、填充颜色以及位置等,并使用 selectAll()
、data()
和 enter()
方法将数据绑定到元素上:
let dots = svg.selectAll(".dot")
.data(dataset)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 5)
.attr("fill", "#69b3a2")
.attr("cx", function (d) { return xScale(d[0]); })
.attr("cy", function (d) { return yScale(d[1]); });
最后,创建坐标轴并添加到 svg
元素上:
let xAxis = d3.axisBottom(xScale);
let yAxis = d3.axisLeft(yScale);
svg.append("g")
.attr("class", "x-axis")
.attr("transform", "translate(0," + (svgHeight - padding) + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y-axis")
.attr("transform", "translate(" + padding + ",0)")
.call(yAxis);
添加了交互功能,包括更新数据、添加数据和删除数据。具体步骤如下:
首先,创建一组按钮,并将它们添加到画布的下方。为每个按钮设置一个 onclick
事件监听器:
let innerHtml = ['更新数据', '添加数据', '删除数据'];
let buts = [];
let butdiv = document.createElement('div');
dom.appendChild(butdiv);
innerHtml.map(item => {
let but = document.createElement('button');
but.innerHTML = item;
butdiv.appendChild(but);
buts.push(but);
})
// 更新数据
buts[0].onclick = function () {
dataset.forEach(item => {
item[0] = Math.random();
item[1] = Math.floor(Math.random() * 90 + 10);
})
dots = svg.selectAll(".dot")
.data(dataset)
.transition()
.duration(1000)
.attr("cx", function (d) { return xScale(d[0]); })
.attr("cy", function (d) { return yScale(d[1]); });
}
// 添加数据
buts[1].onclick = function () {
let x = Math.random();
let y = Math.floor(Math.random() * 90 + 10);
dataset.push([x, y]);
dots = svg.selectAll(".dot")
.data(dataset)
.enter().append("circle")
.attr("class", "dot")
.attr("r", 20)
.attr("opacity", 0)
.attr("fill", "#69b3a2")
.attr("cx", function (d) { return xScale(d[0]); })
.attr("cy", function (d) { return yScale(d[1]); })
.transition()
.duration(1000)
.attr("r", 5)
.attr("opacity", 1)
}
// 删除数据
buts[2].onclick = function () {
dataset.pop();
dots = svg.selectAll(".dot")
.data(dataset)
.exit()
.transition()
.duration(1000)
.attr("r", 20)
.attr("opacity", 0)
.remove()
}
更新数据的功能将数组中的每个元素都重新赋予新的随机值,然后使用 selectAll()
、data()
和 transition()
方法来更新圆点的位置。
添加数据的功能会向数组中添加一个新元素,并通过 selectAll()
、data()
、enter()
和 append()
方法来将新的圆点添加到可视化中。在此之前,先将圆点半径设置为 20 并且不透明度为零,然后在过渡期间,将其半径缩小至 5 并且逐渐变得不透明。
删除数据的功能会从数组末尾删除一个元素,并使用 selectAll()
、data()
、exit()
和 transition()
方法来移除可视化中对应的圆点。在此之前,将这些圆点的半径设置为 20 并且不透明度为零,然后在过渡期间,将其半径放大至 20 并且逐渐变得不可见,最终移除它们。
在线演示和源码地址:scqilin.github.io/d3js/basic-…