Skip to content

Commit 020efe9

Browse files
Merge pull request #100 from hydroserver2/161-lro
161 lro
2 parents 7b6cf4c + b8fac5b commit 020efe9

25 files changed

+492
-1080
lines changed

package-lock.json

Lines changed: 0 additions & 437 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,7 @@
1818
"@googlemaps/js-api-loader": "^1.16.6",
1919
"@googlemaps/markerclusterer": "^2.5.3",
2020
"@mdi/js": "^7.2.96",
21-
"@observablehq/plot": "^0.6.10",
2221
"country-list": "^2.3.0",
23-
"d3": "^7.8.5",
2422
"date-fns": "^2.30.0",
2523
"dotenv": "^16.0.3",
2624
"echarts": "^5.5.0",

src/components/Datastream/DatastreamTable.vue

Lines changed: 78 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,32 @@
11
<template>
2+
<h5 class="text-h5 my-6">Datastreams Available at this Site</h5>
3+
4+
<v-row class="pb-4">
5+
<v-col cols="auto" v-if="thing?.ownsThing">
6+
<v-btn-secondary
7+
prependIcon="mdi-plus"
8+
variant="elevated"
9+
:to="{ name: 'DatastreamForm', params: { id: thingId } }"
10+
>Add New Datastream</v-btn-secondary
11+
>
12+
</v-col>
13+
<v-col v-if="datastreams.length">
14+
<v-btn
15+
color="blue-grey-lighten-2"
16+
prependIcon="mdi-chart-line"
17+
variant="elevated"
18+
:to="{ name: 'VisualizeData', query: { sites: thingId } }"
19+
>View on Data Visualization Page</v-btn
20+
>
21+
</v-col>
22+
</v-row>
23+
24+
<h6 class="text-h6" style="color: #b71c1c">
25+
{{ thing?.dataDisclaimer }}
26+
</h6>
27+
228
<v-data-table
3-
class="elevation-3"
29+
class="elevation-3 my-4"
430
:headers="headers"
531
:items="visibleDatastreams"
632
v-model:sort-by="sortBy"
@@ -30,36 +56,32 @@
3056
</template>
3157

3258
<template v-slot:item.observations="{ item }">
33-
<div v-if="loaded[item.id]">
34-
<div v-if="!isOwner && !item.isDataVisible">
35-
Data is private for this datastream
36-
</div>
37-
<div v-else-if="observations[item.id]">
38-
<v-dialog v-model="item.chartOpen" width="80rem">
39-
<FocusContextPlot
40-
:thing-name="thing?.name || 'Site'"
41-
:datastream="item"
42-
@close="item.chartOpen = false"
43-
/>
44-
</v-dialog>
45-
<Sparkline
46-
@click="item.chartOpen = true"
47-
:observations="observations[item.id]"
59+
<div v-if="!isOwner && !item.isDataVisible">
60+
Data is private for this datastream
61+
</div>
62+
<div v-else>
63+
<v-dialog v-model="item.chartOpen" width="80rem">
64+
<DataVisPopupPlot
4865
:datastream="item"
66+
@close="item.chartOpen = false"
4967
/>
50-
</div>
51-
<div v-else>No data for this datastream</div>
68+
</v-dialog>
69+
<Sparkline :datastream="item" @open-chart="item.chartOpen = true" />
5270
</div>
53-
<v-progress-linear v-else color="secondary" indeterminate />
5471
</template>
5572

5673
<template v-slot:item.last_observation="{ item }">
57-
<div v-if="mostRecentObs[item.id] && (isOwner || item.isDataVisible)">
74+
<div
75+
v-if="
76+
observations[item.id]?.dataArray?.length &&
77+
(isOwner || item.isDataVisible)
78+
"
79+
>
5880
<v-row>
59-
{{ formatDate(mostRecentObs[item.id][0]) }}
81+
{{ getMostRecentObsTime(observations[item.id].dataArray) }}
6082
</v-row>
6183
<v-row>
62-
{{ mostRecentObs[item.id][1] }}&nbsp;
84+
{{ getMostRecentObsVal(observations[item.id].dataArray) }}&nbsp;
6385
{{ units.find((u) => u.id === item.unitId)?.name }}
6486
</v-row>
6587
</div>
@@ -72,7 +94,6 @@
7294
:datastream="item"
7395
:is-owner="isOwner"
7496
:thing-id="thingId"
75-
@openPlot="item.chartOpen = true"
7697
@deleted="onDeleteDatastream(item.id)"
7798
@linkUpdated="loadDatastreams"
7899
/>
@@ -81,17 +102,16 @@
81102
</template>
82103

