aboutsummaryrefslogtreecommitdiff
path: root/data/vue/Plot.vue
diff options
context:
space:
mode:
Diffstat (limited to 'data/vue/Plot.vue')
-rw-r--r--data/vue/Plot.vue125
1 files changed, 125 insertions, 0 deletions
diff --git a/data/vue/Plot.vue b/data/vue/Plot.vue
new file mode 100644
index 0000000..f1f0638
--- /dev/null
+++ b/data/vue/Plot.vue
@@ -0,0 +1,125 @@
+<template>
+ <div class="plot_container" :class="{ plot_maximized: maximized, plot_minimized: !maximized }">
+ <div ref="plot_ref" class="plot">
+ <button @click="plot_toggle" class="plot_button">
+ {{ maximized ? '-' : '+' }}
+ </button>
+ </div>
+ </div>
+</template>
+
+<script setup>
+import { defineProps, inject, onMounted, ref, useTemplateRef, watch } from 'vue'
+
+const props = defineProps({ section: String, name: String })
+
+const maximized = ref(false)
+
+const plots = inject('plots')
+const entries = inject('entries')
+const x_axis = inject('x_axis')
+const data = inject('data')
+
+const plot_ref = useTemplateRef('plot_ref')
+
+const plot_toggle = () => {
+ maximized.value = !maximized.value
+ Plotly.Plots.resize(plot_ref.value)
+ document.body.style.overflow = maximized.value ? 'hidden' : 'visible'
+}
+
+onMounted(() => {
+ const plot_config = plots.value[props.section][props.name]
+
+ switch (plot_config.type) {
+ case 'lines':
+ var data_defs = { mode: 'lines', line: { width: 1 }}
+ break
+ case 'stack':
+ var data_defs = { mode: 'lines', line: { width: 1 }, stackgroup: 'stackgroup' }
+ break
+ case 'stack_percent':
+ var data_defs = { mode: 'lines', line: { width: 1 }, stackgroup: 'stackgroup', groupnorm: 'percent' }
+ break
+ }
+
+ const columns = plot_config.cols
+ const data = Array.from(columns, column => ({ ...data_defs, x: [], y: [], name: column }))
+
+ Plotly.newPlot(plot_ref.value, data, {
+ legend: { font: { color: '#586e75', family: 'monospace' }, maxheight: 100, orientation: 'h' },
+ margin: { b: 32, l: 32, r: 32, t: 32 },
+ paper_bgcolor: '#002b36',
+ plot_bgcolor: '#002b36',
+ title: { font: { color: '#586e75', family: 'monospace' }, text: props.name },
+ xaxis: { gridcolor: '#073642', tickfont: { color: '#586e75' }, zerolinecolor: '#586e75' },
+ yaxis: { gridcolor: '#073642', tickfont: { color: '#586e75' }, zerolinecolor: '#586e75' },
+ }, {
+ displayModeBar: true,
+ responsive: true,
+ })
+})
+
+watch(data, new_data => {
+ const plot_config = plots.value[props.section][props.name]
+ const columns = plot_config.cols
+ const column_count = columns.length
+ const table_data = new_data.values[plot_config.table]
+ const traces = [...Array(column_count).keys()]
+ const xs = Array(column_count).fill(table_data.map(elem => elem[x_axis.value]))
+ const ys = columns.map(column => table_data.map(elem => elem[column]))
+
+ // Clear traces
+ if (new_data.redraw) {
+ const restyle = {
+ x: Array.from(columns, () => []),
+ y: Array.from(columns, () => []),
+ }
+
+ Plotly.restyle(plot_ref.value, restyle)
+ }
+
+ Plotly.extendTraces(plot_ref.value, { x: xs, y: ys }, traces, entries.value)
+})
+</script>
+
+<style>
+.plot_container {
+ background-color: #002b36;
+ display: inline-block;
+ width: 100%;
+}
+
+.plot_maximized {
+ height: 100%;
+ left: 0;
+ position: fixed;
+ top: 0;
+ z-index: 999;
+}
+
+.plot_minimized {
+ height: 400px;
+ position: relative;
+ z-index: 0;
+}
+
+.plot_button {
+ background-color: #002b36;
+ border: 1.5px solid #586e75;
+ color: #586e75;
+ cursor: pointer;
+ font-family: monospace;
+ font-size: 18px;
+ height: 26px;
+ padding: 0;
+ position: absolute;
+ right: 0;
+ top: 0;
+ width: 26px;
+}
+
+.plot {
+ height: 100%;
+}
+</style>