将 plotly fig.to_html 嵌入到 Vue 组件中
Embed plotly fig.to_html into Vue component
我生成了一个名为 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 是 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>
已提出此解决方案here
他们的解决方案的后半部分确实是答案,也是我没有考虑到的。
理论上,您可以使用观察者、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>
我生成了一个名为 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 是 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>
已提出此解决方案here
他们的解决方案的后半部分确实是答案,也是我没有考虑到的。
理论上,您可以使用观察者、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>