为了账号安全,请及时绑定邮箱和手机立即绑定

怎么用d3画跟随鼠标的十字线(当前点的横纵坐标),并且显示当前点的值

我现在已经画出了带坐标的曲线图,数据是后台加载来的 现在想要实现一个功能就是鼠标画上的时候可以有一条跟随鼠标的十字线,分别从x和y轴拉过来,并且显示当前的xy坐标,并在一个方框内显示当前点的其他描述内容。类似这样的。http://img1.sycdn.imooc.com//5788494200010cbd05050228.jpg

正在回答

1 回答

效果图:

http://img1.sycdn.imooc.com//57fb41400001cf7e07610358.jpg

代码:

D3.html

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<title>D3</title>
	<link rel="stylesheet" href="css/D3.css">
</head>
<body>
	<div id="container">	
	<div id="dialog"></div>	
	</div>
	<script src="http://d3js.org/d3.v3.js"></script>
	<script src="js/D3_line_point.js"></script>

</body>
</html>

D3.css

body {
	font: 10px sans-serif;
}
path {
	fill: none;
	stroke: #4682B4;
	stroke-width: 2;
}
.domain, .tick line {
	stroke: gray;
	stroke-width: 1;
}
.circle {
	fill: white;
	stroke: steelblue;
	stroke-width: 2px;
}
.area {
	fill: steelblue;
	stroke: none;
	opacity: 0.1;
}
.zeroline {
	fill: none;
	stroke: red;
	stroke-width: 0.5px;
	stroke-dasharray: 5 5;
}
.zerolinetext {
	fill: red;
}
.overlay {
	fill: none;
	stroke: none;
	pointer-events: all;
}
.focusLine {
	fill: none;
	stroke: steelblue;
	stroke-width: 0.5px;
}
.focusCircle {
	fill: red;
}
#dialog{
	width: 160px;
	height: 60px;
	background-color: #4682B4;
	position: fixed;
	top:50px;
	left:600px;
	opacity: 0;
	line-height: 20px;
}


D3_line_point.js

var data = [];
var currentValue = 100;
var random = d3.random.normal(0, 20.0);

for (var i = 0; i < 100; i++) {
	var currentDate = new Date();
	currentDate.setDate(currentDate.getDate() + i);

	data.push([currentDate, currentValue]);
	currentValue = currentValue + random();
}


var drawLineGraph = function(containerHeight, containerWidth, data, yLabel, warnLine) {

	var svg = d3.select("body").append("svg")
		.attr("width", containerWidth)
		.attr("height", containerHeight);

	var margin = {
		top: 50,
		left: 50,
		right: 50,
		bottom: 50
	};

	var height = containerHeight - margin.top - margin.bottom;
	var width = containerWidth - margin.left - margin.right;

	var xDomain = d3.extent(data, function(d) {
		return d[0];
	})
	var yDomain = d3.extent(data, function(d) {
		return d[1];
	});

	var xScale = d3.time.scale().range([0, width]).domain(xDomain);
	var yScale = d3.scale.linear().range([height, 0]).domain(yDomain);

	var xAxis = d3.svg.axis().scale(xScale).orient('bottom');
	var yAxis = d3.svg.axis().scale(yScale).orient('left');

	var line = d3.svg.line()
		.x(function(d) {
			return xScale(d[0]);
		})
		.y(function(d) {
			return yScale(d[1]);
		});

	var area = d3.svg.area()
		.x(function(d) {
			return xScale(d[0]);
		})
		.y0(function(d) {
			return yScale(d[1]);
		})
		.y1(height);

	var g = svg.append('g').attr('transform', 'translate(' + margin.left + ', ' + margin.top + ')');

	g.append('path')
		.datum(data)
		.attr('class', 'area')
		.attr('d', area);

	g.append('g')
		.attr('class', 'x axis')
		.attr('transform', 'translate(0, ' + height + ')')
		.call(xAxis);

	g.append('g')
		.attr('class', 'y axis')
		.call(yAxis)
		.append('text')
		.attr('transform', 'rotate(-90)')
		.attr('y', 6)
		.attr('dy', '.71em')
		.attr('text-anchor', 'end')
		.text(yLabel);

	g.append('path')
		.datum(data)
		.attr('class', 'line')
		.attr('d', line);

	g.selectAll('circle').data(data).enter().append('circle')
		.attr('cx', function(d) {
			return xScale(d[0]);
		})
		.attr('cy', function(d) {
			return yScale(d[1]);
		})
		.attr('r', 3)
		.attr('class', 'circle');

	// focus tracking

	var focus = g.append('g').style('display', 'none');

	focus.append('line')
		.attr('id', 'focusLineX')
		.attr('class', 'focusLine');
	focus.append('line')
		.attr('id', 'focusLineY')
		.attr('class', 'focusLine');
	focus.append('circle')
		.attr('id', 'focusCircle')
		.attr('r', 5)
		.attr('class', 'circle focusCircle');

	var bisectDate = d3.bisector(function(d) {
		return d[0];
	}).left;

	g.append('rect')
		.attr('class', 'overlay')
		.attr('width', width)
		.attr('height', height)
		.on('mouseover', function() {
			focus.style('display', null);
			d3.select('#dialog')
			.style('opacity',0);
		})
		.on('mouseout', function() {
			focus.style('display', 'none');
			d3.select('#dialog')
			.style('opacity',0);
		})
		.on('mousemove', function() {
			var mouse = d3.mouse(this);
			var mouseDate = xScale.invert(mouse[0]);
			var i = bisectDate(data, mouseDate); // returns the index to the current data item

			var d0 = data[i - 1]
			var d1 = data[i];
			// work out which date value is closest to the mouse
			var d = mouseDate - d0[0] > d1[0] - mouseDate ? d1 : d0;

			var x = xScale(d[0]);
			var y = yScale(d[1]);

			focus.select('#focusCircle')
				.attr('cx', x)
				.attr('cy', y);
			focus.select('#focusLineX')
				.attr('x1', x).attr('y1', yScale(yDomain[0]))
				.attr('x2', x).attr('y2', yScale(yDomain[1]));
			focus.select('#focusLineY')
				.attr('x1', xScale(xDomain[0])).attr('y1', y)
				.attr('x2', xScale(xDomain[1])).attr('y2', y);

			d3.select('#dialog')
				//.attr('transform', 'translate(' + x + ',' + y + ')')
				//.attr('text-anchor', 'middle')
				.style('opacity','0.7')
				.text(d[0]+' '+d[1]);

		});

	// warn line

	if (warnLine && yDomain[0] < warnLine.lineValue && yDomain[1] > warnLine.lineValue) {
		g.append('line')
			.attr('x1', xScale(xDomain[0]))
			.attr('y1', yScale(warnLine.lineValue))
			.attr('x2', xScale(xDomain[1]))
			.attr('y2', yScale(warnLine.lineValue))
			.attr('class', 'zeroline');
		g.append('text')
			.attr('x', xScale(xDomain[1]))
			.attr('y', yScale(warnLine.lineValue))
			.attr('dy', '1em')
			.attr('text-anchor', 'end')
			.text(warnLine.label)
			.attr('class', 'zerolinetext');
	}
};

drawLineGraph(400, 800, data, "Intensity", {
	lineValue: 200,
	label: "OMG!"
});


0 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消

怎么用d3画跟随鼠标的十字线(当前点的横纵坐标),并且显示当前点的值

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信