Skip to content

Commit d30058b

Browse files
authored
Merge pull request #28 from codeuniversity/feature/ndvi-graph
Create NDVI plots
2 parents 5379452 + 54d5e6b commit d30058b

File tree

6 files changed

+344
-57
lines changed

6 files changed

+344
-57
lines changed

frontend/src/App.vue

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<template>
22
<h1 id="app">
3-
<TestComponent />
3+
<NdviComparisonGraph />
4+
<NdviSelectMonthGraph />
5+
<NdviOverlayGraph />
46
<MedianTempGraph />
57
<MeanSoilTempGraph />
68
<MeanSoilMoistureGraph />
@@ -10,8 +12,10 @@
1012
</template>
1113

1214
<script>
13-
import TestComponent from "./components/TestComponent.vue"
14-
import MedianTempGraph from "./components/TestGraphOne.vue"
15+
import NdviComparisonGraph from "./components/NdviGraphs/NdviComparisonGraph.vue"
16+
import NdviSelectMonthGraph from "./components/NdviGraphs/NdviSelectMonthGraph.vue"
17+
import NdviOverlayGraph from "./components/NdviGraphs/NdviOverlayGraph.vue"
18+
import MedianTempGraph from "./components/MedianTempGraph.vue"
1519
import MeanSoilTempGraph from "./components/SoilTempGraph.vue"
1620
import MeanSoilMoistureGraph from "./components/SoilMoistureGraph.vue"
1721
import AugustMeanSoilTempGraph from "./components/AugustSoilTempGraph.vue"
@@ -20,14 +24,16 @@
2024
export default {
2125
name: 'App',
2226
components: {
23-
//TestComponent,
27+
NdviComparisonGraph,
28+
NdviSelectMonthGraph,
29+
NdviOverlayGraph,
2430
MedianTempGraph,
2531
MeanSoilTempGraph,
2632
MeanSoilMoistureGraph,
2733
AugustMeanSoilTempGraph,
2834
SelectMonthMeanSoilTempGraph
2935
}
30-
};
36+
}
3137
</script>
3238