83104
<script setup lang="ts">
84-
import FocusContextPlot from '@/components/Datastream/FocusContextPlot.vue'
85-
105+
import DataVisPopupPlot from '@/components/VisualizeData/DataVisPopupPlot.vue'
106+
import DatastreamTableActions from '@/components/Datastream/DatastreamTableActions.vue'
86107
import Sparkline from '@/components/Sparkline.vue'
87108
import { computed, onMounted, ref } from 'vue'
88109
import { useMetadata } from '@/composables/useMetadata'
89-
import { useObservationsLast72Hours } from '@/store/observations72Hours'
110+
import { useObservationStore } from '@/store/observations'
90111
import { storeToRefs } from 'pinia'
91112
import { useThingStore } from '@/store/thing'
92-
import DatastreamTableActions from '@/components/Datastream/DatastreamTableActions.vue'
93113
import { api } from '@/services/api'
94-
import { Datastream } from '@/types'
114+
import { DataArray, Datastream } from '@/types'
95115
96116
const props = defineProps({
97117
thingId: {
@@ -104,10 +124,8 @@ const props = defineProps({
104124
},
105125
})
106126
107-
const { fetchObservationsBulk } = useObservationsLast72Hours()
108-
const { loaded, observations, mostRecentObs } = storeToRefs(
109-
useObservationsLast72Hours()
110-
)
127+
const { observations } = storeToRefs(useObservationStore())
128+
111129
const { thing } = storeToRefs(useThingStore())
112130
const datastreams = ref<Datastream[]>([])
113131
const actionKey = ref(1)
@@ -116,6 +134,34 @@ const { sensors, units, observedProperties, processingLevels } = useMetadata(
116134
props.thingId
117135
)
118136
137+
const getMostRecentObsTime = (dataArray: DataArray) => {
138+
if (!dataArray.length) return undefined
139+
return formatDate(dataArray[dataArray.length - 1][0])
140+
}
141+
142+
const getMostRecentObsVal = (dataArray: DataArray) => {
143+
if (!dataArray.length) return undefined
144+
return formatNumber(dataArray[dataArray.length - 1][1])
145+
}
146+
147+
function formatDate(dateString: string) {
148+
return (
149+
new Date(dateString).toUTCString().split(' ').slice(1, 5).join(' ') + ' UTC'
150+
)
151+
}
152+
153+
const formatNumber = (value: string | number): string => {
154+
if (typeof value === 'number') {
155+
const formatter = new Intl.NumberFormat('en-US', {
156+
minimumFractionDigits: 0,
157+
maximumFractionDigits: 2,
158+
})
159+
return formatter.format(value)
160+
}
161+
162+
return value?.toString()
163+
}
164+
119165
const visibleDatastreams = computed(() => {
120166
return datastreams.value
121167
.filter((d) => d.isVisible || props.isOwner)
@@ -145,12 +191,6 @@ const headers = [
145191
{ title: 'Actions', key: 'actions', sortable: false },
146192
]
147193
148-
function formatDate(dateString: string) {
149-
return (
150-
new Date(dateString).toUTCString().split(' ').slice(1, 5).join(' ') + ' UTC'
151-
)
152-
}
153-
154194
function onDeleteDatastream(id: string) {
155195
datastreams.value = datastreams.value.filter((ds) => ds.id !== id)
156196
}
@@ -166,6 +206,5 @@ const loadDatastreams = async () => {
166206
167207
onMounted(async () => {
168208
await loadDatastreams()
169-
await fetchObservationsBulk(visibleDatastreams.value)
170209
})
171210
</script>

src/components/Datastream/DatastreamTableActions.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,10 @@
7878
v-if="datastream.isDataVisible"
7979
prepend-icon="mdi-chart-line"
8080
title="View Time Series Plot"
81-
@click="emit('openPlot')"
81+
:to="{
82+
name: 'VisualizeData',
83+
query: { sites: thingId, datastreams: datastream.id },
84+
}"
8285
/>
8386
<v-list-item
8487
v-if="datastream.isDataVisible"
@@ -149,7 +152,7 @@ const props = defineProps({
149152
},
150153
})
151154
152-
const emit = defineEmits(['openPlot', 'deleted', 'linkUpdated'])
155+
const emit = defineEmits(['deleted', 'linkUpdated'])
153156
const handleLinkUpdated = (patchBody: {}) => emit('linkUpdated', patchBody)
154157
155158
const openDelete = ref(false)

src/components/Datastream/FocusContextPlot.vue

Lines changed: 0 additions & 129 deletions
This file was deleted.

0 commit comments

Comments
 (0)