【问题标题】:Embed plotly fig.to_html into Vue component将 plotly fig.to_html 嵌入到 Vue 组件中
【发布时间】:2021-12-11 17:01:04
【问题描述】:

我生成了一个名为 fig 的绘图图,它在 django 模型中保存为 fig.to_html,我使用 graphql 将其导出到 Vue。

Vue 接收数据没有问题,但在显示元素时我得到的是 HTML 代码而不是图形图像。

显示图表而不是 HTML 代码的正确方法是什么?

这些是我将图表保存为 HTML 的设置:

        config = dict({
            'displayModeBar': True,
            'displaylogo': False,
            'modeBarButtonsToRemove': [
                'toImage',
                'select2d',
                'lasso2d',
            ],

        })
    
        fig.to_html(config=config, include_plotlyjs=False, full_html=False)

这是我的 Vue 组件。 signal.signalChart 是绘图的 HTML 元素:

<template>
  <div class="signal" v-if="signal">
    <h2>{{ signal.symbol }}: {{ signal.marketOpen }}</h2>
    <div>{{ displayableDate(signal.date) }}</div>
    <ul>
      <li>{{ signal.bias }}</li>
      <li>{{ signal.tradeType }}</li>
    </ul>
    <p v-html="signal.signalChart">{{ signal.signalChart }}</p>
  </div>
</template>

<script>
import gql from "graphql-tag";

export default {
  name: "Signal",
  data() {
    return {
      signal: null,
    };
  },
  async created() {
    const signal = await this.$apollo.query({
      query: gql`
        query ($slug: String!) {
          signalBySlug(slug: $slug) {
            symbol
            marketOpen
            date
            bias
            tradeType
            signalChart
          }
        }
      `,
      variables: {
        slug: this.$route.params.slug,
      },
    });
    this.signal = signal.data.signalBySlug;
  },
  methods: {
    displayableDate(date) {
      return new Intl.DateTimeFormat("en-US", { dateStyle: "full" }).format(
        new Date(date)
      );
    },
  },
};
</script>

【问题讨论】:

    标签: vue.js plotly vue-component


    【解决方案1】:

    此解决方案已提交here

    他们解决方案的后半部分确实是答案,也是我没有考虑过的。

    理论上你可以使用 watcher、ref、DOM api 和 eval() 来做你想做的事。不过,更好的方法是获取图表的数据,而不是其 html,然后使用 vue 组件安全地构建图表。

    <template>
      <div class="signal" v-if="signal">
        <h2>{{ signal.symbol }}: {{ signal.marketOpen }}</h2>
        <div>{{ displayableDate(signal.date) }}</div>
        <ul>
          <li>{{ signal.bias }}</li>
          <li>{{ signal.tradeType }}</li>
        </ul>
        <p ref="chart" v-html="signal.signalChart"></p>
      </div>
    </template>
    
    <script>
    import gql from "graphql-tag";
    import Vue from 'vue';
    
    export default {
      name: "Signal",
      data() {
        return {
          signal: null,
        };
      },
      async created() {
        const signal = await this.$apollo.query({
          query: gql`
            query ($slug: String!) {
              signalBySlug(slug: $slug) {
                symbol
                marketOpen
                date
                bias
                tradeType
                signalChart
              }
            }
          `,
          variables: {
            slug: this.$route.params.slug,
          },
        });
        this.signal = signal.data.signalBySlug;
      },
      methods: {
        displayableDate(date) {
          return new Intl.DateTimeFormat("en-US", { dateStyle: "full" }).format(
            new Date(date)
          );
        },
      },
    
      watch: {
        'signal.signalChart': {
          async handler() {
            if (this.$refs.chart) {
              await Vue.nextTick();
    
              [...this.$refs.chart.querySelectorAll('script')].forEach((scriptElement) => {
                if (scriptElement.textContent) {
                  eval(scriptElement.textContent);
                }
              })
            }
          }
        }
      }
    };
    </script>
    

    【讨论】:

      猜你喜欢
      • 2018-08-17
      • 2017-05-18
      • 2020-07-20
      • 2023-04-01
      • 2020-01-30
      • 2019-10-14
      • 2021-03-27
      • 2018-08-31
      • 2021-12-17
      相关资源
      最近更新 更多