Skip to content

Commit 5379452

Browse files
authored
Merge pull request #26 from codeuniversity/feature/soil-graphs
Add soil temperature and soil moisture plots to vue frontend
2 parents 9ce30b4 + f18a63a commit 5379452

File tree

6 files changed

+606
-79
lines changed

6 files changed

+606
-79
lines changed

frontend/src/App.vue

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,30 @@
22
<h1 id="app">
33
<TestComponent />
44
<MedianTempGraph />
5+
<MeanSoilTempGraph />
6+
<MeanSoilMoistureGraph />
7+
<AugustMeanSoilTempGraph />
8+
<SelectMonthMeanSoilTempGraph />
59
</h1>
610
</template>
711

812
<script>
913
import TestComponent from "./components/TestComponent.vue"
10-
// import MedianTempGraph from "./components/TestGraphOne.vue"
14+
import MedianTempGraph from "./components/TestGraphOne.vue"
15+
import MeanSoilTempGraph from "./components/SoilTempGraph.vue"
16+
import MeanSoilMoistureGraph from "./components/SoilMoistureGraph.vue"
17+
import AugustMeanSoilTempGraph from "./components/AugustSoilTempGraph.vue"
18+
import SelectMonthMeanSoilTempGraph from "./components/SelectMonthSoilTempGraph.vue"
1119
1220
export default {
1321
name: 'App',
1422
components: {
15-
TestComponent,
16-
// MedianTempGraph
23+
//TestComponent,
24+
MedianTempGraph,
25+
MeanSoilTempGraph,
26+
MeanSoilMoistureGraph,
27+
AugustMeanSoilTempGraph,
28+
SelectMonthMeanSoilTempGraph
1729
}
1830
};
1931
</script>
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
<template>
2+
<div>
3+
<h2>Mean Soil Temperature in August</h2>
4+
5+
<!-- Plotly Chart -->
6+
<div ref="plotlyChart" style="width: 100%; height: 400px;"></div>
7+
</div>
8+
</template>
9+
10+
<script>
11+
import { ref, onMounted } from 'vue';
12+
import axios from 'axios';
13+
import Plotly from 'plotly.js-dist-min';
14+
15+
export default {
16+
name: 'MeanSoilTempGraph',
17+
setup() {
18+
const weatherData = ref(null);
19+
const plotData = ref([]);
20+
const plotlyChart = ref(null);
21+
22+
const fetchData = async () => {
23+
const apiUrl = 'http://localhost:8000/weather/index';
24+
25+
const params = {
26+
weatherVariable: "soil_temperature_0_to_7cm",
27+
startDate: new Date('2015-01-01').getTime() / 1000, // Fixed start date
28+
endDate: new Date('2023-12-31').getTime() / 1000, // Fixed end date
29+
location: "TEMPELHOFER_FELD",
30+
temporalResolution: "MONTHLY",
31+
aggregation: "MEAN",
32+
};
33+
34+
try {
35+
const response = await axios.get(apiUrl, { params });
36+
weatherData.value = response.data;
37+
processData(response.data);
38+
renderPlot();
39+
} catch (error) {
40+
console.error("Error fetching temperature data:", error);
41+
}
42+
};
43+
44+
const processData = (apiResponse) => {
45+
if (!apiResponse.data || !Array.isArray(apiResponse.data)) {
46+
console.log('Unexpected data format:', apiResponse);
47+
return;
48+
}
49+
50+
// Filter for August data (month is 7 since JavaScript months are 0-indexed)
51+
const augustData = apiResponse.data.filter(entry => {
52+
const date = new Date(entry.timestamp * 1000);
53+
return date.getMonth() === 7; // August is month 7
54+
});
55+
56+
// Extract years and temperatures for filtered data
57+
const years = augustData.map(entry =>
58+
new Date(entry.timestamp * 1000).getFullYear().toString()
59+
);
60+
const temperatures = augustData.map(entry => entry.value);
61+
62+
// Update plot data
63+
plotData.value = [
64+
{
65+
x: years,
66+
y: temperatures,
67+
type: 'bar',
68+
name: 'August Soil Temperature',
69+
marker: { color: 'darkgreen' }
70+
}
71+
];
72+
};
73+
74+
const renderPlot = () => {
75+
const layout = {
76+
title: 'Mean Soil Temperature for Tempelhofer Feld (2015 - 2023)',
77+
xaxis: { title: 'Year', type: 'category' },
78+
yaxis: { title: 'Temperature (°C)' },
79+
template: 'plotly_white'
80+
};
81+
82+
Plotly.newPlot(plotlyChart.value, plotData.value, layout);
83+
};
84+
85+
onMounted(() => {
86+
fetchData();
87+
});
88+
89+
return {
90+
weatherData,
91+
plotlyChart
92+
};
93+
}
94+
};
95+
</script>
96+
97+
<style scoped>
98+
h2 {
99+
text-align: center;
100+
margin-bottom: 10px;
101+
}
102+
</style>
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
<template>
2+
<div>
3+
<h2>Mean Soil Temperature by Month</h2>
4+
5+
<!-- Month Picker -->
6+
<div class="date-picker">
7+
8+
<label>
9+
Select Month:
10+
<select v-model="selectedMonth" @change="updateGraph">
11+
<option v-for="(month, index) in months" :key="index" :value="index">
12+
{{ month }}
13+
</option>
14+
</select>
15+
</label>
16+
</div>
17+
18+
<!-- Plotly Chart -->
19+
<div ref="plotlyChart" style="width: 100%; height: 400px;"></div>
20+
</div>
21+
</template>
22+
23+
<script>
24+
import { ref, onMounted } from 'vue';
25+
import axios from 'axios';
26+
import Plotly from 'plotly.js-dist-min';
27+
28+
export default {
29+
name: 'SelectMonthMeanSoilTempGraph',
30+
setup() {
31+
const weatherData = ref(null);
32+
const startDate = ref('2015-01-01');
33+
const endDate = ref('2023-12-31');
34+
const selectedMonth = ref(0); // Default to January (0-indexed)
35+
const months = ref([
36+
'January', 'February', 'March', 'April', 'May',
37+
'June', 'July', 'August', 'September',
38+
'October', 'November', 'December'
39+
]);
40+
const plotData = ref([]);
41+
const plotlyChart = ref(null);
42+
43+
const fetchData = async () => {
44+
const apiUrl = 'http://localhost:8000/weather/index';
45+
46+
const params = {
47+
weatherVariable: "soil_temperature_0_to_7cm",
48+
startDate: new Date(startDate.value).getTime() / 1000,
49+
endDate: new Date(endDate.value).getTime() / 1000,
50+
location: "TEMPELHOFER_FELD",
51+
temporalResolution: "MONTHLY",
52+
aggregation: "MEAN",
53+
};
54+
55+
try {
56+
const response = await axios.get(apiUrl, { params });
57+
weatherData.value = response.data;
58+
processData(response.data);
59+
renderPlot();
60+
} catch (error) {
61+
console.error("Error fetching temperature data:", error);
62+
}
63+
};
64+
65+
const processData = (apiResponse) => {
66+
if (!apiResponse.data || !Array.isArray(apiResponse.data)) {
67+
console.log('Unexpected data format:', apiResponse);
68+
return;
69+
}
70+
71+
// Filter for the selected month
72+
const filteredData = apiResponse.data.filter(entry => {
73+
const date = new Date(entry.timestamp * 1000);
74+
return date.getMonth() === selectedMonth.value;
75+
});
76+
77+
// Extract years and temperatures for the filtered data
78+
const years = filteredData.map(entry =>
79+
new Date(entry.timestamp * 1000).getFullYear().toString()
80+
);
81+
const temperatures = filteredData.map(entry => entry.value);
82+
83+
// Update plot data
84+
plotData.value = [
85+
{
86+
x: years,
87+
y: temperatures,
88+
type: 'bar',
89+
name: months.value[selectedMonth.value],
90+
marker: { color: 'darkgreen' }
91+
}
92+
];
93+
};
94+
95+
const renderPlot = () => {
96+
const layout = {
97+
title: `Mean Soil Temperature in ${months.value[selectedMonth.value]} for Tempelhofer Feld`,
98+
xaxis: { title: 'Year', type: 'category' },
99+
yaxis: { title: 'Temperature (°C)' },
100+
template: 'plotly_white'
101+
};
102+
103+
Plotly.newPlot(plotlyChart.value, plotData.value, layout);
104+
};
105+
106+
const updateGraph = () => {
107+
if (startDate.value && endDate.value) {
108+
fetchData();
109+
}
110+
};
111+
112+
onMounted(() => {
113+
fetchData();
114+
});
115+
116+
return {
117+
weatherData,
118+
startDate,
119+
endDate,
120+
selectedMonth,
121+
months,
122+
updateGraph,
123+
plotlyChart
124+
};
125+
}
126+
};
127+
</script>
128+
129+
<style scoped>
130+
h2 {
131+
text-align: center;
132+
margin-bottom: 10px;
133+
}
134+
135+
p {
136+
text-align: center;
137+
margin-bottom: 10px;
138+
}
139+
140+
.date-picker {
141+
display: flex;
142+
justify-content: center;
143+
gap: 10px;
144+
margin-bottom: 20px;
145+
}
146+
</style>

0 commit comments

Comments
 (0)