Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to hide values information on hover while keeping hover events firing?

I need to customize hover interaction of graph in plotly.js. I display time series and want the hover cursor to be just a vertical line. The values below the cursor should be displayed in a table below the graph (not within the graph itself). I managed to show the vertical line cursor and displaying the values in the table below but can't figure out how to disable showing the values in the graph (I mean the tooltips like shapes with values when hovering over the graph), see the snippet.

I only find I could disable the tooltips by setting the attribute hovermode: false on the layout but then there are no hover events fired, which I need to draw the vertical line cursor.

Is there a way to achieve this?

var gd = document.getElementById('tester');
var hoverInfo = document.getElementById('hoverinfo');

var traceX = {
  name: "X",
  x: ['2001-06-11 11:50', '2001-06-12 00:00', '2001-06-12 12:30'],
  y: [35, 21, 28],
  type: 'scatter', // set the chart type
  mode: 'lines+markers',
  line: {
    width: 1
  }
};

var cursor1 = {
  xid: 1,
  type: 'line',
  // x-reference is assigned to the x-values
  xref: 'x',
  // y-reference is assigned to the plot paper [0,1]
  yref: 'paper',
  x0: '2001-06-12 12:30',
  y0: 0,
  x1: '2001-06-12 12:30',
  y1: 1,
  fillcolor: '#d3d3d3',
  opacity: 0.1,
};

var layout = {
  yaxis: {
    title: "Wind Speed",
    hoverformat: ''
  }, // set the y axis title
  xaxis: {
    showgrid: false, // remove the x-axis grid lines
    tickformat: "%B, %Y", // customize the date format to "month, day"
    hoverformat: ''
  },
  margin: { // update the left, bottom, right, top margin
    l: 40,
    b: 40,
    r: 20,
    t: 20
  },
  showline: true,
  hovermode: 'x',
  shapes: []
};

var hoverFn = function(data) {
  if (gd.layout.shapes.length === 0) {
    gd.layout.shapes.push(cursor1);
  }
  var update = {
    'shapes[0].x0': data.points[0].x,
    'shapes[0].x1': data.points[0].x
  };
  Plotly.relayout(gd, update);

  var infotext = data.points.map(function(d) {
    return (d.data.name + ': ' + d.x + ' | ' + d.y.toPrecision(3));
  });

  hoverInfo.innerHTML = infotext.join('<br/>');
};

var unhoverFn = function(data) {
  //hoverInfo.innerHTML = '';
}

var draw = function(data, layout) {

  Plotly.newPlot(gd, data, layout, {
    showLink: false,
    displaylogo: false
  });

  gd.on('plotly_click', function(data) {
      //console.log('click');
    })
    .on('plotly_beforehover', function(data) {
      //console.log('beforehover');
    })
    .on('plotly_hover', function(data) {
      //var pointNum = data.points[0].pointNumber;
      var pointNum = data;
      hoverFn(data);
    })
    .on('plotly_unhover', function(data) {
      unhoverFn(data);
    });

  Plotly.addTraces(gd, [traceX]);
};

Plotly.d3.csv('https://raw.githubusercontent.com/plotly/datasets/master/wind_speed_laurel_nebraska.csv', function(rows) {
  var data = [{
    name: 'P1',
    type: 'scatter', // set the chart type
    mode: 'lines', // connect points with lines
    x: rows.map(function(row) { // set the x-data
      return row['Time'];
    }),
    y: rows.map(function(row) { // set the x-data
      return row['10 Min Sampled Avg'];
    }),
    line: { // set the width of the line.
      width: 1
    }
  }, {
    name: 'P2',
    type: 'scatter', // set the chart type
    mode: 'lines', // connect points with lines
    x: rows.map(function(row) { // set the x-data
      return row['Time'];
    }),
    y: rows.map(function(row) { // set the x-data
      return Number(row['10 Min Sampled Avg']) + 3.0;
    }),
    line: { // set the width of the line.
      width: 1
    }
  }];

  draw(data, layout);
});
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="tester" style="width:600px;height:300px;"></div>
<div id="hoverinfo" style="margin-left:80px;"></div>
like image 751
eXavier Avatar asked Oct 18 '25 12:10

eXavier


2 Answers

Another solution is to use the hoverinfo value and set it to 'none' as seen in the reference: https://plot.ly/javascript/reference/#scatter-hoverinfo

like this:

var trace1 =
{
  x: [1, 2, 3],
  y: [40, 50, 60],
  name: 'data1',
  type: 'scatter',
  hoverinfo: 'none'
};

