-
Notifications
You must be signed in to change notification settings - Fork 74
/
Plotly.vue
128 lines (126 loc) · 2.89 KB
/
Plotly.vue
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<template>
<div :id="id" v-resize:debounce.100="onResize" />
</template>
<script>
import Plotly from "plotly.js";
import events from "./events.js";
import methods from "./methods.js";
import { camelize } from "@/utils/helper";
const directives = {};
if (typeof window !== "undefined") {
directives.resize = require("vue-resize-directive");
}
export default {
name: "plotly",
inheritAttrs: false,
directives,
props: {
data: {
type: Array
},
layout: {
type: Object
},
id: {
type: String,
required: false,
default: null
}
},
data() {
return {
scheduled: null,
innerLayout: { ...this.layout }
};
},
mounted() {
Plotly.newPlot(this.$el, this.data, this.innerLayout, this.options);
events.forEach(evt => {
this.$el.on(evt.completeName, evt.handler(this));
});
},
watch: {
data: {
handler() {
this.schedule({ replot: true });
},
deep: true
},
options: {
handler(value, old) {
if (JSON.stringify(value) === JSON.stringify(old)) {
return;
}
this.schedule({ replot: true });
},
deep: true
},
layout(layout) {
this.innerLayout = { ...layout };
this.schedule({ replot: false });
}
},
computed: {
options() {
const optionsFromAttrs = Object.keys(this.$attrs).reduce((acc, key) => {
acc[camelize(key)] = this.$attrs[key];
return acc;
}, {});
return Object.assign(optionsFromAttrs, { responsive: false });
}
},
beforeDestroy() {
events.forEach(event => this.$el.removeAllListeners(event.completeName));
Plotly.purge(this.$el);
},
methods: {
...methods,
onResize() {
Plotly.Plots.resize(this.$el);
},
schedule(context) {
const { scheduled } = this;
if (scheduled) {
scheduled.replot = scheduled.replot || context.replot;
return;
}
this.scheduled = context;
this.$nextTick(() => {
const {
scheduled: { replot }
} = this;
this.scheduled = null;
if (replot) {
this.react();
return;
}
this.relayout(this.innerLayout);
});
},
toImage(options) {
const allOptions = Object.assign(this.getPrintOptions(), options);
return Plotly.toImage(this.$el, allOptions);
},
downloadImage(options) {
const filename = `plot--${new Date().toISOString()}`;
const allOptions = Object.assign(
this.getPrintOptions(),
{ filename },
options
);
return Plotly.downloadImage(this.$el, allOptions);
},
getPrintOptions() {
const { $el } = this;
return {
format: "png",
width: $el.clientWidth,
height: $el.clientHeight
};
},
react() {
Plotly.react(this.$el, this.data, this.innerLayout, this.options);
}
}
};
</script>