aboutsummaryrefslogtreecommitdiff
path: root/fe/src/lib/DataView.svelte
diff options
context:
space:
mode:
Diffstat (limited to 'fe/src/lib/DataView.svelte')
-rw-r--r--fe/src/lib/DataView.svelte228
1 files changed, 228 insertions, 0 deletions
diff --git a/fe/src/lib/DataView.svelte b/fe/src/lib/DataView.svelte
new file mode 100644
index 0000000..ffc2fe8
--- /dev/null
+++ b/fe/src/lib/DataView.svelte
@@ -0,0 +1,228 @@
1<script lang="ts">
2 import { onDestroy, onMount } from "svelte";
3 import http from "../http";
4 import { token } from "../stores/auth";
5 import { addFormOpen } from "../stores/forms";
6 import Table from "./Table.svelte";
7 import ChartJS from "chart.js/auto";
8 import Chart from './Chart.svelte'
9 import Card from "./Card.svelte";
10 import Column from "./Column.svelte";
11 import AddForm from "./forms/AddForm.svelte";
12 import { apiURL } from "../utils";
13
14 let json: Promise<any>;
15
16 let barCanvasRef: HTMLCanvasElement;
17 let lineCanvasRef: HTMLCanvasElement;
18 let barChart: any;
19 let lineChart: any;
20
21 let lastSevenDays: string[];
22 let lastSevenDaysData: number[];
23
24 let userTotalsLabels: string[];
25 let userTotalsData: number[];
26
27 async function fetchData() {
28 const res = await fetch(apiURL("stats"), {
29 method: "GET",
30 headers: {
31 Authorization: `Bearer ${$token}`
32 }
33 });
34 if (res.ok) {
35 json = res.json();
36 } else {
37 throw new Error("There was a problem with your request");
38 }
39 }
40
41 async function fetchDailyUserStatistics() {
42 const res = await fetch(apiURL("stats/daily"), {
43 method: "GET",
44 headers: {
45 Authorization: `Bearer ${$token}`
46 }
47 });
48
49 if (res.ok) {
50 const json = await res.json();
51 let labels = json.map((d: any) => d.name);
52 let data = json.map((d: any) => d.total);
53 return [labels, data];
54 } else {
55 throw new Error("There was a problem with your request");
56 }
57
58 }
59
60 async function fetchWeeklyTotals() {
61 const res = await fetch(apiURL("stats/weekly"), {
62 method: "GET",
63 headers: {
64 Authorization: `Bearer ${$token}`
65 }
66 });
67
68 if (res.ok) {
69 const json = await res.json();
70 let labels = json.map((d: any) => d.date);
71 let data = json.map((d: any) => d.total);
72 return [labels, data];
73 } else {
74 throw new Error("There was a problem with your request");
75 }
76 }
77
78 function closeDialog() {
79 addFormOpen.set(false);
80 }
81
82 function onStatisticAdd() {
83 closeDialog();
84 fetchData();
85 fetchWeeklyTotals().then(updateWeeklyTotalsChart).catch(err => console.error(err));
86 fetchDailyUserStatistics().then(updateDailyUserTotalsChart).catch(err => console.error(err));
87 }
88
89 function setupWeeklyTotalsChart(result: any) {
90 [lastSevenDays, lastSevenDaysData] = result;
91 lineChart = new ChartJS(lineCanvasRef, {
92 type: "line",
93 data: {
94 labels: lastSevenDays,
95 datasets: [
96 {
97 label: "Totals",
98 data: lastSevenDaysData,
99 backgroundColor: "rgba(255, 192, 192, 0.2)"
100 }
101 ]
102 },
103 options: {
104 responsive: true,
105 maintainAspectRatio: false,
106 scales: {
107 y: {
108 suggestedMax: 30,
109 beginAtZero: true,
110 ticks: {
111 autoSkip: true,
112 stepSize: 5
113 }
114 }
115 },
116 plugins: {
117 legend: {
118 display: false
119 },
120 title: {
121 display: true,
122 text: "Weekly Breakdown"
123 },
124 subtitle: {
125 display: true,
126 text: "Water consumption over the last week",
127 padding: {bottom: 10}
128 }
129 }
130 }
131 });
132 }
133
134 function setupDailyUserTotalsChart(result: any) {
135 [userTotalsLabels, userTotalsData] = result;
136
137 barChart = new ChartJS(barCanvasRef, {
138 type: "bar",
139 data: {
140 labels: userTotalsLabels,
141 datasets: [
142 {
143 data: userTotalsData,
144 backgroundColor: [
145 "#330000",
146 "rgba(100, 200, 192, 0.2)"
147 ]
148 }
149 ]
150 },
151 options: {
152 responsive: true,
153 maintainAspectRatio: false,
154 scales: {
155 y: {
156 beginAtZero: true,
157 suggestedMax: 10,
158 ticks: {
159 autoSkip: true,
160 stepSize: 1
161 }
162 }
163 },
164 plugins: {
165 legend: {
166 display: false
167 },
168 title: {
169 display: true,
170 text: "Daily Total"
171 },
172 subtitle: {
173 display: true,
174 text: "Water Drank Today",
175 padding: {bottom: 10}
176 }
177 }
178 }
179 });
180 }
181
182 function updateWeeklyTotalsChart(result: any) {
183 [, lastSevenDaysData] = result;
184 lineChart.data.datasets[0].data = lastSevenDaysData;
185 lineChart.update();
186 }
187
188 function updateDailyUserTotalsChart(result: any) {
189 [, userTotalsData] = result;
190 barChart.data.datasets[0].data = userTotalsData;
191 barChart.update();
192 }
193
194 onMount(() => {
195 fetchData();
196 fetchWeeklyTotals().then(setupWeeklyTotalsChart);
197 fetchDailyUserStatistics().then(setupDailyUserTotalsChart);
198 });
199
200 onDestroy(() => {
201 if (barChart) barChart.destroy();
202 if (lineChart) lineChart.destroy();
203 barChart = null;
204 lineChart = null;
205 });
206</script>
207
208<Column --width="500px">
209 <Card --height="300px">
210 <!--<Chart />-->
211 <canvas bind:this={barCanvasRef} />
212 </Card>
213 <Card --height="300px">
214 <canvas bind:this={lineCanvasRef} />
215 </Card>
216</Column>
217
218<AddForm open={$addFormOpen} on:submit={onStatisticAdd} on:close={closeDialog} />
219<Column>
220 <Card>
221 {#await json then data}
222 <Table {data} nofooter />
223 {:catch error}
224 <p>{error}</p>
225 {/await}
226 </Card>
227</Column>
228<!-- <Chart /> -->