The advantage is that the unhover-event still fires too. If you use Plotly.Fx.hover(gd, []); instead, unhover-event will not fire.

copied from the reference: hoverinfo (flaglist string)

Any combination of "x", "y", "z", "text", "name" joined with a "+" OR "all" or "none" or "skip". examples: "x", "y", "x+y", "x+y+z", "all" default: "all" Determines which trace information appear on hover. If none or skip are set, no information is displayed upon hovering. But, if none is set, click and hover events are still fired.

like image 129
phil Avatar answered Oct 21 '25 02:10

phil


Found it. Add Plotly.Fx.hover(gd, []); into my hoverFn(). The array (2nd parameter) specifies which points to show, just leave it empty.

(Based on this example in documentation.)

var gd = document.getElementById('tester');
var hoverInfo = document.getElementById('hoverinfo');

var traceX = {
  name: "X",
  x: ['2001-06-11 11:50', '2001-06-12 00:00', '2001-06-12 12:30'],
  y: [35, 21, 28],
  type: 'scatter', // set the chart type
  mode: 'lines+markers',
  line: {
    width: 1
  }
};

var cursor1 = {
  xid: 1,
  type: 'line',
  // x-reference is assigned to the x-values
  xref: 'x',
  // y-reference is assigned to the plot paper [0,1]
  yref: 'paper',
  x0: '2001-06-12 12:30',
  y0: 0,
  x1: '2001-06-12 12:30',
  y1: 1,
  fillcolor: '#d3d3d3',
  opacity: 0.1,
};

var layout = {
  yaxis: {
    title: "Wind Speed",
    hoverformat: ''
  }, // set the y axis title
  xaxis: {
    showgrid: false, // remove the x-axis grid lines
    tickformat: "%B, %Y", // customize the date format to "month, day"
    hoverformat: ''
  },
  margin: { // update the left, bottom, right, top margin
    l: 40,
    b: 40,
    r: 20,
    t: 20
  },
  showline: true,
  hovermode: 'x',
  shapes: []
};

var hoverFn = function(data) {
  Plotly.Fx.hover(gd, []);
  if (gd.layout.shapes.length === 0) {
    gd.layout.shapes.push(cursor1);
  }
  var update = {
    'shapes[0].x0': data.points[0].x,
    'shapes[0].x1': data.points[0].x
  };
  Plotly.relayout(gd, update);

  var infotext = data.points.map(function(d) {
    return (d.data.name + ': ' + d.x + ' | ' + d.y.toPrecision(3));
  });

  hoverInfo.innerHTML = infotext.join('<br/>');
};

var unhoverFn = function(data) {
  //hoverInfo.innerHTML = '';
}

var draw = function(data, layout) {

  Plotly.newPlot(gd, data, layout, {
    showLink: false,
    displaylogo: false
  });

  gd.on('plotly_click', function(data) {
      //console.log('click');
    })
    .on('plotly_beforehover', function(data) {
      //console.log('beforehover');
    })
    .on('plotly_hover', function(data) {
      //var pointNum = data.points[0].pointNumber;
      var pointNum = data;
      hoverFn(data);
    })
    .on('plotly_unhover', function(data) {
      unhoverFn(data);
    });

  Plotly.addTraces(gd, [traceX]);
};

Plotly.d3.csv('https://raw.githubusercontent.com/plotly/datasets/master/wind_speed_laurel_nebraska.csv', function(rows) {
  var data = [{
    name: 'P1',
    type: 'scatter', // set the chart type
    mode: 'lines', // connect points with lines
    x: rows.map(function(row) { // set the x-data
      return row['Time'];
    }),
    y: rows.map(function(row) { // set the x-data
      return row['10 Min Sampled Avg'];
    }),
    line: { // set the width of the line.
      width: 1
    }
  }, {
    name: 'P2',
    type: 'scatter', // set the chart type
    mode: 'lines', // connect points with lines
    x: rows.map(function(row) { // set the x-data
      return row['Time'];
    }),
    y: rows.map(function(row) { // set the x-data
      return Number(row['10 Min Sampled Avg']) + 3.0;
    }),
    line: { // set the width of the line.
      width: 1
    }
  }];

  draw(data, layout);
});
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<div id="tester" style="width:600px;height:300px;"></div>
<div id="hoverinfo" style="margin-left:80px;"></div>
like image 26
eXavier Avatar answered Oct 21 '25 02:10

eXavier