mirror of
https://gitlab.com/wgp/dougal/software.git
synced 2025-12-06 10:27:09 +00:00
All violin plots as well as position scatter plots and histograms are shown by default. This is due to #338. For some reason, having them enabled from the get go does not cause any problems.
384 lines
8.6 KiB
Vue
384 lines
8.6 KiB
Vue
<template>
|
||
<v-card style="min-height:400px;" outlined>
|
||
<v-card-title class="headline">
|
||
Array inline / crossline error
|
||
<v-spacer></v-spacer>
|
||
<!--
|
||
<v-switch v-model="scatterplot" label="Scatterplot"></v-switch>
|
||
<v-switch class="ml-4" v-model="histogram" label="Histogram"></v-switch>
|
||
-->
|
||
</v-card-title>
|
||
|
||
<v-container fluid fill-height>
|
||
<v-row>
|
||
<v-col>
|
||
<div class="graph-container" ref="graph0"></div>
|
||
</v-col>
|
||
</v-row>
|
||
<v-row v-show="scatterplot">
|
||
<v-col>
|
||
<div class="graph-container" ref="graph1"></div>
|
||
</v-col>
|
||
</v-row>
|
||
<v-row v-show="histogram">
|
||
<v-col>
|
||
<div class="graph-container" ref="graph2"></div>
|
||
</v-col>
|
||
</v-row>
|
||
</v-container>
|
||
|
||
<v-overlay :value="busy" absolute z-index="1">
|
||
<v-progress-circular indeterminate></v-progress-circular>
|
||
</v-overlay>
|
||
</v-card>
|
||
|
||
</template>
|
||
|
||
<style scoped>
|
||
|
||
.graph-container {
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
</style>
|
||
|
||
<script>
|
||
|
||
import Plotly from 'plotly.js-dist';
|
||
import { mapActions, mapGetters } from 'vuex';
|
||
import unpack from '@/lib/unpack.js';
|
||
|
||
export default {
|
||
name: 'DougalGraphArraysIJScatter',
|
||
|
||
props: [ "data", "settings" ],
|
||
|
||
data () {
|
||
return {
|
||
graph: [],
|
||
busy: false,
|
||
resizeObserver: null,
|
||
scatterplot: true,
|
||
histogram: true
|
||
};
|
||
},
|
||
|
||
computed: {
|
||
|
||
//...mapGetters(['apiUrl'])
|
||
|
||
},
|
||
|
||
watch: {
|
||
|
||
data (newVal, oldVal) {
|
||
if (newVal === null) {
|
||
this.busy = true;
|
||
} else {
|
||
this.busy = false;
|
||
this.plot();
|
||
}
|
||
},
|
||
|
||
settings () {
|
||
for (const key in this.settings) {
|
||
this[key] = this.settings[key];
|
||
}
|
||
},
|
||
|
||
histogram () {
|
||
this.plot();
|
||
this.$emit("update:settings", {[`${this.$options.name}.histogram`]: this.histogram});
|
||
},
|
||
|
||
|
||
scatterplot () {
|
||
this.plot();
|
||
this.$emit("update:settings", {[`${this.$options.name}.scatterplot`]: this.scatterplot});
|
||
},
|
||
|
||
"$vuetify.theme.isDark" () {
|
||
this.plot();
|
||
}
|
||
},
|
||
|
||
methods: {
|
||
|
||
plot () {
|
||
|
||
this.plotSeries();
|
||
|
||
if (this.histogram) {
|
||
this.plotHistogram();
|
||
}
|
||
|
||
if (this.scatterplot) {
|
||
this.plotScatter();
|
||
}
|
||
},
|
||
|
||
plotSeries () {
|
||
if (!this.data) {
|
||
return;
|
||
}
|
||
|
||
|
||
function transform (d, idx=0, otherParams={}) {
|
||
const errortype = d.errorfinal ? "errorfinal" : "errorraw";
|
||
const coords = unpack(unpack(d, errortype), "coordinates");
|
||
const x = unpack(d, "point");
|
||
const y = unpack(coords, idx);
|
||
const data = {
|
||
type: "scatter",
|
||
mode: "lines",
|
||
x,
|
||
y,
|
||
transforms: [{
|
||
type: "groupby",
|
||
groups: unpack(unpack(d, "meta"), "src_number"),
|
||
styles: [
|
||
{target: 1, value: {line: {color: "green"}}},
|
||
{target: 2, value: {line: {color: "red"}}}
|
||
]
|
||
}],
|
||
...otherParams
|
||
};
|
||
return data;
|
||
}
|
||
|
||
const data = [
|
||
transform(this.data.items, 1, {
|
||
xaxis: 'x',
|
||
yaxis: 'y',
|
||
name: 'Crossline'
|
||
}),
|
||
transform(this.data.items, 0, {
|
||
xaxis: 'x',
|
||
yaxis: 'y2',
|
||
name: 'Inline'
|
||
})
|
||
];
|
||
this.busy = false;
|
||
|
||
const layout = {
|
||
//autosize: true,
|
||
title: {text: "Inline / crossline error – sequence %{meta.sequence}"},
|
||
autocolorscale: true,
|
||
// colorscale: "sequential",
|
||
yaxis2: {
|
||
title: "Crossline (m)",
|
||
anchor: "y2",
|
||
domain: [ 0.55, 1 ]
|
||
},
|
||
yaxis: {
|
||
title: "Inline (m)",
|
||
anchor: "y1",
|
||
domain: [ 0, 0.45 ]
|
||
},
|
||
xaxis: {
|
||
title: "Shotpoint",
|
||
anchor: "x1"
|
||
},
|
||
font: {
|
||
color: this.$vuetify.theme.isDark ? "#fff" : undefined
|
||
},
|
||
plot_bgcolor:"rgba(0,0,0,0)",
|
||
paper_bgcolor:"rgba(0,0,0,0)",
|
||
meta: this.data.meta
|
||
};
|
||
|
||
const config = {
|
||
editable: false,
|
||
displaylogo: false
|
||
};
|
||
|
||
this.graph[0] = Plotly.newPlot(this.$refs.graph0, data, layout, config);
|
||
},
|
||
|
||
plotScatter () {
|
||
|
||
console.log("plot");
|
||
|
||
if (!this.data) {
|
||
console.log("missing data");
|
||
return;
|
||
}
|
||
console.log("Will plot sequence", this.data.meta.project, this.data.meta.sequence);
|
||
|
||
function transform (d) {
|
||
const errortype = d.errorfinal ? "errorfinal" : "errorraw";
|
||
const coords = unpack(unpack(d, errortype), "coordinates");
|
||
const x = unpack(coords, 0);
|
||
const y = unpack(coords, 1);
|
||
const data = [{
|
||
type: "scatter",
|
||
mode: "markers",
|
||
x,
|
||
y,
|
||
transforms: [{
|
||
type: "groupby",
|
||
groups: unpack(unpack(d, "meta"), "src_number"),
|
||
styles: [
|
||
{target: 1, value: {line: {color: "green"}}},
|
||
{target: 2, value: {line: {color: "red"}}}
|
||
]
|
||
}]
|
||
}];
|
||
return data;
|
||
}
|
||
|
||
const data = transform(this.data.items);
|
||
this.busy = false;
|
||
|
||
const layout = {
|
||
//autosize: true,
|
||
//title: {text: "Inline / crossline error – sequence %{meta.sequence}"},
|
||
autocolorscale: true,
|
||
// colorscale: "sequential",
|
||
yaxis: {
|
||
title: "Inline (m)",
|
||
//zeroline: false
|
||
},
|
||
xaxis: {
|
||
title: "Crossline (m)"
|
||
},
|
||
font: {
|
||
color: this.$vuetify.theme.isDark ? "#fff" : undefined
|
||
},
|
||
plot_bgcolor:"rgba(0,0,0,0)",
|
||
paper_bgcolor:"rgba(0,0,0,0)",
|
||
meta: this.data.meta
|
||
};
|
||
|
||
const config = {
|
||
editable: false,
|
||
displaylogo: false
|
||
};
|
||
|
||
this.graph[1] = Plotly.newPlot(this.$refs.graph1, data, layout, config);
|
||
},
|
||
|
||
plotHistogram () {
|
||
|
||
if (!this.data) {
|
||
console.log("missing data");
|
||
return;
|
||
}
|
||
|
||
function transform (d, idx=0, otherParams={}) {
|
||
const errortype = d.errorfinal ? "errorfinal" : "errorraw";
|
||
const coords = unpack(unpack(d, errortype), "coordinates");
|
||
const x = unpack(coords, idx);
|
||
const data = {
|
||
type: "histogram",
|
||
histnorm: 'probability',
|
||
x,
|
||
transforms: [{
|
||
type: "groupby",
|
||
groups: unpack(unpack(d, "meta"), "src_number"),
|
||
styles: [
|
||
{target: 1, value: {marker: {color: "rgba(129, 199, 132, 0.9)"}}},
|
||
{target: 2, value: {marker: {color: "rgba(229, 115, 115, 0.9)"}}}
|
||
]
|
||
}],
|
||
...otherParams
|
||
};
|
||
return data;
|
||
}
|
||
|
||
const data = [
|
||
transform(this.data.items, 0, {
|
||
xaxis: 'x',
|
||
yaxis: 'y',
|
||
name: 'Crossline'
|
||
}),
|
||
transform(this.data.items, 1, {
|
||
xaxis: 'x2',
|
||
yaxis: 'y',
|
||
name: 'Inline'
|
||
})
|
||
];
|
||
|
||
const layout = {
|
||
//autosize: true,
|
||
//title: {text: "Inline / crossline error – sequence %{meta.sequence}"},
|
||
legend: {
|
||
title: { text: "Array" }
|
||
},
|
||
xaxis: {
|
||
title: "Crossline distance (m)",
|
||
domain: [ 0, 0.45 ],
|
||
anchor: 'x1'
|
||
},
|
||
yaxis: {
|
||
title: "Frequency (0‒1)",
|
||
domain: [ 0, 1 ],
|
||
anchor: 'y1'
|
||
},
|
||
xaxis2: {
|
||
title: "Inline distance (m)",
|
||
domain: [ 0.55, 1 ],
|
||
anchor: 'x2'
|
||
},
|
||
font: {
|
||
color: this.$vuetify.theme.isDark ? "#fff" : undefined
|
||
},
|
||
plot_bgcolor:"rgba(0,0,0,0)",
|
||
paper_bgcolor:"rgba(0,0,0,0)",
|
||
meta: this.data.meta
|
||
};
|
||
|
||
const config = {
|
||
editable: false,
|
||
displaylogo: false
|
||
};
|
||
this.busy = false;
|
||
console.log(data);
|
||
console.log(layout);
|
||
|
||
this.graph[2] = Plotly.newPlot(this.$refs.graph2, data, layout, config);
|
||
},
|
||
|
||
replot () {
|
||
if (!this.graph.length) {
|
||
return;
|
||
}
|
||
|
||
console.log("Replotting");
|
||
this.graph.forEach( (graph, idx) => {
|
||
const ref = this.$refs["graph"+idx];
|
||
Plotly.relayout(ref, {
|
||
width: ref.clientWidth,
|
||
height: ref.clientHeight
|
||
});
|
||
});
|
||
},
|
||
|
||
},
|
||
|
||
async mounted () {
|
||
|
||
if (this.data) {
|
||
this.plot();
|
||
} else {
|
||
this.busy = true;
|
||
}
|
||
|
||
this.resizeObserver = new ResizeObserver(this.replot)
|
||
this.resizeObserver.observe(this.$refs.graph0);
|
||
this.resizeObserver.observe(this.$refs.graph1);
|
||
this.resizeObserver.observe(this.$refs.graph2);
|
||
},
|
||
|
||
beforeDestroy () {
|
||
if (this.resizeObserver) {
|
||
this.resizeObserver.unobserve(this.$refs.graph2);
|
||
this.resizeObserver.unobserve(this.$refs.graph1);
|
||
this.resizeObserver.unobserve(this.$refs.graph0);
|
||
}
|
||
}
|
||
|
||
};
|
||
</script>
|