3339
<style scoped></style>
File renamed without changes.
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
<template>
2+
<v-container>
3+
<h2 class="pb-10">NDVI (2018-2023)</h2>
4+
<v-row justify="center">
5+
<v-col class="py-0" style="max-width: 350px">
6+
<v-select
7+
v-model="temporalResolution"
8+
:items="temporalResolutionOptions"
9+
label="Temporal Resolution"
10+
variant="outlined"
11+
density="compact"
12+
required
13+
/>
14+
</v-col>
15+
<v-col
16+
v-if="temporalResolution !== 'Daily'"
17+
class="py-0"
18+
style="max-width: 350px"
19+
>
20+
<v-select
21+
v-model="aggregation"
22+
:items="aggregationOptions"
23+
label="Aggregation"
24+
variant="outlined"
25+
density="compact"
26+
required
27+
/>
28+
</v-col>
29+
</v-row>
30+
<v-row>
31+
<div
32+
id="plotlyGraphNdviComparison"
33+
style="width: 100%; height: 400px"
34+
class="d-flex justify-center"
35+
></div>
36+
</v-row>
37+
</v-container>
38+
</template>
39+
40+
<script>
41+
import { ref, watch, onMounted } from 'vue'
42+
import axios from 'axios'
43+
import Plotly from 'plotly.js-dist-min'
44+
45+
export default {
46+
name: 'NdviComparisonGraph',
47+
setup() {
48+
const ndviData = ref(null)
49+
const startDate = ref(1514761200) // 2018-01-01
50+
const endDate = ref(1704063599) // 2023-12-31
51+
const temporalResolution = ref("Monthly")
52+
const aggregation = ref("Mean")
53+
const temporalResolutionOptions = ["Monthly", "Daily"]
54+
const aggregationOptions = ["Mean", "Median", "Max", "Min"]
55+
56+
const fetchNdviData = async (params) => {
57+
const apiUrl = 'http://localhost:8000/index/ndvi'
58+
try {
59+
const response = await axios.get(apiUrl, { params })
60+
ndviData.value = response.data
61+
renderPlot()
62+
} catch (error) {
63+
console.error("Error fetching NDVI data:", error)
64+
}
65+
}
66+
67+
const renderPlot = () => {
68+
if (ndviData.value && ndviData.value.data) {
69+
const timestamps = ndviData.value.data.map(d => new Date(d.timestamp * 1000))
70+
const values = ndviData.value.data.map(d => d.value)
71+
const trace = {
72+
x: timestamps,
73+
y: values,
74+
mode: 'lines+markers',
75+
type: 'scatter',
76+
name: '',
77+
line: { color: 'blue' }
78+
}
79+
const layout = {
80+
title: 'NDVI of Tempelhofer Feld',
81+
xaxis: { title: '', type: 'date', rangeslider: { visible: true } },
82+
yaxis: { title: 'NDVI Value' },
83+
}
84+
Plotly.newPlot('plotlyGraphNdviComparison', [trace], layout)
85+
}
86+
}
87+
88+
const updateGraph = () => {
89+
const params = {
90+
startDate: startDate.value,
91+
endDate: endDate.value,
92+
location: "TEMPELHOFER_FELD",
93+
temporalResolution: temporalResolution.value.toUpperCase(),
94+
aggregation: aggregation.value.toUpperCase(),
95+
}
96+
fetchNdviData(params)
97+
}
98+
99+
watch([temporalResolution, aggregation], updateGraph)
100+
101+
onMounted(() => {
102+
const defaultParams = {
103+
startDate: startDate.value,
104+
endDate: endDate.value,
105+
location: "TEMPELHOFER_FELD",
106+
temporalResolution: temporalResolution.value.toUpperCase(),
107+
aggregation: aggregation.value.toUpperCase(),
108+
}
109+
fetchNdviData(defaultParams)
110+
})
111+
112+
return {
113+
ndviData,
114+
startDate,
115+
endDate,
116+
temporalResolution,
117+
aggregation,
118+
temporalResolutionOptions,
119+
aggregationOptions
120+
}
121+
}
122+
}
123+
</script>
124+
125+
<style scoped>
126+
h2 {
127+
text-align: center;
128+
}
129+
</style>
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<template>
2+
<v-container>
3+
<h2 class="pb-4">NDVI Year Overlay (2018-2023)</h2>
4+
<v-row>
5+
<div
6+
id="plotlyGraphNdviOverlay"
7+
style="width: 100%; height: 400px"
8+
class="d-flex justify-center"
9+
></div>
10+
</v-row>
11+
</v-container>
12+
</template>
13+
14+
<script>
15+
import { ref, onMounted } from 'vue'
16+
import axios from 'axios'
17+
import Plotly from 'plotly.js-dist-min'
18+
19+
export default {
20+
name: 'NdviComparisonOverlay',
21+
setup() {
22+
const ndviData = ref(null)
23+
const startDate = ref(1514761200) // 2018-01-01
24+
const endDate = ref(1704063599) // 2023-12-31
25+
const years = [2018, 2019, 2020, 2021, 2022, 2023]
26+
27+
const fetchNdviData = async (params) => {
28+
const apiUrl = 'http://localhost:8000/index/ndvi'
29+
try {
30+
const response = await axios.get(apiUrl, { params })
31+
ndviData.value = response.data
32+
renderPlot()
33+
} catch (error) {
34+
console.error("Error fetching NDVI data:", error)
35+
}
36+
}
37+
38+
const renderPlot = () => {
39+
if (ndviData.value && ndviData.value.data) {
40+
const traces = years.map(year => {
41+
const filteredData = ndviData.value.data.filter(d => new Date(d.timestamp * 1000).getFullYear() === year)
42+
43+
const months = filteredData.map(d => new Date(d.timestamp * 1000).getMonth() + 1)
44+
const values = filteredData.map(d => d.value)
45+
46+
return {
47+
x: months,
48+
y: values,
49+
mode: 'lines+markers',
50+
type: 'scatter',
51+
name: `NDVI ${year}`,
52+
line: { width: 2 },
53+
}
54+
})
55+
56+
const layout = {
57+
title: 'NDVI of Tempelhofer Feld',
58+
xaxis: {
59+
title: '',
60+
tickmode: 'array',
61+
tickvals: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12],
62+
ticktext: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
63+
},
64+
yaxis: { title: 'NDVI Value' },
65+
}
66+
67+
Plotly.newPlot('plotlyGraphNdviOverlay', traces, layout)
68+
}
69+
}
70+
71+
onMounted(() => {
72+
const params = {
73+
startDate: startDate.value,
74+
endDate: endDate.value,
75+
location: "TEMPELHOFER_FELD",
76+
temporalResolution: "MONTHLY",
77+
aggregation: "MEAN",
78+
}
79+
fetchNdviData(params)
80+
})
81+
82+
return {
83+
ndviData,
84+
years
85+
}
86+
}
87+
}
88+
</script>
89+
90+
<style scoped>
91+
h2 {
92+
text-align: center;
93+
}
94+
</style>
95+
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
<template>
2+
<v-container>
3+
<h2 class="pb-10">NDVI Monthly Means (2018-2023)</h2>
4+
<v-row justify="center">
5+
<v-col class="py-0" style="max-width: 350px">
6+
<v-select
7+
v-model="month"
8+
:items="monthOptions"
9+
label="Month"
10+
variant="outlined"
11+
density="compact"
12+
required
13+
/>
14+
</v-col>
15+
</v-row>
16+
<v-row>
17+
<div
18+
id="plotlyGraphNdviMonthly"
19+
style="width: 100%; height: 400px"
20+
class="d-flex justify-center"
21+
></div>
22+
</v-row>
23+
</v-container>
24+
</template>
25+
26+
<script>
27+
import { ref, watch, onMounted } from 'vue'
28+
import axios from 'axios'
29+
import Plotly from 'plotly.js-dist-min'
30+
31+
export default {
32+
name: 'NdviSelectMonthGraph',
33+
setup() {
34+
const ndviData = ref(null)
35+
const month = ref("January")
36+
const monthOptions = [
37+
"January", "February", "March", "April",
38+
"May", "June", "July", "August",
39+
"September", "October", "November", "December"
40+
]
41+
const startDate = ref(1514761200) // 2018-01-01
42+
const endDate = ref(1704063599) // 2023-12-31
43+
44+
const fetchNdviData = async () => {
45+
const apiUrl = 'http://localhost:8000/index/ndvi'
46+
try {
47+
const response = await axios.get(apiUrl, {
48+
params: {
49+
startDate: startDate.value,
50+
endDate: endDate.value,
51+
location: "TEMPELHOFER_FELD",
52+
temporalResolution: "MONTHLY",
53+
aggregation: "MEAN"
54+
}
55+
})
56+
ndviData.value = response.data
57+
renderPlot()
58+
} catch (error) {
59+
console.error("Error fetching NDVI data:", error)
60+
}
61+
}
62+
63+
const renderPlot = () => {
64+
if (ndviData.value && ndviData.value.data) {
65+
const monthIndex = monthOptions.indexOf(month.value) + 1
66+
const filteredData = ndviData.value.data.filter(d => new Date(d.timestamp * 1000).getMonth() + 1 === monthIndex)
67+
68+
const years = filteredData.map(d => new Date(d.timestamp * 1000).getFullYear())
69+
const values = filteredData.map(d => d.value)
70+
71+
const trace = {
72+
x: years,
73+
y: values,
74+
mode: 'lines+markers',
75+
type: 'bar',
76+
name: '',
77+
marker: { color: 'green' }
78+
}
79+
80+
const layout = {
81+
title: `NDVI of Tempelhofer Feld (${month.value})`,
82+
xaxis: { title: '' },
83+
yaxis: { title: 'NDVI Value' }
84+
}
85+
86+
Plotly.newPlot('plotlyGraphNdviMonthly', [trace], layout)
87+
}
88+
}
89+
90+
watch(month, renderPlot)
91+
92+
onMounted(() => {
93+
fetchNdviData()
94+
})
95+
96+
return {
97+
ndviData,
98+
monthOptions,
99+
month
100+
}
101+
}
102+
}
103+
</script>
104+
105+
<style scoped>
106+
h2 {
107+
text-align: center;
108+
}
109+
</style>

0 commit comments

Comments
 (0)