Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
407 views
in Technique[技术] by (71.8m points)

javascript - 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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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);
    }

});


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...