d3.js - 如何在悬停时延长跟随鼠标的垂直线
问题描述
我在将悬停时的垂直线延长两倍时遇到问题,我的目的是将两个相似的图表与穿透两个图表的垂直线进行比较(在这个例子中它暂时只包含一个图表)。但我只能稍微延长一点,终于到了极限,时间还不够长。顺便说一句,如果我想在缩放或平移时用围绕每个点的圆圈显示每个点的值,我该怎么办?
var datapointCount = 1000;
var data = [
[1541734491000, 66, 13.096, 385.18518518518522],
[1541734491000, 71, 13.15, 400.8641975308642],
[1541734532000, 67, 13.126, 390.61728395061732],
[1541734532000, 70, 13.134, 392.83950617283949],
[1541734567000, 56, 13.121, 390.12345679012344],
[1541734567000, 66, 13.149, 393.33333333333337],
[1541734605000, 55, 13.113, 381.73066727258959],
[1541734605000, 65, 13.156, 395.80246913580243],
[1541734648000, 30, 13.084, 388.76543209876547],
[1541734648000, 62, 13.147, 397.16049382716051],
[1541734683000, 46, 13.076, 390.75361660228737],
[1541734683000, 61, 13.122, 395.679012345679],
[1541734724000, 53, 13.06, 389.50617283950618],
[1541734724000, 66, 13.087, 393.33333333333337],
[1541734761000, 24, 13.088, 390.49382716049388],
[1541734761000, 63, 13.131, 396.41975308641975],
[1541734798000, 7, 13.111, 390.879345603272],
[1541734798000, 23, 13.142, 397.53389381201242],
[1541734838000, 0, 13.138, 389.63265924411121],
[1541734958000, 0, 13.06, 390.49382716049382],
[1541734958000, 5, 13.131, 391.11111111111109],
[1541734996000, 4, 13.077, 384.84208134514881],
[1541734996000, 14, 13.129, 395.925925925926],
[1541735044000, 5, 13.064, 387.91562523668864],
[1541735044000, 17, 13.096, 398.39506172839504],
[1541735071000, 0, 13.109, 390.38476103915775],
[1541735071000, 10, 13.281, 392.8402635764599],
[1541735221000, 0, 12.946, 391.60493827160496],
[1541735341000, 0, 12.787, 391.60493827160496],
[1541735461000, 0, 12.702, 391.72839506172841],
[1541735512000, 0, 12.66, 391.85185185185185],
[1541735581000, 0, 12.642, 391.72839506172841],
[1541735701000, 0, 12.575, 391.72839506172841],
[1541735821000, 0, 12.486, 391.85185185185185],
[1541735941000, 0, 12.443, 391.72839506172841],
[1541736061000, 0, 12.393, 391.72839506172841],
[1541736181000, 0, 12.356, 391.72839506172841],
[1541736301000, 0, 12.329, 391.72839506172841],
[1541736421000, 0, 12.315, 391.60493827160496],
[1541736541000, 0, 12.276, 391.60493827160496],
[1541736661000, 0, 12.277, 391.72839506172841],
[1541736781000, 0, 12.228, 391.48148148148152],
[1541736901000, 0, 12.215, 391.48148148148152],
[1541737021000, 0, 12.214, 391.48148148148152],
[1541737141000, 0, 12.216, 391.60493827160496],
[1541737261000, 0, 12.188, 391.60493827160496],
[1541737381000, 0, 12.155, 391.60493827160496],
[1541737381000, 0, 12.161, 391.60493827160496],
[1541737465000, 0, 13.61, 391.358024691358],
[1541737465000, 5, 13.614, 391.358024691358],
[1541737497000, 0, 13.698, 391.48148148148152],
[1541737562000, 4, 13.73, 391.358024691358],
[1541737562000, 5, 13.736, 391.358024691358],
[1541737594000, 0, 13.738, 391.48148148148152],
[1541737693000, 4, 13.769, 391.60493827160496],
[1541737723000, 0, 13.759, 391.60493827160496],
[1541737843000, 0, 13.614, 392.46913580246917],
[1541737906000, 4, 13.552, 387.40740740740739],
[1541737906000, 7, 13.614, 394.07407407407408],
[1541737965000, 0, 13.614, 391.97530864197529],
[1541737980000, 5, 13.542, 383.83397712641067],
[1541737980000, 9, 13.614, 396.17283950617286],
[1541738021000, 4, 13.573, 383.46966598500342],
[1541738021000, 4, 13.613, 388.77830796031208],
[1541738052000, 4, 13.546, 384.61940468075437],
[1541738052000, 8, 13.614, 398.02999318336742],
[1541738096000, 8, 13.489, 378.77376353858972],
[1541738096000, 36, 13.56, 388.64576232674392],
[1541738137000, 47, 13.518, 383.83624933727185],
[1541738137000, 58, 13.559, 390.98765432098764],
[1541738178000, 54, 13.553, 386.92266909035823],
[1541738178000, 56, 13.584, 393.7037037037037],
[1541738209000, 45, 13.548, 390.37037037037032],
[1541738209000, 55, 13.587, 392.34567901234567],
[1541738251000, 25, 13.497, 389.7644474740589],
[1541738251000, 54, 13.562, 394.56865863818831],
[1541738295000, 49, 13.505, 382.22676664394453],
[1541738295000, 65, 13.566, 393.58024691358025],
[1541738332000, 61, 13.129, 389.38650306748468],
[1541738332000, 66, 13.277, 392.35249564492915],
[1541738368000, 44, 13.06, 386.6802999318337],
[1541738368000, 66, 13.103, 392.9637203665834],
[1541738404000, 50, 13.084, 380.00378701810195],
[1541738404000, 63, 13.135, 390.02272210861167],
[1541738441000, 20, 13.064, 383.36817389987124],
[1541738441000, 62, 13.168, 391.23456790123453],
[1541738479000, 36, 13.091, 368.56631609699093],
[1541738479000, 55, 13.128, 397.41649625085211],
[1541738518000, 59, 13.104, 385.33212148754069],
[1541738518000, 70, 13.136, 397.41649625085211],
[1541738561000, 42, 13.128, 383.23259865182155],
[1541738561000, 61, 13.135, 386.56441717791409],
[1541738595000, 26, 13.124, 375.58812391123229],
[1541738595000, 59, 13.139, 386.56593198515486],
[1541738640000, 50, 13.121, 383.23487086268273],
[1541738640000, 55, 13.137, 387.17488449594794],
[1541738678000, 46, 13.061, 384.5921381504204],
[1541738678000, 62, 13.129, 389.517533893812],
[1541738712000, 47, 13.065, 384.10361281526923],
[1541738712000, 63, 13.091, 391.122472165417],
[1541738757000, 62, 13.056, 385.70249185791107],
[1541738757000, 79, 13.128, 388.30038627584639],
[1541738789000, 62, 13.075, 383.11595849428159],
[1541738789000, 77, 13.151, 385.57827766416722],
[1541738832000, 54, 13.091, 383.37499053245472],
[1541738832000, 60, 13.135, 386.80678633643868],
[1541738869000, 30, 13.128, 382.15329849276679],
[1541738869000, 52, 13.135, 384.857986821177],
[1541738908000, 7, 13.068, 384.61258804817089],
[1541738908000, 20, 13.128, 389.40998257971671],
[1541738962000, 0, 13.093, 373.0303718851776],
[1541739029000, 7, 13.058, 374.87843671892756],
[1541739029000, 47, 13.12, 386.82193440884646],
[1541739061000, 43, 13.04, 381.37317276376581],
[1541739061000, 57, 13.082, 386.1970764220253],
[1541739102000, 18, 13.055, 374.01120957358177],
[1541739102000, 62, 13.085, 386.70680905854726],
[1541739140000, 14, 13.078, 384.24373248504128],
[1541739140000, 28, 13.126, 394.34976899189576],
[1541739187000, 0, 13.18, 367.79214139643591],
[1541739244000, 8, 13.123, 376.10240096947666],
[1541739244000, 12, 13.154, 383.21896538665453],
[1541739256000, 7, 13.101, 377.338483677952],
[1541739256000, 16, 13.133, 390.49382716049382],
[1541739292000, 0, 13.106, 381.13004620162087],
[1541739292000, 6, 13.183, 390.49382716049382],
[1541739442000, 0, 13.179, 382.62667575551012],
[1541739442000, 5, 13.189, 382.62667575551012],
[1541739447000, 7, 13.121, 368.43850423605022],
[1541739447000, 14, 13.171, 382.86980231765506],
[1541739491000, 7, 13.113, 377.34378550329473],
[1541739491000, 21, 13.132, 383.239415284405],
[1541739531000, 0, 13.184, 382.74710293115197],
[1541739651000, 0, 13.156, 383.1212603196243],
[1541739651000, 8, 13.196, 383.48708626827238],
[1541739687000, 11, 13.111, 370.9346360675604],
[1541739687000, 17, 13.167, 382.62970536999165],
[1541739719000, 14, 13.143, 378.939634931455],
[1541739719000, 23, 13.185, 385.96909793228815],
[1541739757000, 6, 13.123, 377.21881390593046],
[1541739757000, 14, 13.161, 383.62796334166478],
[1541739813000, 0, 13.196, 363.32954631523137],
[1541739933000, 0, 13.19, 380.89903809740213],
[1541740053000, 0, 13.224, 380.77179428917668],
[1541740173000, 0, 13.212, 381.26410664242974],
[1541740183000, 4, 13.16, 377.32485041278494],
[1541740183000, 7, 13.218, 381.38529122169206],
[1541740237000, 0, 13.234, 365.31186094069528],
[1541740237000, 5, 13.238, 369.71662284545721],
[1541740271000, 0, 13.234, 377.08020904339924],
[1541740391000, 0, 13.23, 389.87654320987656],
[1541740511000, 0, 13.202, 381.64659547072631],
[1541740540000, 4, 13.124, 374.99280466560629],
[1541740540000, 21, 13.18, 382.138150420359],
[1541740578000, 6, 13.102, 379.55010224948876],
[1541740578000, 17, 13.185, 387.93456032719837],
[1541740631000, 0, 13.189, 380.68696508369311],
[1541740666000, 5, 13.102, 370.93766568204194],
[1541740666000, 22, 13.189, 381.28834355828224],
[1541740688000, 9, 13.115, 376.10618798757855],
[1541740688000, 21, 13.147, 381.40877073392409],
[1541740742000, 0, 13.187, 374.33586196638407],
[1541740862000, 0, 13.189, 380.17117321820797],
[1541740943000, 7, 13.094, 379.31454972354766],
[1541740943000, 12, 13.162, 381.40043929409978],
[1541740958000, 0, 13.105, 370.0704385366962],
[1541740958000, 10, 13.282, 380.3022040445353],
[1541741112000, 0, 13.089, 382.49640233280314],
[1541741232000, 0, 13.005, 381.75717639930315],
[1541741277000, 0, 12.924, 381.87911838218588],
[1541741352000, 0, 12.824, 382.12300234795123],
[1541741352000, 0, 12.829, 382.24570173445431],
[1541741472000, 0, 12.823, 382.24267211997272],
[1541741525000, 5, 12.916, 381.74808755585855],
[1541741525000, 12, 13.181, 382.11845792622887],
[1541741559000, 4, 13.312, 373.39619783382568],
[1541741559000, 15, 13.377, 379.67052942513067],
[1541741578000, 4, 13.092, 374.01499659168371],
[1541741578000, 15, 13.34, 387.05900174202833],
[1541741632000, 0, 13.134, 381.74733015223813],
[1541741662000, 5, 13.051, 363.97166228454569],
[1541741662000, 23, 13.106, 383.71279254714841],
[1541741694000, 16, 13.011, 363.60356412503654],
[1541741694000, 50, 13.07, 379.5660077255169],
[1541741737000, 45, 13.046, 374.37773882559156],
[1541741737000, 54, 13.109, 386.81814739074451],
[1541741777000, 8, 13.065, 378.68817692948573],
[1541741777000, 49, 13.107, 380.77406650003786],
[1541741811000, 4, 13.042, 349.19588080631024],
[1541741811000, 32, 13.073, 380.41278497311214],
[1541741865000, 33, 13.068, 378.8139329805997],
[1541741865000, 38, 13.092, 379.26834810270395],
[1541741888000, 18, 13.058, 379.92653184882226],
[1541741888000, 43, 13.107, 383.21669317579335],
[1541741926000, 4, 13.07, 369.29739994157171],
[1541741926000, 19, 13.114, 380.667272589563],
[1541741979000, 6, 13.043, 377.45057941376962],
[1541741979000, 10, 13.086, 383.95364689843223],
[1541742017000, 0, 13.14, 379.26834810270395],
[1541742131000, 6, 13.026, 360.54703476482621],
[1541742131000, 20, 13.117, 375.95773687798226],
[1541742159000, 11, 13.04, 355.51635991820041],
[1541742159000, 13, 13.069, 374.36037264258118],
[1541742205000, 0, 13.247, 375.72066954480044],
[1541742325000, 0, 13.07, 380.41884420207526],
[1541742445000, 0, 12.964, 380.80739225933496],
[1541742499000, 0, 12.914, 380.69150950541541],
[1541742509000, 0, 12.894, 380.69226690903582],
[1541742565000, 0, 12.86, 380.82329773536316],
[1541742685000, 0, 12.806, 380.22191926077403],
[1541742805000, 0, 12.702, 380.48398091342875],
[1541742805000, 0, 12.713, 380.48398091342875],
[1541742925000, 0, 12.649, 380.53162650602411],
[1541743045000, 0, 12.582, 380.61295180722891],
[1541743165000, 0, 12.556, 380.68524096385545],
[1541743285000, 0, 12.516, 380.75301204819277],
[1541743405000, 0, 12.464, 380.691265060241],
[1541743525000, 0, 12.433, 380.50903614457832],
[1541743525000, 0, 12.438, 380.75],
[1541743645000, 0, 12.402, 380.67469879518069],
[1541743765000, 0, 12.393, 380.71987951807228]
];
var svg = d3.select("svg"),
margin = {
top: 20,
right: 20,
bottom: 110,
left: 40
},
margin2 = {
top: 430,
right: 20,
bottom: 30,
left: 40
},
width = +svg.attr("width") - margin.left - margin.right,
height = +svg.attr("height") - margin.top - margin.bottom,
height2 = +svg.attr("height") - margin2.top - margin2.bottom;
var x = d3.scaleTime().range([0, width]),
x2 = d3.scaleTime().range([0, width]),
x3 = d3.scaleTime().range([0, width]),
x4 = d3.scaleTime().range([0, width]),
y = d3.scaleLinear().range([height, 0]),
y2 = d3.scaleLinear().range([height2, 0]),
y3 = d3.scaleLinear().range([height, 0]),
y4 = d3.scaleLinear().range([height, 0]);
var xAxis = d3.axisBottom(x),
xAxis2 = d3.axisBottom(x2),
yAxisR = d3.axisRight(y3).tickFormat(d3.format(".2f")),
yAxis3 = d3.axisLeft(y3),
yAxis4 = d3.axisLeft(y4),
yAxis = d3.axisRight(y);
var brush = d3.brushX()
.extent([
[0, 0],
[width, height2]
])
.on("brush end", brushed);
var zoom = d3.zoom()
.scaleExtent([1, Infinity])
.translateExtent([
[0, 0],
[width, height]
])
.extent([
[0, 0],
[width, height]
])
.on("zoom", zoomed);
var line = d3.line()
.x(function(d) {
return x(new Date(d[0]));
})
.y(function(d) {
return y(d[1]);
});
var line2 = d3.line()
.x(function(d) {
return x2(new Date(d[0]));
})
.y(function(d) {
return y2(d[1]);
});
var line3 = d3.line()
.x(function(d) {
return x3(new Date(d[0]));
})
.y(function(d) {
return y3(d[2]);
});
var line4 = d3.line()
.x(function(d) {
return x4(new Date(d[0]));
})
.y(function(d) {
return y4(d[3]);
});
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width)
.attr("height", height);
var focus = svg.append("g")
.attr("class", "focus")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var context = svg.append("g")
.attr("class", "context")
.attr("transform", "translate(" + margin2.left + "," + margin2.top + ")");
x.domain(d3.extent(data, function(d) {
return new Date(d[0]);
}));
y.domain([d3.min(data, function(d) {
return d[1];
}),
d3.max(data, function(d) {
return d[1];
})
]);
x2.domain(x.domain());
y2.domain(y.domain());
x3.domain(d3.extent(data, function(d) {
return new Date(d[0]);
}));
y3.domain([d3.min(data, function(d) {
return d[2];
}),
d3.max(data, function(d) {
return d[2];
})
]);
x4.domain(d3.extent(data, function(d) {
return new Date(d[0]);
}));
y4.domain([d3.min(data, function(d) {
return d[3];
}),
d3.max(data, function(d) {
return d[3];
})
]);
focus.append("path")
.datum(data)
.attr("class", "line3")
.attr("d", line3);
focus.append("path")
.datum(data)
.attr("class", "line4")
.attr("d", line4);
focus.append("path")
.datum(data)
.attr("class", "line")
.attr("d", line);
focus.append("g")
.attr("class", "axis axis--x axisGreen")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
focus.append("g")
.attr("class", "axis axis--y axisGreen")
.call(yAxis);
focus.append("g")
.attr("class", "axis axis--y axisBlue")
.call(yAxis4);
focus.append("g")
.attr("class", "axis axis--y axisRed")
.attr("transform", "translate(" + width + ", 0)")
.call(yAxisR);
context.append("path")
.datum(data)
.attr("class", "lineGreen")
.attr("d", line2);
context.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height2 + ")")
.call(xAxis2);
context.append("g")
.attr("class", "brush")
.call(brush)
.call(brush.move, x.range());
var mouseG = svg.append("g")
.attr("class", "mouse-over-effects");
svg.append("rect")
.attr("class", "zoom")
.attr("width", width)
.attr("height", height)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr('pointer-events', 'all')
.call(zoom);
function brushed() {
if (d3.event.sourceEvent && d3.event.sourceEvent.type === "zoom") return; // ignore brush-by-zoom
var s = d3.event.selection || x2.range();
x.domain(s.map(x2.invert, x2));
x3.domain(s.map(x2.invert, x2));
x4.domain(s.map(x2.invert, x2));
focus.select(".line").attr("d", line);
focus.select(".line3").attr("d", line3);
focus.select(".line4").attr("d", line4);
focus.select(".axis--x").call(xAxis);
//focus.select(".axisRed").call(xAxisR);
svg.select(".zoom").call(zoom.transform, d3.zoomIdentity
.scale(width / (s[1] - s[0]))
.translate(-s[0], 0));
}
function zoomed() {
if (d3.event.sourceEvent && d3.event.sourceEvent.type === "brush") return; // ignore zoom-by-brush
var t = d3.event.transform;
x.domain(t.rescaleX(x2).domain());
x3.domain(t.rescaleX(x2).domain());
x4.domain(t.rescaleX(x2).domain());
//y3.domain(t.rescaleY(y3).domain());
focus.select(".line").attr("d", line);
focus.select(".line3").attr("d", line3);
focus.select(".line4").attr("d", line4);
focus.select(".axis--x").call(xAxis);
//focus.select(".axis--y").call(yAxisR);
context.select(".brush").call(brush.move, x.range().map(t.invertX, t));
//context.select(".brush").call(brush.move, x3.range().map(t.invertX, t));
}
mouseG.append("path") // this is the black vertical line to follow mouse
.attr("class", "mouse-line")
.style("stroke", "black")
.style("stroke-width", "1px")
.style("opacity", "0");
var lines = focus.selectAll('path');
var mousePerLine = mouseG.selectAll('.mouse-per-line')
.data(d3.range(lines.length))
.enter()
.append("g")
.attr("class", "mouse-per-line")
.attr('pointer-events', 'none');
// the circle
mousePerLine.append("circle")
.attr("r", 7)
.style("stroke", function(d) {
return 'red';
})
.style("fill", "none")
.style("stroke-width", "1px")
.style("opacity", "0");
function showLine() {
d3.select(".mouse-line")
.style("opacity", "1");
}
function hideLine() {
d3.select(".mouse-line")
.style("opacity", "0");
}
svg.select(".zoom")
.on('mouseenter', showLine)
.on('mouseleave', hideLine)
.on('mousemove', function() { // mouse moving over canvas
var mouse = d3.mouse(this);
//showLine();
// move the vertical line
d3.select(".mouse-line")
.attr("d", function() {
var d = "M" + (mouse[0] + margin.left) + "," + (height + margin.top + 1000);
d += " " + (mouse[0] + margin.left) + "," + margin.top;
return d;
});
// position the circle and text
});
.line {
stroke: darkgreen;
clip-path: url(#clip);
fill: none;
stroke-width: 1;
shape-rendering: crispEdges;
}
.line4 {
stroke: steelblue;
clip-path: url(#clip);
fill: none;
stroke-width: 1;
shape-rendering: crispEdges;
}
.lineGreen {
stroke: darkgreen;
clip-path: url(#clip);
fill: none;
stroke-width: 1;
shape-rendering: crispEdges;
}
.line3 {
stroke: #ff0000;
clip-path: url(#clip);
fill: none;
stroke-width: 1;
shape-rendering: crispEdges;
}
.axisRed text {
fill: red;
}
.axisBlue text {
fill: steelblue;
}
.axisGreen text {
fill: darkgreen;
}
.zoom {
cursor: ew-resize;
fill: none;
pointer-events: all;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.13.0/d3.min.js"></script>
<svg width="600" height="300"></svg>
解决方案
推荐阅读
- java - IntelliJ 无法识别 JUnitRuleMockery 中的模拟方法
- javascript - Google 的标签管理器将 ```jsx 添加到我的网站,这个标签有什么用?
- c++ - c ++运算符==在链表中重载
- c++ - 避免 SPSC 队列索引的错误共享
- oracle - 尽管条件不满足,如何停止执行 oracle 触发器
- python - Python非凸优化
- python - pyArango bulkImport_json 抱怨指标不当
- java - 工具栏在通知栏下方移动
- python - 如何使用python以特定方式合并2个列表
- r - 将“lm”结果传递给“stepAIC”在脚本中有效,在函数内部失败