我正在使用 D3 制作交互式面积图。在将鼠标悬停在区域图表上时,我希望在图表顶部滚动一个点,如下例所示:http: //hci.stanford.edu/jheer/files/zoo/ex/time/倍数.html
一旦获得鼠标位置(使用 d3.mouse),如何将这些坐标转换为相应的数据?x 轴是直接使用 x 比例的倒数(例如 xinvert)。但是,我找不到图表对应的 y 坐标。理想情况下,我可以“查找”数据中的 x 坐标并找到相应的 y 坐标,但不确定如何使用 D3 执行此操作。谢谢!
我正在使用 D3 制作交互式面积图。在将鼠标悬停在区域图表上时,我希望在图表顶部滚动一个点,如下例所示:http: //hci.stanford.edu/jheer/files/zoo/ex/time/倍数.html
一旦获得鼠标位置(使用 d3.mouse),如何将这些坐标转换为相应的数据?x 轴是直接使用 x 比例的倒数(例如 xinvert)。但是,我找不到图表对应的 y 坐标。理想情况下,我可以“查找”数据中的 x 坐标并找到相应的 y 坐标,但不确定如何使用 D3 执行此操作。谢谢!
创建自己的查找表实际上相对容易:
/* Create the lookup table */
var table = {};
data.forEach(function(d) {
table[d.x] = d.y;
});
如果您有足够的数据点,这是一个可行的解决方案,但您可能需要使用某种舍入或插值器来填充中间 x 值。例如,如果您的点之间存在固定间距,您可以使用线性插值器并执行以下计算以获取您的圆的坐标mouseover:
var x = d3.mouse(this)[0];
var y;
if ( table[x] === undefined ) {
var lower = x - (x % SPACING);
var upper = lower + SPACING;
var between = d3.interpolateNumber(table[lower], table[upper]);
y = between( (x % SPACING) / SPACING );
} else {
y = table[x];
}
这是Mike Bostock如何做到这一点的另一个例子:http : //bl.ocks.org/3025699
mbostock(D3.js 作者)在这里实现这个
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.close) + ")");
focus.select("text").text(formatCurrency(d.close));
}
我使用此代码查看每个点的 X 和 Y 值,并在鼠标事件上在我的曲线上画一个圆圈:这里的 jsFiddle 示例
Y_value 是一个全局的!
var Y_value;
我定义了我的轴怒
x = d3.time.scale().range([0, w]);
y = d3.scale.linear().range([h, 0]);
我定义了圆形光标
var circle = svg.append("circle")
.attr("r", 8)
.attr("cx", 0)
.attr("cy", 0)
.style({fill: '#fff', 'fill-opacity': .2, stroke: '#000', "stroke-width": '1px'})
.attr("opacity", 0);
我在我的圈子上添加了一个工具提示
var tooltip = circle.append("svg:title");
我有我的事件代码
mySensitiveArea.on("mousemove", function() {
var X_pixel = d3.mouse(this)[0],
X_date = x.invert(X_pixel);
var Y_pixel = y(Y_value);
var pathData = curve1.data()[0]; // recupere donnée de la courbe
pathData.forEach(function(element, index, array) {
if ((index+1 < array.length) && (array[index].date <= X_date) && (array[index+1].date >= X_date)) {
if (X_date-array[index].date < array[index+1].date-X_date) Y_value = array[index].val;
else Y_value = array[index+1].val;
}
});
circle.attr("opacity", 1)
.attr("cx", X_px)
.attr("cy", Math.round(y(Y_value)));
tooltip.text("X = " + (X_date) + "\nY = " + (Y_value));
});