0

I have a chart with zoom. I want to add a vertical line that will follow the mouse along the graph, and display the values at the point for all the lines of the graph. Found an example d3.js v4, how do I have a line follow the mouse on hover, but also have a circle follow the path?

But when combining with my chart the following problems:

  • the line flickers or fades while moving the mouse
  • the zoom does not work with the mouse wheel (only works when the mouse is in motion)

I understand that the problem is likely that when the cursor moves, it pulls a line, and is called mouseleave event for the zoom element. I tried to move the line several pixels to the left or to the right, but this is not what I want, and it still does not work correctly.

I tried to create a line not in the mouseG element, as in the example, but on my own zoom element. The line is no longer displayed at all.

Here is my fiddle https://jsfiddle.net/zkdxrtuc/8/

ksav
  • 20,015
  • 6
  • 46
  • 66
Alexander Fresh
  • 92
  • 1
  • 2
  • 11

1 Answers1

1

Put the line group below the zoom rect.

Add second mouse event handlers to the zoom rect.

To show a line set opacity to 1, to hide set opacity to 0.

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() {
//...
}

function zoomed() {
//...
}

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.line', showLine)
  .on('mouseleave.line', hideLine)
  .on('mousemove.line', 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);
        d += " " + (mouse[0] + margin.left) + "," + margin.top;
        return d;
      });
    // position the circle and text
  });
rioV8
  • 24,506
  • 3
  • 32
  • 49
  • It was enough put the `line` group below the `zoom` and change method to set opacity. Here is working example https://jsfiddle.net/zkdxrtuc/9/ – Alexander Fresh Dec 04 '18 at 05:14