Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DataViewer Pagination #113

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
26 changes: 26 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"@vue-leaflet/vue-leaflet": "^0.10.1",
"leaflet": "^1.9.4",
"leaflet.markercluster": "^1.5.3",
"lodash.debounce": "^4.0.8",
"pinia": "^2.2.4",
"plotly.js-cartesian-dist-min": "^2.35.2",
"vue": "^3.5.12",
Expand All @@ -46,6 +47,8 @@
"@types/jsdom": "^21.1.7",
"@types/leaflet": "^1.9.14",
"@types/leaflet.markercluster": "^1.5.5",
"@types/lodash": "^4.17.15",
"@types/lodash.debounce": "^4.0.9",
"@types/node": "^20.17.0",
"@vitejs/plugin-vue": "^5.1.4",
"@vitest/eslint-plugin": "1.1.7",
Expand Down
9 changes: 7 additions & 2 deletions src/components/ChartDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
class="pa-4 scroll">

<v-row justify="end">
<v-btn variant="text" color="pink" icon @click="open = !open">
<v-btn variant="text" color="pink" icon @click="handleClose">
<v-icon icon="mdi-close"> </v-icon>
</v-btn>
</v-row>
Expand All @@ -25,7 +25,7 @@

<v-progress-linear v-if="loading" indeterminate color="primary" />

