D3在一页上的每个图表的鼠标hover效果

我在一个页面上有多个d3图表,并希望为每个图表添加一个鼠标hover效果。 此刻只有一个图表受到影响,并具有鼠标hover效果。

我用多个图表创build了一个例子。 这是小提琴: http : //jsfiddle.net/zumdpjzx/

for( var i= 1; i < 3; i++){ console.log(i); var arrData = [ ["2014-08-20", 100, 100], ["2014-08-21", 95, 85], ["2014-08-22", 93, 71], ["2014-08-23", 88, 57], ["2014-08-24", 86, 42], ["2014-08-25", 98, 28], ["2014-08-26", 117, 14], ["2014-08-27", 123, 0] ]; arrData = arrData.sort((function(index){ return function(a, b){ return (a[index] === b[index] ? 0 : (a[index] < b[index] ? -1 : 1)); }; })(0)); console.log("array: " + arrData); var margin = {top: 40, right: 40, bottom: 60, left: 50}, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var parseDate = d3.time.format("%Y-%m-%d").parse; var x = d3.time.scale().range([0, width]) var y = d3.scale.linear().range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom") .ticks(arrData.length) .tickFormat(d3.time.format("%Y-%m-%d")); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var line = d3.svg.line() .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.close); }); var line2 = d3.svg.line() .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.open); }); var svg = d3.select("#chart" + i).append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var data = arrData.map(function(d) { return { //date: d[0], date: parseDate(d[0]), close: d[2], open: d[1] }; }); var length = arrData.length - 1; // Scale the range of the data x.domain(d3.extent(data, function(d) { return d.date; })); y.domain([0, d3.max(data, function(d) { return Math.max(d.close, d.open); })]); svg.append("g").attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis) .selectAll("text") .style("text-anchor", "end") .attr("dx", "-.8em") .attr("dy", ".15em") .attr("transform", function(d) { return "rotate(-65)" }); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("Open Issues"); svg.append("path") .datum(data) .attr("class", "line") .attr("d", line); svg.append("path") // Add the valueline2 path. .attr("class", "line") .style("stroke", "red") .attr("d", line2(data)) .text("line2"); svg.append("text") .attr("transform", "translate(" + (width+3) + "," + y(data[length].open) + ")") .attr("dy", ".35em") .attr("text-anchor", "start") .style("fill", "red") .text("Open"); svg.append("text") .attr("transform", "translate(" + (width+3) + "," + y(data[length].close) + ")") .attr("dy", ".35em") .attr("text-anchor", "start") .style("fill", "steelblue") .text("Close"); //mouse over var focus = svg.append("g") .attr("class", "focus") .style("display", "none"); focus.append("circle") .attr("r", 4.5); focus.append("circle") .attr("r", 4.5); var bisectDate = d3.bisector(function(d) { return d.date; }).left; var formatValue = d3.format(",.2f"); var formatCurrency = function(d) { return + d; }; focus.append("text") .attr("x", 9) .attr("dy", ".35em"); svg.append("rect") .attr("class", "overlay") .attr("width", width) .attr("height", height) .on("mouseover", function() { focus.style("display", null); }) .on("mouseout", function() { focus.style("display", "none"); }) .on("mousemove", mousemoveOpen); } function mousemoveOpen() { var x0 = x.invert(d3.mouse(this)[0]), i = bisectDate(data, x0, 1), d0 = data[i - 1], d1 = data[i], d = x0 - d0.date > d1.date - x0 ? d1 : d0; focus.attr("transform", "translate(" + x(d.date) + "," + y(d.open) + ")"); focus.select("text").text(formatCurrency(d.open)); } 

编辑:

我发现了一个新的解决scheme。 这里是小提琴: http : //jsfiddle.net/4h72u83h/1/谢谢你的帮助!

你非常接近标记,但是你没有跟踪你在mouseoutmouseovermousemove处理程序中更新哪个焦点元素。

你可以做这样的事情:

 for (var i = 1; i < 3; i++) { console.log(i); var arrData = [ ["2014-08-20", 100, 100], ["2014-08-21", 95, 85], ["2014-08-22", 93, 71], ["2014-08-23", 88, 57], ["2014-08-24", 86, 42], ["2014-08-25", 98, 28], ["2014-08-26", 117, 14], ["2014-08-27", 123, 0] ]; arrData = arrData.sort((function(index) { return function(a, b) { return (a[index] === b[index] ? 0 : (a[index] < b[index] ? -1 : 1)); }; })(0)); console.log("array: " + arrData); var margin = { top: 40, right: 40, bottom: 60, left: 50 }, width = 960 - margin.left - margin.right, height = 500 - margin.top - margin.bottom; var parseDate = d3.time.format("%Y-%m-%d").parse; var x = d3.time.scale() .range([0, width]) var y = d3.scale.linear() .range([height, 0]); var xAxis = d3.svg.axis() .scale(x) .orient("bottom").ticks(arrData.length).tickFormat(d3.time.format("%Y-%m-%d")); var yAxis = d3.svg.axis() .scale(y) .orient("left"); var line = d3.svg.line() .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.close); }); var line2 = d3.svg.line() .x(function(d) { return x(d.date); }) .y(function(d) { return y(d.open); }); var svg = d3.select("#chart" + i).append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var data = arrData.map(function(d) { return { //date: d[0], date: parseDate(d[0]), close: d[2], open: d[1] }; }); console.log(data); console.log(arrData.length); var length = arrData.length - 1; // Scale the range of the data x.domain(d3.extent(data, function(d) { return d.date; })); y.domain([0, d3.max(data, function(d) { return Math.max(d.close, d.open); })]); svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height + ")") .call(xAxis) .selectAll("text") .style("text-anchor", "end") .attr("dx", "-.8em") .attr("dy", ".15em") .attr("transform", function(d) { return "rotate(-65)" }); svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", ".71em") .style("text-anchor", "end") .text("Open Issues"); svg.append("path") .datum(data) .attr("class", "line") .attr("d", line); svg.append("path") // Add the valueline2 path. .attr("class", "line") .style("stroke", "red") .attr("d", line2(data)) .text("line2"); svg.append("text") .attr("transform", "translate(" + (width + 3) + "," + y(data[length].open) + ")") .attr("dy", ".35em") .attr("text-anchor", "start") .style("fill", "red") .text("Open"); svg.append("text") .attr("transform", "translate(" + (width + 3) + "," + y(data[length].close) + ")") .attr("dy", ".35em") .attr("text-anchor", "start") .style("fill", "steelblue") .text("Close"); //mouse over var focus = svg.append("g") .attr("class", "focus") .style("display", "none"); focus.append("circle") .attr("r", 4.5); focus.append("circle") .attr("r", 4.5); var bisectDate = d3.bisector(function(d) { return d.date; }).left; var formatValue = d3.format(",.2f"); var formatCurrency = function(d) { return +d; }; focus.append("text") .attr("x", 9) .attr("dy", ".35em"); svg.append("rect") .attr("class", "overlay") .attr("width", width) .attr("height", height) .on("mouseover", function() { var thisFocus = d3.select(d3.select(this)[0][0].parentNode).select(".focus"); thisFocus.style("display", null); }) .on("mouseout", function() { var thisFocus = d3.select(d3.select(this)[0][0].parentNode).select(".focus"); thisFocus.style("display", "none"); }) .on("mousemove", mousemoveOpen); } function mousemoveOpen() { var x0 = x.invert(d3.mouse(this)[0]), i = bisectDate(data, x0, 1), d0 = data[i - 1], d1 = data[i], d = x0 - d0.date > d1.date - x0 ? d1 : d0; var thisFocus = d3.select(d3.select(this)[0][0].parentNode).select(".focus"); thisFocus.attr("transform", "translate(" + x(d.date) + "," + y(d.open) + ")"); thisFocus.select("text").text(formatCurrency(d.open)); } 
 body { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .line { fill: none; stroke: steelblue; stroke-width: 1.5px; } .overlay { fill: none; pointer-events: all; } .focus circle { fill: none; stroke: steelblue; } .legend { padding: 5px; font: 10px sans-serif; background: yellow; box-shadow: 2px 2px 1px #888; } 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <body> <div id="chart1"></div> <div id="chart2"></div> </body> 

在你的例子中,在两个图表上调用mousemoveOpen。 从这个angular度来看,“关注”和“数据”在封闭之外存在。 在调用mousemoveOpen的时候,这两个参数都将从全局范围中获取,并使用它们设置的最后一个值。 这就是为什么最后的图表总是得到更新:焦点和数据variables点引用最后的图表。

我试着用你的小提琴演奏,但是我不能工作。 你可以使用下划线,或原生的JavaScript的“绑定”