D3.js-简单入门2-动态图表&交互操作

参考:

【D3.js】基础教程-CSDN博客

https://blog.csdn.net/weixin_39085822/article/details/119755130

D3 by Observable | The JavaScript library for bespoke data visualization

https://d3js.org/


目录

动态方法

  • transition()
    是指从状态A变到状态B,d3会自动计算。比如从颜色A过渡到颜色B,d3会自动插值。
  • duration()
    指定过渡的时间,单位为毫秒
  • ease()
    指定过渡的方式,比如.ease(d3.easeLinear)是普通的线性变换,.ease(d3.easeBounce)是弹跳着变换。变换方式有很多,看:https://d3js.org/d3-ease#easeLinear
  • delay()
    指定延迟时间,表示经过一定时间后才开始转换。单位是毫秒。如果要对整体做延迟就放在最后并给一个固定值;如果需要对所有图形进行不同的延迟,可以用匿名函数(function(d, i)
javascript 复制代码
var body = d3.select("body"); //选择文档中的body元素
var svg = body.select("svg"); //选择body中的svg元素
var circle1 = svg.append("circle")
                 .attr("cx", 100)
                 .attr("cy", 100)
                 .attr("r", 45)
                 .style("fill", "green");
//在1秒(1000毫秒)内将圆心坐标由100变为300
circle1.transition()
  	   .duration(1000)
	   .ease(d3.easeLinear)
  	   .attr("cx", 300) // 改属性
	   .style("fill", "red");

柱状图上文字跳动实例

效果:

javascript 复制代码
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <script>
		//画布大小
		var width = 400;
		var height = 400;
		
		//在 body 里添加一个 SVG 画布   
		var svg = d3.select("body")
			.append("svg")
			.attr("width", width)
			.attr("height", height);
		
		//画布周边的空白
		var padding = {left:30, right:30, top:20, bottom:20};
		// 定义数据
        var dataset = [10, 20, 30, 40, 33, 24, 12, 5];

		//x轴的比例尺(创建一个序列化比例尺)
		var xScale = d3.scaleBand()
					.domain(d3.range(dataset.length))
					.rangeRound([0, width - padding.left - padding.right]);
		var xAxis = d3.axisBottom(xScale); //定义x轴
		// y轴的比例尺
		var yScale = d3.scaleLinear()
					.domain([0, d3.max(dataset)])
					.range([height - padding.top - padding.bottom, 0]);
		var yAxis = d3.axisLeft(yScale); //定义y轴
		
		//矩形之间的空白
		var rectPadding = 4;

		//添加矩形元素
		var rects = svg.selectAll(".MyRect")
					.data(dataset)
					.enter()
					.append("rect")
					.attr("class", "MyRect")
					.attr(
						"transform",
						"translate(" + padding.left + "," + padding.top + ")"
					)
					.attr("x", function(d, i) {
						return xScale(i) + rectPadding / 2;
					})
					.attr("y", function(d) {
						return yScale(d);
					})
					.attr("width", xScale.step() - rectPadding)
					.attr("height", function(d) {
						return height - padding.top - padding.bottom - yScale(d);
					})
					.attr("fill","blue");

		//添加文字元素
		var texts = svg.selectAll(".MyText")
					.data(dataset)
					.enter()
					.append("text")
					.attr("class", "MyText")
					.attr(
						"transform",
						"translate(" + padding.left + "," + padding.top + ")"
					)
					.attr("x", function(d, i) {
						return xScale(i) + rectPadding / 2;
					})
					
					.attr("dx", function() {
						return (xScale.step() - rectPadding) / 2;
					})
					.attr("dy", function(d) {
						return 20;
					})
					.attr("fill","white")
					.text(function(d) {
						return d;
					})
					// 先从底端出现
					.attr("y", function(d) {
						//return yScale(d);
						var min = yScale.domain()[0];
						return yScale(min);
					})
					// 开始动
					.transition()
					.delay(function(d,i){
						return i * 200;
					})
					.duration(2000)
					.ease(d3.easeBounce)
					// 最后跳到顶端
					.attr("y",function(d){
						return yScale(d);
					});


		//添加x轴
		svg.append("g")
			.attr("class","axis")
			.attr("transform","translate(" + padding.left + "," + (height - padding.bottom) + ")")
			.call(xAxis); 

		//添加y轴
		svg.append("g")
			.attr("class","axis")
			.attr("transform","translate(" + padding.left + "," + padding.top + ")")
			.call(yAxis);


    </script>

交互式操作

有d3-brush(刷选,允许用户选择一个区域)、d3-zoom(缩放,允许用户用鼠标滚轮或手势缩放图表)、d3-drag(允许用户拖动元素,如节点、滑块等),还有一些鼠标和键盘事件可以用.on(),第一个参数是监听的事件,第二个参数是一个函数,用来处理事件。

javascript 复制代码
var circle = svg.append("circle");

circle.on("click", function(){
    //在这里添加交互内容
});

鼠标常用的事件有:click、mouseover、mouseout、mousemove、mousedown、mouseup、dblclick(双击)。

键盘常用的事件有:keydown(按住不放触发、不区分大小写;keypress区分大小写)、keyup(释放键时触发,不区分字母大小写)

下面的实例创建一个柱状图,并实现以下交互功能:

  1. 悬停高亮:当鼠标悬停在柱子上时,柱子颜色改变。
  2. 点击切换:点击柱子时,柱子高度变化。
  3. 工具提示:悬停时显示工具提示,显示柱子的值。
  4. 缩放:允许用户通过鼠标滚轮缩放整个图表。
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>D3.js 交互示例</title>
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <style>
        .bar:hover {
            fill: orange; /* 悬停时柱子的颜色 */
        }
        .tooltip {
            position: absolute;
            background: white;
            padding: 5px;
            border: 1px solid #ccc;
            border-radius: 5px;
            pointer-events: none; /* 防止工具提示干扰鼠标事件 */
        }
    </style>
</head>
<body>
    <div id="chart"></div>
    <div class="tooltip" style="opacity: 0;"></div>

    <script>
        // 数据
        const data = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100];

        // 定义画布尺寸和边距
        const width = 600;
        const height = 400;
        const margin = { top: 20, right: 20, bottom: 30, left: 40 };

        // 创建 SVG 画布
        const svg = d3.select("#chart")
            .append("svg")
            .attr("width", width)
            .attr("height", height)
            .call(d3.zoom().on("zoom", (event) => {
                svg.attr("transform", event.transform); // 缩放整个 SVG
            }))
            .append("g")
            .attr("transform", `translate(${margin.left}, ${margin.top})`);

        // 定义比例尺
        const xScale = d3.scaleBand()
            .domain(data.map((d, i) => i))
            .range([0, width - margin.left - margin.right])
            .padding(0.1);

        const yScale = d3.scaleLinear()
            .domain([0, d3.max(data)])
            .range([height - margin.top - margin.bottom, 0]);

        // 创建柱子
        svg.selectAll(".bar")
            .data(data)
            .enter()
            .append("rect")
            .attr("class", "bar")
            .attr("x", (d, i) => xScale(i))
            .attr("y", d => yScale(d))
            .attr("width", xScale.bandwidth())
            .attr("height", d => height - margin.top - margin.bottom - yScale(d))
            .attr("fill", "steelblue")
            .on("mouseover", function (event, d) {
                d3.select(this).attr("fill", "orange"); // 悬停时改变颜色
                tooltip.style("opacity", 1)
                    .html(`值: ${d}`)
                    .style("left", `${event.pageX + 5}px`)
                    .style("top", `${event.pageY - 20}px`);
            })
            .on("mouseout", function () {
                d3.select(this).attr("fill", "steelblue"); // 恢复颜色
                tooltip.style("opacity", 0);
            })
            .on("click", function (event, d) {
                const newHeight = d === 0 ? 100 : d / 2; // 点击时改变柱子高度
                d3.select(this)
                    .transition()
                    .duration(500)
                    .attr("y", yScale(newHeight))
                    .attr("height", height - margin.top - margin.bottom - yScale(newHeight));
            });

        // 创建 X 轴
        svg.append("g")
            .attr("transform", `translate(0, ${height - margin.top - margin.bottom})`)
            .call(d3.axisBottom(xScale));

        // 创建 Y 轴
        svg.append("g")
            .call(d3.axisLeft(yScale));

        // 工具提示
        const tooltip = d3.select(".tooltip");
    </script>
</body>
</html>
相关推荐
青春_strive22 分钟前
Qt:文件
开发语言·qt
wen__xvn22 分钟前
每日一题蓝桥杯P8598 [蓝桥杯 2013 省 AB] 错误票据c++
开发语言·数据结构·c++·算法
fleetstar36 分钟前
如何使用go本地编译caddy插件
开发语言·后端·golang
IT北辰43 分钟前
源码:用Python进行电影数据分析实战指南
开发语言·python
银之夏雪1 小时前
ESLint 深度解析:原理、规则与插件开发实践
java·前端·javascript
重生之成了二本看我逆天改命走向巅峰1 小时前
从0搭建Tomcat第二天:深入理解Servlet容器与反射机制
java·开发语言·笔记·学习·servlet·tomcat·idea
rkmhr_sef1 小时前
Java进阶:Dubbo
java·开发语言·dubbo
数维学长9861 小时前
【2025rust笔记】超详细,小白,rust基本语法
开发语言·笔记·rust
不止会JS1 小时前
cursor使用经验分享(java后端服务开发向)
java·开发语言·经验分享·cursor
徐白11772 小时前
Rust WebAssembly 入门教程
开发语言·rust·wasm