Improve stats view

This commit is contained in:
Torjus Håkestad 2021-04-10 15:09:26 +02:00
parent 28120637e1
commit af6b022932
2 changed files with 112 additions and 6 deletions

View File

@ -1,26 +1,53 @@
<template> <template>
<div class="stats"> <div class="stats">
<h1>Stats!</h1> <h1>Stats!</h1>
<stats-username /> <b-card no-body>
<b-tabs card>
<b-tab title="Totals">
<b-card-body>
<stats-pie statType="total" />
</b-card-body>
</b-tab>
<b-tab title="Usernames">
<b-card-body>
<stats-pie statType="username" />
</b-card-body>
</b-tab>
<b-tab title="Passwords">
<b-card-body>
<stats-pie statType="password"></stats-pie>
</b-card-body>
</b-tab>
<b-tab title="Countries">
<b-card-body>
<stats-pie statType="country"></stats-pie>
</b-card-body>
</b-tab>
<b-tab title="IPs">
<b-card-body>
<stats-pie statType="ip"></stats-pie>
</b-card-body>
</b-tab>
</b-tabs>
</b-card>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator'; import { Component, Prop, Vue } from 'vue-property-decorator';
import StatsUsername from '@/components/StatsUsername.vue'; import StatsUsername from '@/components/StatsUsername.vue';
import StatsPie from '@/components/StatsPie.vue';
@Component({ @Component({
components: { components: {
StatsUsername, StatsUsername,
StatsPie,
}, },
}) })
export default class Stats extends Vue { export default class Stats extends Vue {}
@Prop() private msg!: string;
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.stats { .stats {
align-content: center; margin: 50px;
width: 70%;
} }
</style> </style>

View File

@ -0,0 +1,79 @@
<template>
<div class="stats-container" :class="containerClass">
<h2>{{ title() }}</h2>
<div class="chart-container">
<canvas id="chart" widht="400" height="400"></canvas>
</div>
</div>
</template>
<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import { StatResult } from '@/apiary/apiary';
import axios from 'axios';
import Chart from 'chart.js/auto';
import randomColor from 'randomcolor';
export type StatType = 'username' | 'password' | 'ip' | 'country' | 'total';
@Component
export default class StatsPie extends Vue {
@Prop() private statType!: StatType;
stats: StatResult[];
constructor() {
super();
this.stats = [];
}
title(): string {
if (this.statType === 'total') {
return 'Totals';
}
return `Top 10 ${this.statType}s`;
}
containerClass(): string {
return `stats-container-${this.statType}`;
}
mounted(): void {
const url = `/api/stats?type=${this.statType}&limit=10`;
axios.get<StatResult[]>(url).then((resp) => {
this.stats = resp.data;
this.renderPie();
});
}
renderPie(): void {
const elem = document.getElementById('chart') as HTMLCanvasElement;
const ctx = elem.getContext('2d') as CanvasRenderingContext2D;
const sortedStats = this.stats.sort();
const values = sortedStats.map((s) => s.count);
const headers = sortedStats.map((s) => s.name);
const colors = sortedStats.map(() => randomColor());
const chart = new Chart(ctx, {
type: 'doughnut',
data: {
labels: headers,
options: {},
datasets: [
{
data: values,
backgroundColor: colors,
},
],
},
});
}
}
</script>
<style lang="scss" scoped>
.chart-container {
max-width: 500px;
max-height: 500px;
}
</style>