Skip to content

Commit

Permalink
feat: replace chartist with chart.js for nicer chats
Browse files Browse the repository at this point in the history
  • Loading branch information
MiniDigger committed Jan 13, 2024
1 parent 2631814 commit 880a9a0
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 197 deletions.
1 change: 1 addition & 0 deletions frontend/.npmrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
shamefully-hoist=true
strict-peer-dependencies=false
shell-emulator=false
save-exact=true
4 changes: 2 additions & 2 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@
"@vueuse/core": "10.7.1",
"accept-language-parser": "1.5.0",
"axios": "1.6.5",
"chartist": "1.3.0",
"chartist-plugin-legend": "0.6.2",
"chart.js": "4.4.1",
"debug": "4.3.4",
"diff-match-patch": "1.0.5",
"dompurify": "3.0.8",
Expand All @@ -55,6 +54,7 @@
"universal-cookie": "6.1.1",
"vue": "3.4.0-rc.3",
"vue-advanced-cropper": "2.8.8",
"vue-chartjs": "5.3.0",
"vue-i18n": "9.9.0",
"vue3-popper": "1.5.0",
"vuedraggable": "4.1.0"
Expand Down
40 changes: 26 additions & 14 deletions frontend/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

106 changes: 0 additions & 106 deletions frontend/src/components/Chart.vue

This file was deleted.

