鼠标悬停在多个折线图上,相同的x(时间)显示不同的y(价格)
D3.js: Multiple line charts mouseover with same x (time) showing different y (price)
我试图结合两个D3.js的例子,我发现这里bl.ocks.org/mbostock/1157787(多个示例)这里bl.ocks.org/mbostock/3902569(鼠标悬停的例子)
到目前为止一切正常。鼠标悬停焦点通过x(时间)链接到所有图表上,同时显示每个图表上的价格值。然而,显示的值和位置是由最后一张图表的数据设置的,在所有其他图表上显示错误的位置和值。我想弄清楚的是如何解决每一个图表与它自己的价值和焦点位置。我发现了几个关于多个图表和多个鼠标悬停焦点位置的类似问题,但没有将两个主题结合起来。我是JS和D3的新手,所以我不知道如何将正确的值分配给正确的焦点对象。请看这里http://plnkr.co/edit/btAPsU0ra6uR3f4ZXZWj。这是我的代码
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px sans-serif;
margin: 0;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
//shape-rendering: crispEdges;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 1.5px;
}
.area {
//fill: #e7e7e7;
fill: transparent;
}
.overlay {
fill: none;
pointer-events: all;
}
.focus circle {
fill: none;
stroke: steelblue;
}
</style>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script>
var margin = {top: 8, right: 10, bottom: 20, left: 30},
width = 960 - margin.left - margin.right,
height = 138 - margin.top - margin.bottom;
var parseDate = d3.time.format("%b %Y").parse,
bisectDate = d3.bisector(function(d) { return d.date; }).left,
formatValue = d3.format(",.2f"),
formatCurrency = function(d) { return formatValue(d); };
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var area = d3.svg.area()
.x(function(d) { return x(d.date); })
.y0(height)
.y1(function(d) { return y(d.price); });
var line = d3.svg.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.price); });
var xAxis = d3.svg.axis()
.scale(x) // x is the d3.time.scale()
.orient("bottom") // the ticks go below the graph
.ticks(4); // specify the number of ticks
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(4);
d3.csv("stocks_chart2.csv", type, function(error, data) {
// Nest data by symbol.
var symbols = d3.nest()
.key(function(d) { return d.symbol; })
.entries(data);
// Compute the maximum price per symbol, needed for the y-domain.
symbols.forEach(function(s) {
s.maxPrice = d3.max(s.values, function(d) { return d.price; });
});
// Compute the minimum and maximum date across symbols.
// We assume values are sorted by date.
x.domain([
d3.min(symbols, function(s) { return s.values[0].date; }),
d3.max(symbols, function(s) { return s.values[s.values.length - 1].date; })
]);
// Add an SVG element for each symbol, with the desired dimensions and margin.
var svg = d3.select("body").selectAll("svg")
.data(symbols)
.enter().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 + ")");
// Add the area path elements. Note: the y-domain is set per element.
svg.append("path")
.attr("class", "area")
.attr("d", function(d) { y.domain([0, d.maxPrice]); return area(d.values); });
// Add the line path elements. Note: the y-domain is set per element.
svg.append("path")
.attr("class", "line")
.attr("d", function(d) { y.domain([0, d.maxPrice]); return line(d.values); });
// Add a small label for the symbol name.
svg.append("text")
.attr("x", width - 6)
.attr("y", height - 6)
.style("text-anchor", "end")
.text(function(d) { return d.key; });
svg.append('g') // create a <g> element
.attr('class', 'x axis') // specify classes
.attr("transform", "translate(0," + height + ")")
.call(xAxis); // let the axis do its thing
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("Value");
var focus = svg.append("g")
.attr("class", "focus")
.style("display", "none");
focus.append("circle")
.attr("r", 4.5);
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", mousemove);
function mousemove() {
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.price) + ")");
focus.select("text").text(formatCurrency(d.price));
}
});
function type(d) {
d.price = +d.price;
d.date = parseDate(d.date);
return d;
}
</script>
和在倍数示例中使用的data.csv(缩短)
symbol,date,price
S&P 500,Jan 2000,1394.46
S&P 500,Feb 2000,1366.42
S&P 500,Mar 2000,1498.58
S&P 500,Apr 2000,1452.43
S&P 500,May 2000,1420.6
S&P 500,Jun 2000,1454.6
S&P 500,Jul 2000,1430.83
S&P 500,Aug 2000,1517.68
S&P 500,Sep 2000,1436.51
S&P 500,Oct 2000,1429.4
S&P 500,Nov 2000,1314.95
S&P 500,Dec 2000,1320.28
S&P 500,Jan 2001,1366.01
S&P 500,Feb 2001,1239.94
S&P 500,Mar 2001,1160.33
S&P 500,Apr 2001,1249.46
S&P 500,May 2001,1255.82
S&P 500,Jun 2001,1224.38
S&P 500,Jul 2001,1211.23
S&P 500,Aug 2001,1133.58
S&P 500,Sep 2001,1040.94
S&P 500,Oct 2001,1059.78
S&P 500,Nov 2001,1139.45
S&P 500,Dec 2001,1148.08
S&P 500,Jan 2002,1130.2
S&P 500,Feb 2002,1106.73
S&P 500,Mar 2002,1147.39
S&P 500,Apr 2002,1076.92
S&P 500,May 2002,1067.14
S&P 500,Jun 2002,989.82
S&P 500,Jul 2002,911.62
S&P 500,Aug 2002,916.07
S&P 500,Dec 2008,903.25
S&P 500,Jan 2009,825.88
S&P 500,Feb 2009,735.09
S&P 500,Mar 2009,797.87
S&P 500,Apr 2009,872.81
S&P 500,May 2009,919.14
S&P 500,Jun 2009,919.32
S&P 500,Jul 2009,987.48
S&P 500,Aug 2009,1020.62
S&P 500,Sep 2009,1057.08
S&P 500,Oct 2009,1036.19
S&P 500,Nov 2009,1095.63
S&P 500,Dec 2009,1115.1
S&P 500,Jan 2010,1073.87
S&P 500,Feb 2010,1104.49
S&P 500,Mar 2010,1140.45
MSFT,Jan 2000,39.81
MSFT,Feb 2000,36.35
MSFT,Mar 2000,43.22
MSFT,Apr 2000,28.37
MSFT,May 2000,25.45
MSFT,Jun 2000,32.54
MSFT,Jul 2000,28.4
MSFT,Aug 2000,28.4
MSFT,Sep 2000,24.53
MSFT,Oct 2000,28.02
MSFT,Nov 2000,23.34
MSFT,Dec 2000,17.65
MSFT,Jan 2001,24.84
MSFT,Feb 2001,24
MSFT,Mar 2001,22.25
MSFT,Apr 2001,27.56
MSFT,Aug 2009,24.43
MSFT,Sep 2009,25.49
MSFT,Oct 2009,27.48
MSFT,Nov 2009,29.27
MSFT,Dec 2009,30.34
MSFT,Jan 2010,28.05
MSFT,Feb 2010,28.67
MSFT,Mar 2010,28.8
AMZN,Jan 2000,64.56
AMZN,Feb 2000,68.87
AMZN,Mar 2000,67
AMZN,Apr 2000,55.19
AMZN,May 2000,48.31
AMZN,Jun 2000,36.31
AMZN,Jul 2000,30.12
AMZN,Aug 2000,41.5
AMZN,Sep 2000,38.44
AMZN,Oct 2000,36.62
AMZN,Nov 2000,24.69
AMZN,Dec 2000,15.56
AMZN,Jan 2001,17.31
AMZN,Feb 2001,10.19
AMZN,Mar 2001,10.23
AMZN,Apr 2001,15.78
AMZN,May 2001,16.69
AMZN,Jun 2001,14.15
AMZN,Jul 2001,12.49
AMZN,May 2007,69.14
AMZN,Jun 2007,68.41
AMZN,Jul 2007,78.54
AMZN,Aug 2007,79.91
AMZN,Sep 2007,93.15
AMZN,Oct 2007,89.15
AMZN,Nov 2007,90.56
AMZN,Dec 2007,92.64
AMZN,Jan 2008,77.7
AMZN,Feb 2008,64.47
AMZN,Mar 2008,71.3
AMZN,Apr 2008,78.63
AMZN,May 2008,81.62
AMZN,Jun 2008,73.33
AMZN,Jul 2008,76.34
AMZN,Aug 2008,80.81
AMZN,Sep 2008,72.76
AMZN,Oct 2008,57.24
AMZN,Nov 2008,42.7
AMZN,Dec 2008,51.28
AMZN,Jan 2009,58.82
AMZN,Feb 2009,64.79
AMZN,Mar 2009,73.44
AMZN,Apr 2009,80.52
AMZN,May 2009,77.99
AMZN,Jun 2009,83.66
AMZN,Jul 2009,85.76
AMZN,Aug 2009,81.19
AMZN,Sep 2009,93.36
AMZN,Oct 2009,118.81
AMZN,Nov 2009,135.91
AMZN,Dec 2009,134.52
AMZN,Jan 2010,125.41
AMZN,Feb 2010,118.4
AMZN,Mar 2010,128.82
IBM,Jan 2000,100.52
IBM,Feb 2000,92.11
IBM,Mar 2000,106.11
IBM,Jun 2003,75.42
IBM,Jul 2003,74.28
IBM,Aug 2003,75.12
IBM,Sep 2003,80.91
IBM,Mar 2009,95.09
IBM,Apr 2009,101.29
IBM,May 2009,104.85
IBM,Jun 2009,103.01
IBM,Jul 2009,116.34
IBM,Aug 2009,117
IBM,Sep 2009,118.55
IBM,Oct 2009,119.54
IBM,Nov 2009,125.79
IBM,Dec 2009,130.32
IBM,Jan 2010,121.85
IBM,Feb 2010,127.16
IBM,Mar 2010,125.55
GOOG,Aug 2004,102.37
GOOG,Sep 2004,129.6
GOOG,Oct 2004,190.64
GOOG,Nov 2004,181.98
GOOG,Dec 2004,192.79
GOOG,Jan 2005,195.62
GOOG,Feb 2005,187.99
GOOG,Mar 2005,180.51
GOOG,Apr 2005,220
GOOG,May 2005,277.27
GOOG,Jun 2005,294.15
GOOG,Jul 2005,287.76
GOOG,Aug 2005,286
GOOG,Sep 2005,316.46
GOOG,Oct 2005,372.14
GOOG,Nov 2005,404.91
GOOG,Dec 2005,414.86
GOOG,Jan 2006,432.66
GOOG,Feb 2006,362.62
GOOG,Mar 2006,390
GOOG,Apr 2006,417.94
GOOG,May 2006,371.82
GOOG,Jun 2006,419.33
GOOG,Jul 2006,386.6
GOOG,Aug 2006,378.53
GOOG,Sep 2006,401.9
GOOG,Oct 2006,476.39
GOOG,Nov 2006,484.81
GOOG,Jul 2009,443.05
GOOG,Aug 2009,461.67
GOOG,Sep 2009,495.85
GOOG,Oct 2009,536.12
GOOG,Nov 2009,583
GOOG,Dec 2009,619.98
GOOG,Jan 2010,529.94
GOOG,Feb 2010,526.8
GOOG,Mar 2010,560.19
10 Year T-Note,Jan 2000,6.67
10 Year T-Note,Feb 2000,6.41
10 Year T-Note,Mar 2000,6.02
10 Year T-Note,Apr 2000,6.21
10 Year T-Note,May 2000,6.28
10 Year T-Note,Jun 2000,6.02
10 Year T-Note,Jul 2000,6.03
10 Year T-Note,Aug 2000,5.73
10 Year T-Note,Sep 2000,5.78
10 Year T-Note,Oct 2000,5.76
10 Year T-Note,Nov 2000,5.44
10 Year T-Note,Dec 2000,5.11
10 Year T-Note,Jan 2001,5.18
10 Year T-Note,Feb 2001,4.91
10 Year T-Note,Mar 2001,4.91
10 Year T-Note,Apr 2001,5.34
10 Year T-Note,May 2001,5.41
10 Year T-Note,Jun 2001,5.39
10 Year T-Note,Jul 2001,5.04
10 Year T-Note,Aug 2001,4.82
10 Year T-Note,Sep 2001,4.57
AAPL,Jan 2000,25.94
AAPL,Feb 2000,28.66
AAPL,Mar 2000,33.95
AAPL,Apr 2000,31.01
AAPL,May 2000,21
AAPL,Jun 2000,26.19
AAPL,Jul 2000,25.41
AAPL,Aug 2000,30.47
AAPL,Sep 2000,12.88
AAPL,Oct 2000,9.78
AAPL,Nov 2000,8.25
AAPL,Dec 2000,7.44
AAPL,Jan 2001,10.81
AAPL,Feb 2001,9.12
AAPL,Mar 2001,11.03
AAPL,Apr 2001,12.74
AAPL,May 2001,9.98
任何帮助都将非常感激!谢谢你!
我还没有把这个工作得很完美,但我相信这应该让你开始。你所做的事情不起作用的原因是因为你在所有的图表中共享数据d
。
function mousemove() {
var date = x.invert(d3.mouse(this)[0]),
index = bisectDate(data, date, 1),
d0 = data[index - 1],
d1 = data[index],
d = date - d0.date > d1.date - date ? d1 : d0;
focus.attr("transform", "translate(" + x(d.date) + "," + y(d.price) + ")");
focus.select("text").text(formatCurrency(d.price));
所以这里的这段代码是选择所有的focus
项目,你使用你的工具提示,但d.price
应用格式化的货币。然而,如果你看这个,驱动价格的d
直接来自鼠标移动的数据。
相反,您需要做的是为每个焦点项单独分配数据。不幸的是,我还没有完全做到这一点,因为我没有追踪index
是如何计算的,但这给出了一个想法:
function mousemove() {
var date = x.invert(d3.mouse(this)[0]),
index = bisectDate(data, date, 1),
d0 = data[index - 1],
d1 = data[index],
d = date - d0.date > d1.date - date ? d1 : d0;
var focus = svg.selectAll(".focus");
focus.attr("translate", function(d) {
return "translate(" + x(d.values[index].date) + "," + y(d.values[index].price) + ")"
});
focus.selectAll("text", function(d) {
return formatCurrency(d.values[index].price);
});
}
所以这里发生的是每个focus
项目都有它们的翻译和文本集,专门来自驱动该系列的数据。d
参数现在被限定在这些函数的范围内(并且将在D3之前的数据绑定后自动提供),并将用于访问您想要的实际数据。
相关文章:
- 悬停时显示当前时间
- 只显示潜水时悬停按钮X时间-可以'我不能使它正常工作
- 无法让悬停事件使用 jQuery UI 持续时间参数或 CSS 处理目标元素的同级元素
- 如何让时间轴悬停动画在某个 ID 可见时停止
- 时间轴.js如何将鼠标悬停事件添加到可视化项目框框
- D3.js :仅当指针在同一位置停留最短时间时,才启动鼠标悬停事件
- 如何制作一个更长时间的鼠标悬停棒
- 如何在悬停150毫秒的时间内将元素旋转到180度
- Highcharts:日期时间x轴的不规则时间间隔没有悬停在所有点上
- 如何让一个消息弹出(悬停)当玩家击中一个时间瞬间
- 使元素的悬停效果只持续有限的时间
- 鼠标悬停需要时间来显示图像
- 如果未经过时间,取消鼠标悬停
- 如果连续悬停一段时间触发
- 鼠标悬停在多个折线图上,相同的x(时间)显示不同的y(价格)
- 高图-散点图标记悬停状态持续时间过长
- Jquery -当频繁地悬停多次时,元素仍然会摇晃很长时间
- 显示时间悬停在完整的日历垂直资源视图
- 如何在悬停时以规则的时间间隔对图像进行混洗
- 如何在输入范围内获得悬停时间的值