Highlight multiple marks on hover in Vega

Viewed 138

I have a waterfall-like Vega graph that is constructed from vertical and horizontal rectangle marks:

enter image description here

The graph supports multiple series at once, each in different colors by id (only one is shown in the image above).

Is there a way to hightlight the entire series on hover, rather than just a single column as shown? eg. if I hover on the blue series, the whole blue series should turn firebrick. If I hover on the orange series (not shown), it should turn firebrick instead. etc.

        marks: [
          {
            type: 'group',
            from: {
              facet:
                  {data: 'datatable', name: 'curve', groupby: 'id'}
            },
            marks: [{
              type: 'rect',
              from: {data: 'curve'},
              encode: {
                update: {
                  xc: {scale: 'x', field: 'x'},
                  width: {value: 10},
                  y: {scale: 'y', field: 'y'},
                  'y2': {scale: 'y', field: 'prevY'},
                  fill: {scale: 'color', field: 'id'}
                },
                hover: {fill: {value: 'firebrick'}}
              }
            },{
              type: 'rect',
              from: {data: 'curve'},
              encode: {
                update: {
                  x: {scale: 'x', field: 'prevX'},
                  'x2': {scale: 'x', field: 'x'},
                  y: {scale: 'y', field: 'prevY'},
                  height: {value: 1},
                  fill: {scale: 'color', field: 'id'},
                },
              }
            }]
          },
        ]
1 Answers

You can use a signal to do this. First give both your marks blocks names e.g. "rect1" and "rect2", this way we can reference them. Your signal should look something like this...

{
  name: hoverSignal
  value: false
  on: [
    {
      events: @rect1:mousover, @rect2:mouseover
      update: true
    }
    {
      events: @rect1:mousout, @rect2:mouseout
      update: false
    }
  ]
}

The signal will listen to see if you move over or out of any marks associated with "rect1" or "rect2". Then within each mark block replace the fill spec with this...

{
  ...
  fill: [
    {
      test: hoverSignal
      value: firebrick
    }
    {
      scale: color
      field: id
    }
  ]
  ...
}

If the hoverSignal is true it will force the colour to firebrick. Otherwise it will just default to the last case. Make sure this is included in the update part of your encoding.

Related