我在d3中有一个垂直线图,我正试图添加一个工具提示,以直线和圆圈的形式,跟随光标在垂直方向的移动。后一种方法有效,但圆无法沿着路径移动——我尝试过不同的方法,但圆从未沿着路径移动,它目前只是沿着图形的y轴移动(例如,请参见附图)。我已经在水平图上实现了同样的效果,但是当我尝试调整垂直图的代码时,我无法让圆正常工作。
我将下面的代码与一个示例结合在一起,对javascript来说还是很新的,所以代码有点混乱。
圆圈(红色)无法跟随路径的图形截图:
function test(test_data) {
// setup params
var margin_ = {top: 30, right: 60, bottom: 30, left: 20},
width_ = 300
height_ = 700
// Add svg
var line_graph = d3.select("#my_dataviz_test")
.append("svg")
.attr("width", width_ + 100)
.attr("height", height_)
.append("g")
.attr("transform",
"translate(" + margin_.left + "," + margin_.top + ")");
d3.csv(test_data,
function(d){
return { output_time_ref: d.output_time_ref = +d.output_time_ref,
output_time: d3.timeParse("%d/%m/%Y %H:%M")(d.output_time),
prediction: d.prediction = +d.prediction,
}
},
function(data) {
// Add x axis
var x_test = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return +d.prediction; })])
.range([ 0, width_ ]);
line_graph.append("g")
.attr("transform", "translate(" + 0 + "," + height_ + ")")
.call(d3.axisBottom(x_test).tickSizeOuter(0).tickSizeInner(0).ticks(2))
.select(".domain").remove();
// Add Y axis
var y_test = d3.scaleLinear()
.domain([0, d3.max(data, function(d) { return +d.output_time_ref; })])
.range([ height_, 0 ]);
line_graph.append("g")
.call(d3.axisLeft(y_test).tickSizeOuter(0).tickSizeInner(0).ticks(5))
.select(".domain").remove();
// Add the line
path_test = line_graph.append("path")
.datum(data)
.attr("fill", "none")
.attr("fill", "steelblue")
.attr("fill-opacity", 0.2)
.attr("stroke", "steelblue")
.attr("stroke-width", 1)
.attr("d", d3.line()
.curve(d3.curveBasis)
.x(function(d) { return x_test(d.prediction) })
.y(function(d) { return y_test(d.output_time_ref) })
)
var mouseG2 = line_graph
.append("g")
.attr("class", "mouse-over-effects");
mouseG2
.append("path")
.attr("class", "mouse-line2")
.style("stroke", "#393B45")
.style("stroke-width", "0.5px")
.style("opacity", 0.75)
mouseG2.append("text")
.attr("class", "mouse-text2")
var totalLength2 = path_test.node().getTotalLength();
var mousePerLine2 = mouseG2.selectAll('.mouse-per-line2')
.data(data)
.enter()
.append("g")
.attr("class", "mouse-per-line2");
mousePerLine2.append("circle")
.attr("r", 8)
.style("stroke", 'red')
.style("fill", "none")
.style("stroke-width", "2px")
.style("opacity", "0");
mouseG2
.append('svg:rect')
.attr('width', width_)
.attr('height', height_)
.attr('fill', 'none')
// .attr('opacity', 0.2)
.attr('pointer-events', 'all')
.on('mouseout', function() {
d3.select("#my_dataviz_test")
.selectAll(".mouse-per-line2 circle")
.style("opacity", "0"); })
var mouseover = function(d) {
d3.select("#my_dataviz_test")
.select(".mouse-line2")
.style("opacity", "1")
.select(".mouse-text2")
.style("opacity", "1")
.select(".mouse-per-line2 circle")
.style("opacity", "1");
///////////////////////////////////////////////////
d3.select("#my_dataviz_test")
var mouse2 = d3.mouse(this);
d3.select("#my_dataviz_test")
.select(".mouse-text2")
.attr("y", mouse2[1])
.attr("transform", "translate(" + (mouse2[1]+60) + "," + (mouse2[1]+5) + ") rotate(90)")
d3.select("#my_dataviz_test")
.select(".mouse-line2")
.attr("d", function() {
var d = "M" + width_ + "," + mouse2[1];
d += " " + 0 + "," + mouse2[1];
return d;
})
d3.select("#my_dataviz_test")
.selectAll(".mouse-per-line2")
.attr("transform", function(d, i) {
var beginning2 = 0,
end2 = totalLength2
target2 = null;
while (true){
target2 = Math.floor((beginning2 + end2) / 2);
var pos2 = path_test.node().getPointAtLength(target2);
if ((target2 === end2 || target2 === beginning2) && pos2.y !== mouse2[1]) {
break;
}
if (pos2.y > mouse2[1]) { end2 = target2; }
else if (pos2.y < mouse2[1]) { beginning2 = target2; }
else {break};
}
d3.select("#my_dataviz_test").select('circle')
.style("opacity", 1)
return "translate(" + (pos2.x) + "," + mouse2[1] +")";
});
///////////////////////////////////////////////////
}
var mouseleave = function(d) {
d3.select("#my_dataviz_test")
.select(".mouse-line2")
.style("opacity", "0")
d3.select("#my_dataviz_test")
.select(".circle")
.style("opacity", "0")
}
line_graph
.on("mouseover", mouseover)
.on("mouseleave", mouseleave)
})
}
test_data.csv:
output_time_ref,output_time,prediction
0,04/01/2013 00:00,0
1,04/01/2013 00:30,0
2,04/01/2013 01:00,0
3,04/01/2013 01:30,0
4,04/01/2013 02:00,0
5,04/01/2013 02:30,0
6,04/01/2013 00:00,0
7,04/01/2013 03:30,0
8,04/01/2013 04:00,0
9,04/01/2013 04:30,8.17E-05
10,04/01/2013 05:00,0.002014463
11,04/01/2013 05:30,0.01322314
12,04/01/2013 06:00,0.033264463
13,04/01/2013 06:30,0.059607438
14,04/01/2013 07:00,0.098553719
15,04/01/2013 07:30,0.145661157
16,04/01/2013 08:00,0.186983471
17,04/01/2013 08:30,0.225206612
18,04/01/2013 09:00,0.267561983
19,04/01/2013 09:30,0.314049587
20,04/01/2013 10:00,0.334710744
21,04/01/2013 10:30,0.350206612
22,04/01/2013 11:00,0.359504132
23,04/01/2013 11:30,0.375
24,04/01/2013 12:00,0.393595041
25,04/01/2013 12:30,0.396694215
26,04/01/2013 13:00,0.393595041
27,04/01/2013 13:30,0.385330579
28,04/01/2013 14:00,0.367768595
29,04/01/2013 14:30,0.344008264
30,04/01/2013 15:00,0.320247934
31,04/01/2013 15:30,0.297520661
32,04/01/2013 16:00,0.273760331
33,04/01/2013 16:30,0.254132231
34,04/01/2013 17:00,0.216942149
35,04/01/2013 17:30,0.167355372
36,04/01/2013 18:00,0.123966942
37,04/01/2013 18:30,0.080785124
38,04/01/2013 19:00,0.041115702
39,04/01/2013 19:30,0.015805785
40,04/01/2013 20:00,0.002489669
41,04/01/2013 20:30,2.67E-05
42,04/01/2013 21:00,1.24E-05
43,04/01/2013 21:30,0
44,04/01/2013 22:00,0
45,04/01/2013 22:30,0
46,04/01/2013 23:00,0
47,04/01/2013 23:30,0
暂无答案!
目前还没有任何答案,快来回答吧!