简体   繁体   中英

vega-lite and vuejs - dismiss tooltip

I'm drawing a bar chart with vega-lite in a Vue.js SPA. The encoding section of the main data layer looks like this:

encoding: {
    x: {field: 'word', type: 'ordinal', sort: '-count'},
    y: {field: 'count', type: 'quantitative'},
    tooltip: [{field: 'word'}, {field: 'count'}, {field: 'doc_count'}]
  }

… and in the Vue component method that updates the chart, I have this:

vegaEmbed('#vis', spec)
   .then(({_spec, view}) => {
     view.addEventListener('click', function (event, item) {
       if (item) {  
          vueComponent.onWordClicked(item.datum.word);
          }
        })
      })

… which, to complete all of that, calls this:

onWordClicked(word) {
  this.$router.push({path: 'words', params: {word: word}});
}

All of this works exactly as I expect: you hover over a bar, a tooltip is displayed, you click the bar, and you are navigated to a different route in the SPA.

BUT… the tooltip stays on screen, unless and until you navigate back to the chart page and hover over the bars, in which case the tooltip can be reinvoked and then dismissed when you mouse out.

Any ideas on how to make the tooltip go away when the Vue path changes? I've tried playing around with the view.tooltip(...) method, but suspect that's overkill (I'm happy with the default tooltip) and may not even solve my problem.

Thanks.

So, when the route changes the component that triggered the tooltip is replaced by a different component. Your component's beforeDestroy and destroyed methods will be called and you can hook into this and clean up anything that should be cleaned up.

destroyed() { 
    // close the any open vega views. (dont know the specific of vega-embed)
}

If a components cleans up all it's side effects on destroy you can call this a well-behaved component. Side effects can be timeouts and intervals that have been set, popups and dialogs that have been opened and what not. If you want to be able to clean up you need to save the handles so you can close them later on. I'll demonstrate a well-behaved clock component:

Vue.component("clock", {
    template: `
    <div>{{time}}</div>
    
`,
    data() {
        return {
            time: null
        }
    },
    mounted() {
        // save the handle this.interval so we can clear it later on.
        this.interval = setInterval(() => {
            var d = new Date;
            this.time = d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds()
        }, 750);
    },
    destroyed() {
        clearInterval(this.interval);
    }

});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM