我正在使用d3库绘制折线图。
以下是我生成折线图的代码。
<html>
<head>
<title>Simple Line Graph using SVG and d3.js</title>
<script src="http://mbostock.github.com/d3/d3.v2.js"></script>
<style>
/* tell the SVG path to be a thin blue line without any area fill */
path {
stroke: steelblue;
stroke-width: 1;
fill: none;
}
.axis {
shape-rendering: crispEdges;
}
.x.axis line {
stroke: lightgrey;
}
.x.axis .minor {
stroke-opacity: .5;
}
.x.axis path {
display: none;
}
.y.axis line, .y.axis path {
fill: none;
stroke: #000;
}
</style>
</head>
<body>
<div id="graph" class="aGraph" style="position:absolute;top:0px;left:0; float:left;"></div>
<script>
/* implementation heavily influenced by http://bl.ocks.org/1166403 */
// define dimensions of graph
var m = [80, 80, 80, 80]; // margins
var w = 1000 - m[1] - m[3]; // width
var h = 400 - m[0] - m[2]; // height
// create a simple data array that we'll plot with a line (this array represents only the Y values, X will just be the index location)
var data = [3, 6, 2, 7, 5, 2, 0, 3, 8, 9, 2, 5, 9, 3, 6, 3, 6, 2, 7, 5, 2, 1, 3, 8, 9, 2, 5, 9, 2, 7];
// X scale will fit all values from data[] within pixels 0-w
var x = d3.scale.linear().domain([0, data.length]).range([0, w]);
// Y scale will fit values from 0-10 within pixels h-0 (Note the inverted domain for the y-scale: bigger is up!)
var y = d3.scale.linear().domain([0, 10]).range([h, 0]);
// automatically determining max range can work something like this
// var y = d3.scale.linear().domain([0, d3.max(data)]).range([h, 0]);
// create a line function that can convert data[] into x and y points
var line = d3.svg.line()
// assign the X function to plot our line as we wish
.x(function(d, i) {
// verbose logging to show what's actually being done
console.log('Plotting X value for data point: ' + d + ' using index: ' + i + ' to be at: ' + x(i) + ' using our xScale.');
// return the X coordinate where we want to plot this datapoint
return x(i);
})
.y(function(d) {
// verbose logging to show what's actually being done
console.log('Plotting Y value for data point: ' + d + ' to be at: ' + y(d) + " using our yScale.");
// return the Y coordinate where we want to plot this datapoint
return y(d);
})
// Add an SVG element with the desired dimensions and margin.
var graph = d3.select("#graph").append("svg:svg")
.attr("width", w + m[1] + m[3])
.attr("height", h + m[0] + m[2])
.append("svg:g")
.attr("transform", "translate(" + m[3] + "," + m[0] + ")");
// create yAxis
var xAxis = d3.svg.axis().scale(x).tickSize(-h).tickSubdivide(true);
// Add the x-axis.
graph.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + h + ")")
.call(xAxis);
// create left yAxis
var yAxisLeft = d3.svg.axis().scale(y).ticks(4).orient("left");
// Add the y-axis to the left
graph.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(-25,0)")
.call(yAxisLeft);
// Add the line by appending an svg:path element with the data line we created above
// do this AFTER the axes above so that the line is above the tick-lines
graph.append("svg:path").attr("d", line(data));
var line1 = graph.append('line')
.attr('transform', 'translate(100, 50)')
.attr({'x1': 0, 'y1': 0, 'x2': 0, 'y2': 1400})
.attr('class', 'selection_line');
graph.on('mousemove', function(e) {
var navigatorVersion = navigator.appVersion;
var navigatorAgent = navigator.userAgent;
var browserName = navigator.appName;
var fullVersionName = '' + parseFloat(navigator.appVersion);
var majorVersionName = parseInt(navigator.appVersion, 10);
var nameOffset, verOffset, ix;
// In Firefox, the true version is after "Firefox"
//To make line scroll horizontally in mozilla firefox use following code
if ((verOffset = navigatorAgent.indexOf("Firefox")) != -1) {
browserName = "Firefox";
fullVersionName = navigatorAgent.substring(verOffset + 8);
}
if (browserName == "Firefox") {
line1.attr("x1", d3.event.clientX - 100);
line1.attr("x2", d3.event.clientX - 100);
}
else {
line1.attr("x1", d3.event.x - 100);
line1.attr("x2", d3.event.x - 100);
}
});
</script>
</body>
</html>
鼠标移动我想用鼠标移动一条垂直线,想要找到垂直线与线图的交点。即找到折线图的x和y坐标,其中垂直线与图形相交。
知道为什么它不起作用?
答案 0 :(得分:6)
此处是图表的工作版本,其中包含大量更改 - http://jsfiddle.net/cuckovic/vKe67/
以下是执行“繁重工作”的代码:
rect.on('mousemove', function () {
var xPos = d3.mouse(this)[0];
d3.select(".verticalLine").attr("transform", function () {
return "translate(" + xPos + ",0)";
});
var pathLength = mainLine.node().getTotalLength();
var x = xPos;
var beginning = x,
end = pathLength,
target;
while (true) {
target = Math.floor((beginning + end) / 2);
pos = mainLine.node().getPointAtLength(target);
if ((target === end || target === beginning) && pos.x !== x) {
break;
}
if (pos.x > x) end = target;
else if (pos.x < x) beginning = target;
else break; //position found
}
circle.attr("opacity", 1)
.attr("cx", x)
.attr("cy", pos.y);
console.log("x and y coordinate where vertical line intersects graph: " + [pos.x, pos.y]);
console.log("data where vertical line intersects graph: " + [xScale.invert(pos.x), yScale.invert(pos.y)]);
});
此致 伊戈尔