implementing snapshots

This commit is contained in:
Emily
2024-07-29 15:21:39 +02:00
parent 229c341d7a
commit 7b54c109f0
7 changed files with 133 additions and 111 deletions

View File

@@ -80,6 +80,9 @@ const { lineChartProps, lineChartRef } = useLineChart({ chartData: chartData, op
onMounted(async () => {
console.log('MOUNTED')
const c = document.createElement('canvas');
const ctx = c.getContext("2d");
let gradient: any = `${props.color}22`;
@@ -106,5 +109,5 @@ onMounted(async () => {
<template>
<LineChart ref="lineChartRef" v-bind="lineChartProps"> </LineChart>
<LineChart ref="lineChartRef" v-bind="lineChartProps"> </LineChart>
</template>

View File

@@ -1,46 +1,43 @@
<script lang="ts" setup>
import { onMounted } from 'vue';
import DateService, { type Slice } from '@services/DateService';
const data = ref<number[]>([]);
const labels = ref<string[]>([]);
const ready = ref<boolean>(false);
const props = defineProps<{ slice: Slice }>();
const { snapshot } = useSnapshot();
const slice = computed(() => props.slice);
const snapshotFrom = computed(() => {
return new Date(snapshot.value?.from || '0').toISOString();
});
const snapshotTo = computed(() => {
return new Date(snapshot.value?.to || Date.now()).toISOString();
});
async function loadData() {
ready.value = false;
const response = await useTimeline('sessions', props.slice,
snapshotFrom.value.toString(),
snapshotTo.value.toString()
);
if (!response) return;
data.value = response.map(e => e.count);
labels.value = response.map(e => DateService.getChartLabelFromISO(e._id, navigator.language, props.slice));
ready.value = true;
}
const res = useTimeline('sessions', slice);
onMounted(async () => {
await loadData();
watch(props, async () => { await loadData(); });
watch(snapshot, async () => { await loadData(); });
res.onResponse(resData => {
if (!resData.value) return;
data.value = resData.value.map(e => e.count);
labels.value = resData.value.map(e => DateService.getChartLabelFromISO(e._id, navigator.language, props.slice));
});
await res.refresh();
watch(props, () => res.refresh());
})
const chartVisible = computed(() => {
if (res.pending.value) return false;
if (!res.data.value) return false;
return true;
})
</script>
<template>
<div>
<AdvancedLineChart v-if="ready" :data="data" :labels="labels" color="#f56523"></AdvancedLineChart>
<div v-if="!chartVisible" class="flex justify-center py-40">
<i class="fas fa-spinner text-[2rem] text-accent animate-[spin_1s_linear_infinite] duration-500"></i>
</div>
<AdvancedLineChart v-if="chartVisible" :data="data" :labels="labels" color="#f56523"></AdvancedLineChart>
</div>
</template>

View File

@@ -1,6 +1,7 @@
<script lang="ts" setup>
import DateService from '@services/DateService';
import type { Slice } from '@services/DateService';
const { data: metricsInfo } = useMetricsData();
@@ -75,31 +76,41 @@ const avgSessionDuration = computed(() => {
return `${hours > 0 ? hours + 'h ' : ''}${minutes}m ${seconds.toFixed()}s`
});
const chartSlice = computed(() => {
const snapshotSizeMs = new Date(snapshot.value.to).getTime() - new Date(snapshot.value.from).getTime();
if (snapshotSizeMs < 1000 * 60 * 60 * 24 * 6) return 'hour' as Slice;
if (snapshotSizeMs < 1000 * 60 * 60 * 24 * 30) return 'day' as Slice;
if (snapshotSizeMs < 1000 * 60 * 60 * 24 * 90) return 'day' as Slice;
return 'month' as Slice;
});
async function loadData(timelineEndpointName: string, target: Data) {
target.ready = false;
const response = await useTimeline(timelineEndpointName as any, 'day',
snapshot.value?.from.toString() || "0",
snapshot.value?.to.toString() || Date.now().toString()
);
const response = useTimeline(timelineEndpointName as any, chartSlice);
console.log(timelineEndpointName,response);
response.onResponse(data => {
if (!response) return;
if (!data.value) return;
target.data = response.map(e => e.count);
target.labels = response.map(e => DateService.getChartLabelFromISO(e._id, navigator.language, 'day'));
target.data = data.value.map(e => e.count);
target.labels = data.value.map(e => DateService.getChartLabelFromISO(e._id, navigator.language, chartSlice.value));
const pool = [...response.map(e => e.count)];
pool.pop();
const avg = pool.reduce((a, e) => a + e, 0) / pool.length;
const pool = [...data.value.map(e => e.count)];
pool.pop();
const avg = pool.reduce((a, e) => a + e, 0) / pool.length;
const diffPercent: number = (100 / avg * (response.at(-1)?.count || 0)) - 100;
const diffPercent: number = (100 / avg * (data.value.at(-1)?.count || 0)) - 100;
target.trend = Math.max(Math.min(diffPercent, 99), -99);
target.trend = Math.max(Math.min(diffPercent, 99), -99);
target.ready = true;
});
response.execute();
target.ready = true;
}
@@ -113,6 +124,7 @@ async function loadAllData() {
])
}
onMounted(async () => {
await loadAllData();
@@ -137,13 +149,15 @@ onMounted(async () => {
</DashboardCountCard>
<DashboardCountCard :ready="eventsData.ready" icon="far fa-flag" text="Total custom events"
:value="formatNumberK(eventsData.data.reduce((a, e) => a + e, 0))" :avg="formatNumberK(avgEventsDay) + '/day'"
:trend="eventsData.trend" :data="eventsData.data" :labels="eventsData.labels" color="#1e9b86">
:value="formatNumberK(eventsData.data.reduce((a, e) => a + e, 0))"
:avg="formatNumberK(avgEventsDay) + '/day'" :trend="eventsData.trend" :data="eventsData.data"
:labels="eventsData.labels" color="#1e9b86">
</DashboardCountCard>
<DashboardCountCard :ready="sessionsData.ready" icon="far fa-user" text="Unique visits sessions"
:value="formatNumberK(sessionsData.data.reduce((a, e) => a + e, 0))" :avg="formatNumberK(avgSessionsDay) + '/day'"
:trend="sessionsData.trend" :data="sessionsData.data" :labels="sessionsData.labels" color="#4abde8">
:value="formatNumberK(sessionsData.data.reduce((a, e) => a + e, 0))"
:avg="formatNumberK(avgSessionsDay) + '/day'" :trend="sessionsData.trend" :data="sessionsData.data"
:labels="sessionsData.labels" color="#4abde8">
</DashboardCountCard>
<DashboardCountCard :ready="sessionsDurationData.ready" icon="far fa-timer" text="Avg session time"

View File

@@ -4,43 +4,41 @@ import DateService, { type Slice } from '@services/DateService';
const data = ref<number[]>([]);
const labels = ref<string[]>([]);
const ready = ref<boolean>(false);
const props = defineProps<{ slice: Slice }>();
const { snapshot } = useSnapshot();
const slice = computed(() => props.slice);
const snapshotFrom = computed(() => {
return new Date(snapshot.value?.from || '0').toISOString();
});
const res = useTimeline('visits', slice);
const snapshotTo = computed(() => {
return new Date(snapshot.value?.to || Date.now()).toISOString();
});
async function loadData() {
ready.value = false;
const response = await useTimeline('visits', props.slice,
snapshotFrom.value.toString(),
snapshotTo.value.toString()
);
if (!response) return;
data.value = response.map(e => e.count);
labels.value = response.map(e => DateService.getChartLabelFromISO(e._id, navigator.language, props.slice));
ready.value = true;
}
onMounted(async () => {
await loadData();
watch(props, async () => { await loadData(); });
watch(snapshot, async () => { await loadData(); });
res.onResponse(resData => {
if (!resData.value) return;
data.value = resData.value.map(e => e.count);
labels.value = resData.value.map(e => DateService.getChartLabelFromISO(e._id, navigator.language, props.slice));
});
await res.refresh();
watch(props, () => res.refresh());
})
const chartVisible = computed(() => {
if (res.pending.value) return false;
if (!res.data.value) return false;
return true;
})
</script>
<template>
<div>
<AdvancedLineChart v-if="ready" :data="data" :labels="labels" color="#5655d7"></AdvancedLineChart>
<div v-if="!chartVisible" class="flex justify-center py-40">
<i class="fas fa-spinner text-[2rem] text-accent animate-[spin_1s_linear_infinite] duration-500"></i>
</div>
<AdvancedLineChart v-if="chartVisible" :data="data" :labels="labels" color="#5655d7">
</AdvancedLineChart>
</div>
</template>