130 changes: 55 additions & 75 deletions frontend/src/pages/admin/stats.vue
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
<script lang="ts" setup>
import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router";
import { ref, watch } from "vue";
import type { LineChartData, LineChartOptions } from "chartist";
import { FixedScaleAxis } from "chartist";
import { computed, ref, watch } from "vue";
import { useHead } from "@unhead/vue";
import { Line } from "vue-chartjs";
import { CategoryScale, Chart, type ChartData, Colors, Legend, LinearScale, LineController, LineElement, PointElement, Tooltip } from "chart.js";
import { handleRequestError } from "~/composables/useErrorHandling";
import { fromISOString, toISODateString } from "~/composables/useDate";
import { useInternalApi } from "~/composables/useApi";
import Chart from "~/components/Chart.vue";
import PageTitle from "~/components/design/PageTitle.vue";
import Card from "~/components/design/Card.vue";
import InputDate from "~/components/ui/InputDate.vue";
Expand All @@ -19,11 +18,6 @@ definePageMeta({
globalPermsRequired: ["VIEW_STATS"],
});
interface DayStat {
x: Date;
y: number;
}
interface DayStats {
day: string;
flagsClosed: number;
Expand All @@ -41,82 +35,74 @@ const oneMonthBefore = new Date(now.getFullYear(), now.getMonth() - 1, now.getDa
const startDate = ref<string>(toISODateString(oneMonthBefore));
const endDate = ref<string>(toISODateString(now));
let data: DayStats[] = (await useInternalApi<DayStats[]>("admin/stats", "get", {
from: startDate.value,
to: endDate.value,
}).catch((e) => handleRequestError(e))) as DayStats[];
const data = ref<DayStats[] | void>(
await useInternalApi<DayStats[]>("admin/stats", "get", {
from: startDate.value,
to: endDate.value,
}).catch((e) => handleRequestError(e))
);
let reviews: DayStat[] = [];
let uploads: DayStat[] = [];
let totalDownloads: DayStat[] = [];
let openedFlags: DayStat[] = [];
let closedFlags: DayStat[] = [];
for (const statDay of data) {
const day = fromISOString(statDay.day);
reviews.push({ x: day, y: statDay.reviews });
uploads.push({ x: day, y: statDay.uploads });
totalDownloads.push({ x: day, y: statDay.totalDownloads });
openedFlags.push({ x: day, y: statDay.flagsOpened });
closedFlags.push({ x: day, y: statDay.flagsClosed });
}
const labels = computed(() => data.value?.map((day) => i18n.d(fromISOString(day.day), "date")));
const pluginData = ref<LineChartData>({
labels: [i18n.t("stats.reviews"), i18n.t("stats.uploads")],
series: [reviews, uploads],
const pluginData = ref<ChartData<"line", number[], string>>({
labels: labels.value,
datasets: [
{
label: i18n.t("stats.reviews"),
data: data.value?.map((day) => day.reviews) || [],
tension: 0.2,
},
{
label: i18n.t("stats.uploads"),
data: data.value?.map((day) => day.uploads) || [],
tension: 0.2,
},
],
});
const downloadData = ref<LineChartData>({
labels: [i18n.t("stats.totalDownloads")],
series: [totalDownloads],
const downloadData = ref<ChartData<"line", number[], string>>({
labels: labels.value,
datasets: [
{
label: i18n.t("stats.totalDownloads"),
data: data.value?.map((day) => day.totalDownloads) || [],
tension: 0.2,
},
],
});
const flagData = ref<LineChartData>({
labels: [i18n.t("stats.openedFlags"), i18n.t("stats.closedFlags")],
series: [openedFlags, closedFlags],
const flagData = ref<ChartData<"line", number[], string>>({
labels: labels.value,
datasets: [
{
label: i18n.t("stats.openedFlags"),
data: data.value?.map((day) => day.flagsOpened) || [],
tension: 0.2,
},
{
label: i18n.t("stats.closedFlags"),
data: data.value?.map((day) => day.flagsClosed) || [],
tension: 0.2,
},
],
});
const options: LineChartOptions = {
axisX: {
type: FixedScaleAxis,
divisor: 5,
labelInterpolationFnc: (value: string | Date) => {
return i18n.d(value, "date");
},
},
// plugins: [Chartist.plugins.legend()],
const options = {
responsive: true,
};
Chart.register(CategoryScale, LinearScale, Tooltip, Legend, PointElement, LineElement, LineController, Colors);
useHead(useSeo(i18n.t("stats.title"), null, route, null));
watch(startDate, updateDate);
watch(endDate, updateDate);
async function updateDate() {
data = (await useInternalApi<DayStats[]>("admin/stats", "get", {
data.value = (await useInternalApi<DayStats[]>("admin/stats", "get", {
from: startDate.value,
to: endDate.value,
}).catch((e) => handleRequestError(e))) as DayStats[];
if (!data) {
return;
}
reviews = [];
uploads = [];
totalDownloads = [];
openedFlags = [];
closedFlags = [];
for (const statDay of data) {
const day = fromISOString(statDay.day);
reviews.push({ x: day, y: statDay.reviews });
uploads.push({ x: day, y: statDay.uploads });
totalDownloads.push({ x: day, y: statDay.totalDownloads });
openedFlags.push({ x: day, y: statDay.flagsOpened });
closedFlags.push({ x: day, y: statDay.flagsClosed });
}
pluginData.value.series[0] = reviews;
pluginData.value.series[1] = uploads;
downloadData.value.series[0] = totalDownloads;
flagData.value.series[0] = openedFlags;
flagData.value.series[1] = closedFlags;
}
</script>

Expand All @@ -127,21 +113,15 @@ async function updateDate() {
<InputDate v-model="endDate" />
<Card class="mt-4">
<template #header> {{ i18n.t("stats.plugins") }}</template>
<client-only>
<Chart id="stats" :data="pluginData" :options="options" bar-type="Line" />
</client-only>
<Line :data="pluginData" :options="options"></Line>
</Card>
<Card class="mt-4">
<template #header>{{ i18n.t("stats.downloads") }}</template>
<client-only>
<Chart id="downloads" :data="downloadData" :options="options" bar-type="Line" />
</client-only>
<Line :data="downloadData" :options="options"></Line>
</Card>
<Card class="mt-4">
<template #header>{{ i18n.t("stats.flags") }}</template>
<client-only>
<Chart id="flags" :data="flagData" :options="options" bar-type="Line" />
</client-only>
<Line :data="flagData" :options="options"></Line>
</Card>
</div>
</template>

0 comments on commit 880a9a0

Please sign in to comment.