Search code examples
vega-lite

What's the proper way to implement a custom click handler in vega-lite


I don't seem to be able to figure this out by reading the docs. Is there a way to implement a onClick event handler for any of my marks?


Solution

  • Since Vega-Lite does not yet have support for signals, you could patch the generated Vega. You can add a signal to the compiled Vega spec and then add a signal listener through the Vega view API. You can patch the generated Vega with the patch option in Vega-Embed.

    <!DOCTYPE html>
    <head>
      <meta charset="utf-8">
      <script src="https://cdn.jsdelivr.net/npm/vega@5"></script>
        <script src="https://cdn.jsdelivr.net/npm/vega-lite@3"></script>
        <script src="https://cdn.jsdelivr.net/npm/vega-embed@4"></script>
    </head>
    
    <body>  
      <div id="vis"></div>
    
      <script>
        const spec = {
          "$schema": "https://vega.github.io/schema/vega-lite/v3.json",
          "data": {
            "values": [
              {"a": "A", "b": 28},
              {"a": "B", "b": 55},
              {"a": "C", "b": 43},
              {"a": "D", "b": 91},
              {"a": "E", "b": 81},
              {"a": "F", "b": 53},
              {"a": "G", "b": 19},
              {"a": "H", "b": 87},
              {"a": "I", "b": 52}
            ]
          },
          "mark": "bar",
          "encoding": {
            "x": {"field": "a", "type": "ordinal"},
            "y": {"field": "b", "type": "quantitative"}
          }
        };
        vegaEmbed('#vis', spec, {
          patch: (spec) => {
            spec.signals.push({
                "name": "barClick",
                "value": 0,
                "on": [{"events": "rect:mousedown", "update": "barClick + 1"}]
            })
            return spec;
          }
        }).then(result => {
            result.view.addSignalListener('barClick', console.log);
        }).catch(console.warn);
      </script>
    </body>