路线更改时,Plotly boxplot 无法正确重新布局

Plotly boxplot not relayouting properly when route changes

我在 Vue 中使用 Plotly,当我访问新路线时,绘图无法正确呈现。只有悬停后绘图才会更改为适当的大小。当我更改为具有不同网格的另一条路线时(对于同一地块 UUID),该地块似乎有某种错误的大小,并且它溢出了容器。但是,如果我将鼠标悬停在上面,那么它似乎很好。 这是我用于绘图和重新布局的代码:

  mounted() {
    Plotly.plot(
      this.$refs[this.chartCopy.uuid],
      this.chartCopy.traces,
      this.chartCopy.layout
    );
    this.$refs[this.chartCopy.uuid].on("plotly_hover", this.hover);
    this.$refs[this.chartCopy.uuid].on("plotly_unhover", this.unhover);
  },
  watch: {
    chart: {
      handler: function () {
        Plotly.react(
          this.$refs[this.chartCopy.uuid],
          this.chartCopy.traces,
          this.chartCopy.layout
        );
      },
      deep: true,
    },
  },

在选项和布局中,我将 autosizeresponsive 设置为 true 有没有一种方法可以使绘图已经具有适当的大小(高度和宽度)而无需将鼠标悬停在它上面? 这是可以清楚地看到此行为的复制示例:

https://codesandbox.io/s/vuetify-with-plotly-20nev

任何一种重新布局都会破坏剧情的既定布局,只有悬停后才能正确。

还有一件事是我不能为 Plotly 使用 Vue 包装器(它还有其他问题),所以我必须坚持只使用 plotly.js 库。

响应图表

要使图表响应 window 大小,请将 responsive property of the config option, which is the fourth argument 设置为 Plotly.plot()

// Boxplot.vue
export default {
  mounted() {
    Plotly.plot(
      this.$refs[this.chartCopy.uuid],
      this.chartCopy.traces,
      this.chartCopy.layout,
      { responsive: true } 
    )
  }
}

重新布局

要重新布局图表,请使用 IntersectionObsesrver that calls Plotly.relayout()。这应该在 mounted 挂钩中设置并在 beforeDestroy 挂钩中拆除:

// Boxplot.vue
export default {
  mounted() {
    const chart = this.$refs[this.chartCopy.uuid]
    const intersectionObserver = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          requestIdleCallback(() => Plotly.relayout(entry.target, {}))
        }
      })
    })
    intersectionObserver.observe(chart)
    this._unobserveChart = () => intersectionObserver.unobserve(chart)
  },
  beforeDestroy() {
    this._unobserveChart()
  },
}

你使用标签来呈现路线有什么原因吗?布局实际上是无效的。 User.vue 中实际发生的是多次渲染视图。这会导致工件:

// you render same contents in all tabs many times
<v-tab-item v-for="tab of tabs" :key="tab.id" :value="tab.route">
  <router-view></router-view>
</v-tab-item>

只需使用 <router-link> 而不是制表符:

// User.vue
<template>
  <div>
    <router-link v-for="tab of tabs" :to="tab.route" :key="tab.id">
      {{ tab.name }}
    </router-link>
    <div>
      <router-view></router-view>
    </div>
  </div>
</template>

像 @tony19 提到的那样,让图表响应:

 Plotly.plot(
      this.$refs[this.chartCopy.uuid],
      this.chartCopy.traces,
      this.chartCopy.layout,
      { responsive: true }
    );

就是这样!检查 sandbox