• d3 mouseover Tips


    本篇简单介绍d3 mouseover添加tips的实现

    绘制曲线

    • 以前几篇的d3曲线为例
    
    <!DOCTYPE html>
    <html>
    
    	<head>
    		<meta charset="UTF-8">
    		<title></title>
    	</head>
    
    	<body>
    		<div id="test-svg">
    		</div>
    	</body>
    	<script src="https://d3js.org/d3.v5.js"></script>
    	<script>
    		window.onload = function() {
    
    			// 数据
    			var data = [{
    				date: new Date(2019, 3, 24),
    				value: 23.24
    			}, {
    				date: new Date(2019, 3, 25),
    				value: 72.15
    			}, {
    				date: new Date(2019, 3, 26),
    				value: 38.84
    			}, {
    				date: new Date(2019, 3, 27),
    				value: 58.62
    			}, {
    				date: new Date(2019, 3, 30),
    				value: 10.80
    			}, {
    				date: new Date(2019, 4, 1),
    				value: 85.47
    			}];
    
    			var width = 800,
    				height = 400,
    				padding = {
    					top: 40,
    					right: 40,
    					bottom: 40,
    					left: 40
    				};
    
    			var colors = d3.schemeSet2;
    			var svg = d3.select("#test-svg")
    				.append('svg')
    				.attr('width', width + 'px')
    				.attr('height', height + 'px');
    
    			// x轴:时间轴
    			var xScale = d3.scaleTime()
    				.domain(d3.extent(data, function(d) {
    					return d.date;
    				}))
    				.range([padding.left, width - padding.right]);
    
    			var xAxis = d3.axisBottom()
    				.scale(xScale)
    				.tickSize(10);
    
    			var bisect = d3.bisector(function(d) {
    				return d.date;
    			}).left;
    
    			svg.append('g')
    				.call(xAxis)
    				.attr("transform", "translate(0," + (height - padding.bottom) + ")")
    				.selectAll("text")
    				.attr("font-size", "10px")
    				.attr("dx", "50px");
    
    			var ymax = d3.max(data, function(d) {
    				return d.value;
    			});
    
    			// y轴
    			var yScale = d3.scaleLinear()
    				.domain([0, ymax])
    				.range([height - padding.bottom, padding.top]);
    
    			var yAxis = d3.axisLeft()
    				.scale(yScale)
    				.ticks(10);
    
    			svg.append('g')
    				.call(yAxis)
    				.attr("transform", "translate(" + padding.left + ",0)");
    
    			var curveLine = d3.line()
    				.x(function(d) {
    					return xScale(d.date);
    				})
    				.y(function(d) {
    					return yScale(d.value);
    				})
    				.curve(d3.curveCatmullRom.alpha(0.5));
    
    			svg.append("path")
    				.datum(data)
    				.attr("fill", "none")
    				.attr("stroke", "steelblue")
    				.attr("stroke-width", 1.5)
    				.attr("stroke-linejoin", "round")
    				.attr("stroke-linecap", "round")
    				.attr("d", curveLine);
    
    		}
    	</script>
    
    </html>
    
    

    添加坐标点标识

    
    svg.append("g")
    				.selectAll('circle')
    				.data(data)
    				.join("circle")
    				.attr("r", 5)
    				.attr("fill", "white")
    				.attr("stroke", "steelblue")
    				.attr("stroke-width", 1.5)
    				.attr("transform", function(item) {
    					return "translate(" + xScale(item.date) + "," + yScale(item.value) + ")";
    				})
    
    

    添加tips

    • 添加tips,一个圆点及数据文本
    
    var tips = svg.append("g")
    				.attr("class", "tips")
    				.style("display", "none");
    
    			tips.append("circle")
    				.attr("r", 3);
    
    			tips.append("text")
    				.attr("x", 8)
    				.attr("dy", ".35em");
    
    

    添加事件

    • 添加一个和svg同等大小的透明rect面板用来触发事件

    • 获取坐标

    
    // d3.mouse(this)[0] 获取当前鼠标位置的x坐标
    // xScale.invert() 转为曲线上的x坐标
    xScale.invert(d3.mouse(this)[0])
    
    // d3.bisector() 获取当前曲线上x坐标对应数据中的点序号
    var bisect = d3.bisector(function(d) {
    				return d.date;
    			}).left;
    
    bisect(data, xdata, 1, data.length - 1);
    
    
    
    svg.append("rect")
    				.attr("class", "overPlane")
    				.attr("width", width)
    				.attr("height", height)
    				.attr("opacity", 0)
    				.on("mouseover", function() {
    					tips.style("display", null);
    				})
    				.on("mouseout", function() {
    					tips.style("display", "none");
    				})
    				.on("mousemove", function() {
    					var xdata = xScale.invert(d3.mouse(this)[0]);
    					var yIndex = bisect(data, xdata, 1, data.length - 1);
    					var d0 = data[yIndex - 1],
    						d1 = data[yIndex],
    						d = xdata - d0.date > d1.date - xdata ? d1 : d0;
    					tips.attr("transform", "translate(" + xScale(d.date) + "," + yScale(d.value) + ")");
    					tips.select("text").text(d.value);
    				});
    
    

    线性的数值展示

    
    .on("mousemove", function() {
    
    					var mouse = d3.mouse(this);
    					var begin = 0,
    						end = line[0].getTotalLength(),
    						target = null;
                        
                        // 已知当前鼠标x轴坐标,求出对应的path上的坐标点
    					while(true) {
    						target = Math.floor((begin + end) / 2);
                                                    // getPointAtLength 返回给定路径上给定长度的点坐标 
    						pos = line[0].getPointAtLength(target);
    						if((target === end || target === begin) && pos.x !== mouse[0]) {
    							break;
    						}
                                                    // 当返回的路径的x坐标和鼠标对应的x坐标重合 break;
    						if(pos.x > mouse[0]) end = target;
    						else if(pos.x < mouse[0]) begin = target;
    						else break;
    					}
    
    					tips.select("text").text(yScale.invert(pos.y).toFixed(2));
    					tips.attr("transform", "translate(" + mouse[0] + "," + pos.y + ")");
    
    				});
    
    

  • 相关阅读:
    Centos 7 KVM安装win10
    python3.6小程序
    linux随手笔记(Centos为主)
    python 3.6练习题(仿购物车)
    linux mint软件安装
    pacman详解及常见问题
    manjaro安装及设置
    Ansible安装及配置
    大盘分时黄白线
    渊海子平学习
  • 原文地址:https://www.cnblogs.com/chenjy1225/p/11368632.html
Copyright © 2020-2023  润新知