我对如何将工具提示添加到我的线性d3图表感到疯狂,以便用户可以看到多年来的性能特定值。 这是小提琴:http://jsfiddle.net/d9Lya/ 这个代码
// define dimensions of graph
var m = [20, 80, 80, 80]; // margins
var w = 650 - m[1] - m[3]; // width
var h = 500 - m[0] - m[2]; // height
var data = [30, 28, 33] ;
var years = [2010, 2011, 2012] ;
var data2 = [100, 200, 200] ;
var years2 = [2009, 2010, 2011] ;
var alldata = data.concat(data2);
var allyears = years.concat(years2);
var data3 = [200, 220, 300] ;
var years3 = [2011, 2012, 2013] ;
var alldata = data.concat(data2, data3);
var allyears = years.concat(years2, years3);
//unique vals functin
var unique = function(origArr) {
var newArr = [],
origLen = origArr.length,
found,
x, y;
for ( x = 0; x < origLen; x++ ) {
found = undefined;
for ( y = 0; y < newArr.length; y++ ) {
if ( origArr[x] === newArr[y] ) {
found = true;
break;
}
}
if ( !found) newArr.push( origArr[x] );
}
return newArr;
};
allyears = unique(allyears);
var x = d3.scale.linear().domain([d3.min(allyears), d3.max(allyears)]).range([0,w]);
var y = d3.scale.linear().domain([0, (d3.max(alldata))*1.3]).range([h, 0]);
var line = d3.svg.line()
.x(function(d,i) {
return x(years[i]);
})
.y(function(d) {
return y(d);
})
var line2 = d3.svg.line()
.x(function(d,i) {
return x(years2[i]);
})
.y(function(d) {
return y(d);
})
var line3 = d3.svg.line()
.x(function(d,i) {
return x(years3[i]);
})
.y(function(d) {
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 xAxis
var xAxis = d3.svg.axis().scale(x).ticks(allyears.length).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(8).orient("left");
// Add the y-axis to the left
graph.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(-25,0)")
.call(yAxisLeft);
graph.append("svg:text")
.attr("class", "title1")
.attr("x", (w/2))
.attr("y", 0)
.text("Performance")
.style({ "stroke": "Black", "fill": "Black", "stroke-width": "1px"})
.attr("text-anchor", "middle")
.style("font-size", "16px") ;
graph.append("svg:path").attr("d", line(data)).style("stroke", "steelblue");
graph.append("svg:text")
.attr("class", "title1")
.attr("x", 0)
.attr("y", 30)
.text("TEAM A")
.style({ "stroke": "steelblue", "fill": "steelblue", "stroke-width": "0px"});
graph.append("svg:path")
.attr("d", line2(data2)).style("stroke", "green")
;
graph.append("svg:text")
.attr("class", "title2")
.attr("x", 0)
.attr("y", 50)
.text("TEAM B")
.style({ "stroke": "Green", "fill": "Green", "stroke-width": "0px"});
graph.append("svg:path").attr("d", line3(data3)).style("stroke", "red");
graph.append("svg:text")
.attr("class", "title3")
.attr("x", 0)
.attr("y", 70)
.text("team C")
.style({ "stroke": "Red", "fill": "Red", "stroke-width": "0px"});
我实际上是D3的新手,我已经看到了其他样本,我无法在我的js代码上重现它们。谁能帮我? 此致
答案 0 :(得分:2)
我在评论中提到&#34;线的数据是完整的数组,并且弄清楚用户鼠标在线的位置需要额外的计算&#34;。这是使用&#34;隐形圈&#34;的一个原因。在数据点上抓取鼠标事件。另一个原因是,您可以使圆的半径远大于笔划宽度,以便为鼠标事件创建更大的区域。第三个是你可以在鼠标悬停时装饰圆圈,就像在NVD3 line charts。
中一样但是,如果你不想要额外的圈子挤占你的DOM,那该怎么办?或者,如果您希望鼠标悬停事件在线路上任何地方触发,而不仅仅是在点上?您仍然可以确定鼠标相对于该行的位置,并可以使用它来查找该行的数据数组中的正确点。
d3.selectAll("path")
.on("mouseover", findValue);
function findValue(d, i) {
var mouseX = d3.mouse(this.parentNode)[0];
//find the mouse's horizontal coordinate relative to the drawing container
var dataX = x.invert(mouseX);
//invert the scale to find the x value at the mouse point
//scan through the data array to find the value closest to the mouse
var j = d.length;
while ((j--) && (d[j].x > dataX)); //repeat until false
var datapoint;
if (j >= 0) {
//d[j] will now be the first datapoint *less than* the mousepoint
//compare it with d[j+1] to see which is closer to the mouse:
if ( isNaN(d[j+1]) || (dataX - d[j].x < d[j+1].x - dataX) )
datapoint = d[j];
else
datapoint = d[j+1];
} else {
//all the values in the array were greater than the mouse point,
//so return the first point
datapoint = d[0];
}
//Do something with your datapoint value:
alert("Crossed line " + i + " near " + [datapoint.x, datapoint.y]);
}
此处的实例:http://fiddle.jshell.net/c2mru/8/
传递给事件处理函数的d
值是附加到<path>
元素的数据对象。这通常是线上的点数组,尽管有时它是包含点数组作为属性的对象,在这种情况下,您必须修改它以适应。使用d3.mouse(container)
可以找出鼠标在相关SVG坐标系中的位置,并使用比例的反转方法可以计算出鼠标相对于水平轴的位置。然后,假设您的数据是不重复x值的法线图,那么滚动点数组就可以找到最接近鼠标的点数。
请注意,此方法无法使用@ picus&#39;原始代码,因为该代码实际上没有使用d3方法将数据链接到元素。 (@picus,查看Tutorials page了解如何更轻松地使用d3!)