aboutsummaryrefslogtreecommitdiff
path: root/data/vue/Plot.vue
blob: f1f06388b99691ce281277a304c06f062ce657a8 (plain)
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
<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>