在Vue组件中嵌入plotly fig.to_html



我已经生成了一个名为fig的plot graph,它被保存为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组件。信号。signalChart是plotly 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>

这里给出了解决方案

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

理论上,您可以使用监视器、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>

最新更新