vue-plotly icon indicating copy to clipboard operation
vue-plotly copied to clipboard

[Documentation Request]: Animation

Open SumNeuron opened this issue 5 years ago • 4 comments

Please provide a minimal example of animation with your wrapper. I have data dynamically bound, but it seems to just have plotly redraw, when animation is specified in options

SumNeuron avatar Nov 28 '19 20:11 SumNeuron

Since the owner of the repo seems silent on addressing issues, i'll address two main issues here for others to reference.

Animation

As is, the component doesn't support animation. Why? Two reasons.

  1. the author of the component does not expose Plotly.animate anywhere.
  2. the author of the component explicitly uses Plotly.react to do all updating. This means if your data changes, it will call this.react() twice and since the data is now where it is would be, even if you manually call Plotly.animate you will see no animation.

How can you get around this? (for those that need a one-and-done, not a reusable solution)

  1. copy-paste the component to your own Plotly.vue file
  2. above export default add your transition specification:
const transitionSpec = {
  transition: {
    duration: 500,
    easing: 'cubic-in-out',
  },
  frame: {
    duration: 500,
    redraw: false
  }
}
  1. in the mounted lifecycle hook, change the this.$watch functions that call this.react to a function called `this.reactAnimate()
  2. in methods define a function animatePlot
animatePlot() {
      try {
        return Plotly.animate(
          this.$refs.container,
          {
            data: this.data,
            layout: this.internalLayout,
            config: {
              ...this.getOptions(),
              animationAttributes: transitionSpec, // <--- hardcoded above 
              displaylogo: false
            }
          },
        )
      }
      catch (error) {
         // maybe fall back here to this.react()
        console.log('error',  error)
      }
    },
  1. in methods define the function reactAnimate
reactAnimate() {
      let dr = this.internalLayout.datarevision
      if (dr === 1) {
        this.react()
      }
      else {
        this.animatePlot()
      }
    },

This will work because react will create a plot if it doesn't already exist. Since this component updates the data revisions, every time the data changes, if it is not the first time, it will animate instead.

If you want to make it more reusable, add a prop to the component for the animation configuration.

Resize

If you specify autoResize inside options or layout, it will not work. You need to specify on the component that you want it to resize:

<Plotly :autoResize="true"/>

This must be set on the components creation, as the function initEvents will only add a debounced resize option if set to true!

NOTE if you made my above changes for animation, you do not need to change the debounced function. Leave this as this.react so your plot will snap correctly when resizing occurs (reactAnimate will only call react once!)

SumNeuron avatar Feb 13 '20 10:02 SumNeuron

So how do you call the animation in the component? Is the plot automatically animated after adding those extra lines of codes above?

datainvestor avatar Feb 20 '20 11:02 datainvestor

Heads up, the solution posted above does not work.

datainvestor avatar Mar 13 '20 11:03 datainvestor

can someone help with this issue? would be super nice if the animation feature works!

yishiy avatar Nov 19 '20 11:11 yishiy