我在一个页面上有多个d3图表,并希望为每个图表添加鼠标悬停效果。 目前只有一个图表受到影响并具有鼠标悬停效果。
我创建了一个包含多个图表的示例。 这是小提琴: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));
}
编辑:
我现在找到了一个新的解决方案。这是小提琴:http://jsfiddle.net/4h72u83h/1/ 谢谢你的帮助!
答案 0 :(得分:0)
我尝试过你的小提琴示例,但我无法让它发挥作用。您可以使用下划线或本机javascript&#39; bind&#39;
答案 1 :(得分:0)
您非常接近该标记,但是您没有跟踪mouseout
,mouseover
和mousemove
处理程序中要更新的焦点元素
你可以这样做:
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));
}
&#13;
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;
}
&#13;
<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>
&#13;
基本上,我在那里做的是修改mouseover
,mouseout
和mousemove
,以便抓取正确的焦点元素进行更新,然后更新它
重要的一点是:
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));
第一行抓取与接收鼠标事件的图形对应的焦点。您会在mouseover
和mouseout
处理程序中看到类似的行。
我可能建议你只是在一个对象中分别跟踪焦点元素,然后你可以在鼠标处理函数中使用该引用。一直选择它可能会对性能产生影响,但在这种情况下并非如此。