<v-responsive height="590">
<v-responsive height="620">
<DataViewer :datastreams="datastreams" :topic="topic" :selected-station="selectedStation" />
</v-responsive>
</v-card>
Expand Down Expand Up @@ -64,6 +64,7 @@ export default defineComponent({
required: true
}
},
emits: ["toggleDataset"],
methods: {
async fetchDatastreams() {
this.loading = true;
Expand Down Expand Up @@ -101,6 +102,10 @@ export default defineComponent({
this.loading = false;
}
},
handleClose: function() {
this.$emit('toggleDataset');
this.open = false;
}
},
async mounted() {
await this.fetchDatastreams();
Expand Down
74 changes: 44 additions & 30 deletions src/components/data/DataPlotter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@

<template id="data-plotter">
<div class="data-plotter">
<v-card min-height="500px" class="ma-4">
<v-card min-height="470px" class="ma-4">
<v-progress-linear striped indeterminate color="primary" v-if="loading" />
<div :style="{ visibility: !loading ? 'visible' : 'hidden' }">
<div>
<v-card class="mx-auto" flat>
<div :id="'plotly-chart-' + selectedStation.id" />
</v-card>
Expand All @@ -20,8 +20,8 @@ import { defineComponent, type PropType } from "vue";
import { mdiOpenInNew } from "@mdi/js";
import { catchAndDisplayError } from "@/lib/errors";
import type { Trace, Datastreams, Feature, ItemsResponse } from "@/lib/types";
import { clean, fetchWithToken, getColumnFromKey } from "@/lib/helpers";
import { t } from "@/locales/i18n"
import { clean, getColumnFromKey } from "@/lib/helpers";
import { t } from "@/locales/i18n";

export default defineComponent({
props: {
Expand All @@ -36,15 +36,41 @@ export default defineComponent({
selectedDatastream: {
type: Object as PropType<Datastreams[0]>,
required: true,
},
itemsResponse: {
type: Object as PropType<ItemsResponse>,
required: true
},
itemsResponseUrl: {
type: String,
required: true,
},
loading: {
type: Boolean,
required: true,
}
},
mounted: function () {
this.loadObservations();
computed: {
combinedProps() {
return {
selectedDatastream: this.selectedDatastream,
itemsResponse: this.itemsResponse,
itemsResponseUrl: this.itemsResponseUrl,
};
},
},
watch: {
selectedDatastream: function () {
this.loadObservations();
}
combinedProps: function () {
this.generatePlot();
},
itemsResponse: {
handler: function () {
this.generatePlot();
}, deep: true
},
},
mounted: function () {
this.generatePlot();
},
data: function () {
return {
Expand All @@ -70,7 +96,6 @@ export default defineComponent({
name: "",
},
data: [] as Trace[],
loading: false,
layout: {
title: "",
xaxis: {
Expand Down Expand Up @@ -112,15 +137,15 @@ export default defineComponent({
},
methods: {
plot() {
this.loading = true;
this.$emit('loading', true);
const plot = document.getElementById(
"plotly-chart-" + this.selectedStation.id
);
if (plot !== null) {
Plotly.purge(plot);
}
Plotly.newPlot(plot, this.data, this.layout, this.config);
this.loading = false;
this.$emit('loading', false);
},
getColumnFromKey,
newTrace(features: Feature[], xAxis: keyof Feature["properties"], yAxis: keyof Feature["properties"]) {
Expand All @@ -138,23 +163,14 @@ export default defineComponent({
const lastreportTime = lastFeature?.properties.reportTime;
this.setDateLayout(lastreportTime || '');
},
async loadObservations() {
generatePlot() {
if (!Object.keys(this.itemsResponse).length || !this.itemsResponseUrl.length) {
return;
}

this.data = [];
this.loading = true;
try {
const url = `${window.VUE_APP_OAPI}/collections/${this.topic}/items?f=json&name=${this.selectedDatastream.name}&reportId=${this.selectedDatastream.reportId}&wigos_station_identifier=${this.selectedStation.id}&sortby=reportTime`;

let response
try {
response = await fetchWithToken(url);
}
catch (error) {
catchAndDisplayError(String(error), undefined, response?.status);
return;
}

const data: ItemsResponse = await response.json();
const dataURL = response.url;
this.config.modeBarButtonsToAdd = [{
name: t("chart.data_source"),
icon: {
Expand All @@ -165,19 +181,17 @@ export default defineComponent({
click: () => {
const [start, end] = this.layout.xaxis.range;
const timeExtent = `${new Date(start + "Z").toISOString()}/${new Date(end + "Z").toISOString()}`;
window.location.href = `${dataURL}&datetime=${timeExtent}`;
window.location.href = `${this.itemsResponseUrl}&datetime=${timeExtent}`;
},
}];
const xAxis = "reportTime";
const yAxis = "value";
this.newTrace(data.features, xAxis, yAxis);
this.newTrace(this.itemsResponse.features, xAxis, yAxis);
this.layout.yaxis.title = this.selectedDatastream.units || '';
this.layout.title = clean(this.selectedDatastream.name || '');
this.plot();
} catch (error) {
catchAndDisplayError(String(error));
} finally {
this.loading = false;
}
},
setDateLayout(reportTime: string) {
Expand Down
71 changes: 46 additions & 25 deletions src/components/data/DataTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
-->

<template id="data-table">
<v-card min-height="500px" class="ma-4">
<v-card min-height="470px" max-height="470px" class="ma-4">
<v-progress-linear striped indeterminate color="primary" v-if="loading" />
<div>
<v-container>
Expand All @@ -12,7 +12,7 @@
</v-row>
</v-container>

<v-table v-show="title !== ''" fixed-header height="470px">
<v-table v-show="title !== ''" fixed-header height="438px">
<thead>
<tr>
<th class="text-center">
Expand Down Expand Up @@ -47,10 +47,11 @@ import { defineComponent, type PropType } from "vue";
import { mdiDownload } from "@mdi/js";
import { catchAndDisplayError } from "@/lib/errors";
import type { Datastreams, Feature, ItemsResponse } from "@/lib/types";
import { clean, fetchAllOAFFeatures, getColumnFromKey } from "@/lib/helpers";
import { clean, getColumnFromKey } from "@/lib/helpers";
import { t } from "@/locales/i18n";



export default defineComponent({
props: {
topic: {
Expand All @@ -64,15 +65,42 @@ export default defineComponent({
selectedDatastream: {
type: Object as PropType<Datastreams[0]>,
required: true,
},
itemsResponse: {
type: Object as PropType<ItemsResponse>,
required: true
},
itemsResponseUrl: {
type: String,
required: true,
},
loading: {
type: Boolean,
required: true,
}
},
mounted: function () {
this.loadObservations();
computed: {
combinedProps() {
return {
selectedDatastream: this.selectedDatastream,
itemsResponse: this.itemsResponse,
itemsResponseUrl: this.itemsResponseUrl,
};
},
features() {
return this.itemsResponse.features
}
},
watch: {
selectedDatastream: function () {
this.loadObservations();
}
combinedProps: function () {
this.generateTable();
},
features: function () {
this.generateTable();
},
},
mounted: function () {
this.generateTable();
},
data() {
return {
Expand All @@ -81,7 +109,6 @@ export default defineComponent({
phenomenonTime: string[],
value: number[] | string[], // value can be either categorical or numerical
},
loading: false,
title: "",
headerOverflow: 0,
alert_: this.alert,
Expand Down Expand Up @@ -135,30 +162,24 @@ export default defineComponent({
},
t,
getColumnFromKey,
async loadObservations() {

this.loading = true;

generateTable() {
if (!Object.keys(this.itemsResponse).length || !this.itemsResponseUrl.length) {
return;
}

try {
const url = `${window.VUE_APP_OAPI}/collections/${this.topic}/items?f=json&name=${this.selectedDatastream.name}&reportId=${this.selectedDatastream.reportId}&wigos_station_identifier=${this.selectedStation.id}`
console.log(url)
const response = await fetchAllOAFFeatures(url);
const data: ItemsResponse = await response.json();
this.plot(response.url);
this.plot(this.itemsResponseUrl);
if (this.selectedDatastream.units === "CODE TABLE") {
this.title = clean(`${this.selectedDatastream.name}`);
this.data.value = this.getColumnFromKey(data.features, "description") as string[];
this.data.value = this.getColumnFromKey(this.itemsResponse.features, "description") as string[];
} else {
this.title = `${clean(this.selectedDatastream.name)} (${this.selectedDatastream.units})`;
this.data.value = this.getColumnFromKey(data.features, "value") as number[];
this.data.value = this.getColumnFromKey(this.itemsResponse.features, "value") as number[];
}
this.data.time = this.getColumnFromKey(data.features, "reportTime") as string[];
this.data.phenomenonTime = this.getColumnFromKey(data.features, "phenomenonTime") as string[];
this.data.time = this.getColumnFromKey(this.itemsResponse.features, "reportTime") as string[];
this.data.phenomenonTime = this.getColumnFromKey(this.itemsResponse.features, "phenomenonTime") as string[];
} catch (error) {
catchAndDisplayError(String(error));
} finally {
this.loading = false;
console.log("done");
}
},
plot(url: string) {
Expand Down
Loading