首页 > 解决方案 > 如何在悬停时延长跟随鼠标的垂直线

问题描述

我在将悬停时的垂直线延长两倍时遇到问题,我的目的是将两个相似的图表与穿透两个图表的垂直线进行比较(在这个例子中它暂时只包含一个图表)。但我只能稍微延长一点,终于到了极限,时间还不够长。顺便说一句,如果我想在缩放或平移时用围绕每个点的圆圈显示每个点的值,我该怎么办?

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>

标签: d3.js

解决方案


推荐阅读