Refactor Chart component (#8622)
* refactor(client): refactor Chart component * Apply review suggestions from @Johann150 Co-authored-by: Johann150 <johann@qwertqwefsday.eu> * fix(client): don't expose values from Chart Co-authored-by: Johann150 <johann@qwertqwefsday.eu>
This commit is contained in:
parent
e0cce893be
commit
88307327e6
1 changed files with 789 additions and 793 deletions
|
@ -7,8 +7,13 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent, onMounted, ref, watch, PropType, onUnmounted, shallowRef } from 'vue';
|
/* eslint-disable id-denylist --
|
||||||
|
Chart.js has a `data` attribute in most chart definitions, which triggers the
|
||||||
|
id-denylist violation when setting it. This is causing about 60+ lint issues.
|
||||||
|
As this is part of Chart.js's API it makes sense to disable the check here.
|
||||||
|
*/
|
||||||
|
import { defineProps, onMounted, ref, watch, PropType, onUnmounted } from 'vue';
|
||||||
import {
|
import {
|
||||||
Chart,
|
Chart,
|
||||||
ArcElement,
|
ArcElement,
|
||||||
|
@ -36,6 +41,46 @@ import * as os from '@/os';
|
||||||
import { defaultStore } from '@/store';
|
import { defaultStore } from '@/store';
|
||||||
import MkChartTooltip from '@/components/chart-tooltip.vue';
|
import MkChartTooltip from '@/components/chart-tooltip.vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
src: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
args: {
|
||||||
|
type: Object,
|
||||||
|
required: false,
|
||||||
|
},
|
||||||
|
limit: {
|
||||||
|
type: Number,
|
||||||
|
required: false,
|
||||||
|
default: 90
|
||||||
|
},
|
||||||
|
span: {
|
||||||
|
type: String as PropType<'hour' | 'day'>,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
detailed: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
stacked: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
bar: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
aspectRatio: {
|
||||||
|
type: Number,
|
||||||
|
required: false,
|
||||||
|
default: null
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
Chart.register(
|
Chart.register(
|
||||||
ArcElement,
|
ArcElement,
|
||||||
LineElement,
|
LineElement,
|
||||||
|
@ -80,51 +125,9 @@ const getColor = (i) => {
|
||||||
return colorSets[i % colorSets.length];
|
return colorSets[i % colorSets.length];
|
||||||
};
|
};
|
||||||
|
|
||||||
export default defineComponent({
|
const now = new Date();
|
||||||
props: {
|
let chartInstance: Chart = null;
|
||||||
src: {
|
let chartData: {
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
args: {
|
|
||||||
type: Object,
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
limit: {
|
|
||||||
type: Number,
|
|
||||||
required: false,
|
|
||||||
default: 90
|
|
||||||
},
|
|
||||||
span: {
|
|
||||||
type: String as PropType<'hour' | 'day'>,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
detailed: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
stacked: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
bar: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
aspectRatio: {
|
|
||||||
type: Number,
|
|
||||||
required: false,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
setup(props) {
|
|
||||||
const now = new Date();
|
|
||||||
let chartInstance: Chart = null;
|
|
||||||
let data: {
|
|
||||||
series: {
|
series: {
|
||||||
name: string;
|
name: string;
|
||||||
type: 'line' | 'area';
|
type: 'line' | 'area';
|
||||||
|
@ -136,45 +139,45 @@ export default defineComponent({
|
||||||
y: number;
|
y: number;
|
||||||
}[];
|
}[];
|
||||||
}[];
|
}[];
|
||||||
} = null;
|
} = null;
|
||||||
|
|
||||||
const chartEl = ref<HTMLCanvasElement>(null);
|
const chartEl = ref<HTMLCanvasElement>(null);
|
||||||
const fetching = ref(true);
|
const fetching = ref(true);
|
||||||
|
|
||||||
const getDate = (ago: number) => {
|
const getDate = (ago: number) => {
|
||||||
const y = now.getFullYear();
|
const y = now.getFullYear();
|
||||||
const m = now.getMonth();
|
const m = now.getMonth();
|
||||||
const d = now.getDate();
|
const d = now.getDate();
|
||||||
const h = now.getHours();
|
const h = now.getHours();
|
||||||
|
|
||||||
return props.span === 'day' ? new Date(y, m, d - ago) : new Date(y, m, d, h - ago);
|
return props.span === 'day' ? new Date(y, m, d - ago) : new Date(y, m, d, h - ago);
|
||||||
};
|
};
|
||||||
|
|
||||||
const format = (arr) => {
|
const format = (arr) => {
|
||||||
return arr.map((v, i) => ({
|
return arr.map((v, i) => ({
|
||||||
x: getDate(i).getTime(),
|
x: getDate(i).getTime(),
|
||||||
y: v
|
y: v
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
const tooltipShowing = ref(false);
|
const tooltipShowing = ref(false);
|
||||||
const tooltipX = ref(0);
|
const tooltipX = ref(0);
|
||||||
const tooltipY = ref(0);
|
const tooltipY = ref(0);
|
||||||
const tooltipTitle = ref(null);
|
const tooltipTitle = ref(null);
|
||||||
const tooltipSeries = ref(null);
|
const tooltipSeries = ref(null);
|
||||||
let disposeTooltipComponent;
|
let disposeTooltipComponent;
|
||||||
|
|
||||||
os.popup(MkChartTooltip, {
|
os.popup(MkChartTooltip, {
|
||||||
showing: tooltipShowing,
|
showing: tooltipShowing,
|
||||||
x: tooltipX,
|
x: tooltipX,
|
||||||
y: tooltipY,
|
y: tooltipY,
|
||||||
title: tooltipTitle,
|
title: tooltipTitle,
|
||||||
series: tooltipSeries,
|
series: tooltipSeries,
|
||||||
}, {}).then(({ dispose }) => {
|
}, {}).then(({ dispose }) => {
|
||||||
disposeTooltipComponent = dispose;
|
disposeTooltipComponent = dispose;
|
||||||
});
|
});
|
||||||
|
|
||||||
function externalTooltipHandler(context) {
|
function externalTooltipHandler(context) {
|
||||||
if (context.tooltip.opacity === 0) {
|
if (context.tooltip.opacity === 0) {
|
||||||
tooltipShowing.value = false;
|
tooltipShowing.value = false;
|
||||||
return;
|
return;
|
||||||
|
@ -192,9 +195,9 @@ export default defineComponent({
|
||||||
tooltipShowing.value = true;
|
tooltipShowing.value = true;
|
||||||
tooltipX.value = rect.left + window.pageXOffset + context.tooltip.caretX;
|
tooltipX.value = rect.left + window.pageXOffset + context.tooltip.caretX;
|
||||||
tooltipY.value = rect.top + window.pageYOffset + context.tooltip.caretY;
|
tooltipY.value = rect.top + window.pageYOffset + context.tooltip.caretY;
|
||||||
}
|
}
|
||||||
|
|
||||||
const render = () => {
|
const render = () => {
|
||||||
if (chartInstance) {
|
if (chartInstance) {
|
||||||
chartInstance.destroy();
|
chartInstance.destroy();
|
||||||
}
|
}
|
||||||
|
@ -205,13 +208,13 @@ export default defineComponent({
|
||||||
// フォントカラー
|
// フォントカラー
|
||||||
Chart.defaults.color = getComputedStyle(document.documentElement).getPropertyValue('--fg');
|
Chart.defaults.color = getComputedStyle(document.documentElement).getPropertyValue('--fg');
|
||||||
|
|
||||||
const maxes = data.series.map((x, i) => Math.max(...x.data.map(d => d.y)));
|
const maxes = chartData.series.map((x, i) => Math.max(...x.data.map(d => d.y)));
|
||||||
|
|
||||||
chartInstance = new Chart(chartEl.value, {
|
chartInstance = new Chart(chartEl.value, {
|
||||||
type: props.bar ? 'bar' : 'line',
|
type: props.bar ? 'bar' : 'line',
|
||||||
data: {
|
data: {
|
||||||
labels: new Array(props.limit).fill(0).map((_, i) => getDate(i).toLocaleString()).slice().reverse(),
|
labels: new Array(props.limit).fill(0).map((_, i) => getDate(i).toLocaleString()).slice().reverse(),
|
||||||
datasets: data.series.map((x, i) => ({
|
datasets: chartData.series.map((x, i) => ({
|
||||||
parsing: false,
|
parsing: false,
|
||||||
label: x.name,
|
label: x.name,
|
||||||
data: x.data.slice().reverse(),
|
data: x.data.slice().reverse(),
|
||||||
|
@ -367,13 +370,13 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
}]
|
}]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const exportData = () => {
|
const exportData = () => {
|
||||||
// TODO
|
// TODO
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchFederationChart = async (): Promise<typeof data> => {
|
const fetchFederationChart = async (): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/federation', { limit: props.limit, span: props.span });
|
const raw = await os.api('charts/federation', { limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [{
|
series: [{
|
||||||
|
@ -421,9 +424,9 @@ export default defineComponent({
|
||||||
color: colors.orange,
|
color: colors.orange,
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchApRequestChart = async (): Promise<typeof data> => {
|
const fetchApRequestChart = async (): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/ap-request', { limit: props.limit, span: props.span });
|
const raw = await os.api('charts/ap-request', { limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [{
|
series: [{
|
||||||
|
@ -443,15 +446,15 @@ export default defineComponent({
|
||||||
data: format(raw.deliverFailed)
|
data: format(raw.deliverFailed)
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchNotesChart = async (type: string): Promise<typeof data> => {
|
const fetchNotesChart = async (type: string): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/notes', { limit: props.limit, span: props.span });
|
const raw = await os.api('charts/notes', { limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [{
|
series: [{
|
||||||
name: 'All',
|
name: 'All',
|
||||||
type: 'line',
|
type: 'line',
|
||||||
data: format(type == 'combined'
|
data: format(type === 'combined'
|
||||||
? sum(raw.local.inc, negate(raw.local.dec), raw.remote.inc, negate(raw.remote.dec))
|
? sum(raw.local.inc, negate(raw.local.dec), raw.remote.inc, negate(raw.remote.dec))
|
||||||
: sum(raw[type].inc, negate(raw[type].dec))
|
: sum(raw[type].inc, negate(raw[type].dec))
|
||||||
),
|
),
|
||||||
|
@ -459,7 +462,7 @@ export default defineComponent({
|
||||||
}, {
|
}, {
|
||||||
name: 'Renotes',
|
name: 'Renotes',
|
||||||
type: 'area',
|
type: 'area',
|
||||||
data: format(type == 'combined'
|
data: format(type === 'combined'
|
||||||
? sum(raw.local.diffs.renote, raw.remote.diffs.renote)
|
? sum(raw.local.diffs.renote, raw.remote.diffs.renote)
|
||||||
: raw[type].diffs.renote
|
: raw[type].diffs.renote
|
||||||
),
|
),
|
||||||
|
@ -467,7 +470,7 @@ export default defineComponent({
|
||||||
}, {
|
}, {
|
||||||
name: 'Replies',
|
name: 'Replies',
|
||||||
type: 'area',
|
type: 'area',
|
||||||
data: format(type == 'combined'
|
data: format(type === 'combined'
|
||||||
? sum(raw.local.diffs.reply, raw.remote.diffs.reply)
|
? sum(raw.local.diffs.reply, raw.remote.diffs.reply)
|
||||||
: raw[type].diffs.reply
|
: raw[type].diffs.reply
|
||||||
),
|
),
|
||||||
|
@ -475,7 +478,7 @@ export default defineComponent({
|
||||||
}, {
|
}, {
|
||||||
name: 'Normal',
|
name: 'Normal',
|
||||||
type: 'area',
|
type: 'area',
|
||||||
data: format(type == 'combined'
|
data: format(type === 'combined'
|
||||||
? sum(raw.local.diffs.normal, raw.remote.diffs.normal)
|
? sum(raw.local.diffs.normal, raw.remote.diffs.normal)
|
||||||
: raw[type].diffs.normal
|
: raw[type].diffs.normal
|
||||||
),
|
),
|
||||||
|
@ -483,16 +486,16 @@ export default defineComponent({
|
||||||
}, {
|
}, {
|
||||||
name: 'With file',
|
name: 'With file',
|
||||||
type: 'area',
|
type: 'area',
|
||||||
data: format(type == 'combined'
|
data: format(type === 'combined'
|
||||||
? sum(raw.local.diffs.withFile, raw.remote.diffs.withFile)
|
? sum(raw.local.diffs.withFile, raw.remote.diffs.withFile)
|
||||||
: raw[type].diffs.withFile
|
: raw[type].diffs.withFile
|
||||||
),
|
),
|
||||||
color: colors.purple,
|
color: colors.purple,
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchNotesTotalChart = async (): Promise<typeof data> => {
|
const fetchNotesTotalChart = async (): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/notes', { limit: props.limit, span: props.span });
|
const raw = await os.api('charts/notes', { limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [{
|
series: [{
|
||||||
|
@ -509,9 +512,9 @@ export default defineComponent({
|
||||||
data: format(raw.remote.total),
|
data: format(raw.remote.total),
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchUsersChart = async (total: boolean): Promise<typeof data> => {
|
const fetchUsersChart = async (total: boolean): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/users', { limit: props.limit, span: props.span });
|
const raw = await os.api('charts/users', { limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [{
|
series: [{
|
||||||
|
@ -537,9 +540,9 @@ export default defineComponent({
|
||||||
),
|
),
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchActiveUsersChart = async (): Promise<typeof data> => {
|
const fetchActiveUsersChart = async (): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/active-users', { limit: props.limit, span: props.span });
|
const raw = await os.api('charts/active-users', { limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [{
|
series: [{
|
||||||
|
@ -589,9 +592,9 @@ export default defineComponent({
|
||||||
color: colors.purple,
|
color: colors.purple,
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchDriveChart = async (): Promise<typeof data> => {
|
const fetchDriveChart = async (): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/drive', { limit: props.limit, span: props.span });
|
const raw = await os.api('charts/drive', { limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
bytes: true,
|
bytes: true,
|
||||||
|
@ -625,9 +628,9 @@ export default defineComponent({
|
||||||
data: format(negate(raw.remote.decSize)),
|
data: format(negate(raw.remote.decSize)),
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchDriveFilesChart = async (): Promise<typeof data> => {
|
const fetchDriveFilesChart = async (): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/drive', { limit: props.limit, span: props.span });
|
const raw = await os.api('charts/drive', { limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [{
|
series: [{
|
||||||
|
@ -660,9 +663,9 @@ export default defineComponent({
|
||||||
data: format(negate(raw.remote.decCount)),
|
data: format(negate(raw.remote.decCount)),
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchInstanceRequestsChart = async (): Promise<typeof data> => {
|
const fetchInstanceRequestsChart = async (): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/instance', { host: props.args.host, limit: props.limit, span: props.span });
|
const raw = await os.api('charts/instance', { host: props.args.host, limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [{
|
series: [{
|
||||||
|
@ -682,9 +685,9 @@ export default defineComponent({
|
||||||
data: format(raw.requests.failed)
|
data: format(raw.requests.failed)
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchInstanceUsersChart = async (total: boolean): Promise<typeof data> => {
|
const fetchInstanceUsersChart = async (total: boolean): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/instance', { host: props.args.host, limit: props.limit, span: props.span });
|
const raw = await os.api('charts/instance', { host: props.args.host, limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [{
|
series: [{
|
||||||
|
@ -697,9 +700,9 @@ export default defineComponent({
|
||||||
)
|
)
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchInstanceNotesChart = async (total: boolean): Promise<typeof data> => {
|
const fetchInstanceNotesChart = async (total: boolean): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/instance', { host: props.args.host, limit: props.limit, span: props.span });
|
const raw = await os.api('charts/instance', { host: props.args.host, limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [{
|
series: [{
|
||||||
|
@ -712,9 +715,9 @@ export default defineComponent({
|
||||||
)
|
)
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchInstanceFfChart = async (total: boolean): Promise<typeof data> => {
|
const fetchInstanceFfChart = async (total: boolean): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/instance', { host: props.args.host, limit: props.limit, span: props.span });
|
const raw = await os.api('charts/instance', { host: props.args.host, limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [{
|
series: [{
|
||||||
|
@ -735,9 +738,9 @@ export default defineComponent({
|
||||||
)
|
)
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchInstanceDriveUsageChart = async (total: boolean): Promise<typeof data> => {
|
const fetchInstanceDriveUsageChart = async (total: boolean): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/instance', { host: props.args.host, limit: props.limit, span: props.span });
|
const raw = await os.api('charts/instance', { host: props.args.host, limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
bytes: true,
|
bytes: true,
|
||||||
|
@ -751,9 +754,9 @@ export default defineComponent({
|
||||||
)
|
)
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchInstanceDriveFilesChart = async (total: boolean): Promise<typeof data> => {
|
const fetchInstanceDriveFilesChart = async (total: boolean): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/instance', { host: props.args.host, limit: props.limit, span: props.span });
|
const raw = await os.api('charts/instance', { host: props.args.host, limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [{
|
series: [{
|
||||||
|
@ -766,9 +769,9 @@ export default defineComponent({
|
||||||
)
|
)
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchPerUserNotesChart = async (): Promise<typeof data> => {
|
const fetchPerUserNotesChart = async (): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/user/notes', { userId: props.args.user.id, limit: props.limit, span: props.span });
|
const raw = await os.api('charts/user/notes', { userId: props.args.user.id, limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [...(props.args.withoutAll ? [] : [{
|
series: [...(props.args.withoutAll ? [] : [{
|
||||||
|
@ -798,9 +801,9 @@ export default defineComponent({
|
||||||
color: colors.blue,
|
color: colors.blue,
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchPerUserFollowingChart = async (): Promise<typeof data> => {
|
const fetchPerUserFollowingChart = async (): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/user/following', { userId: props.args.user.id, limit: props.limit, span: props.span });
|
const raw = await os.api('charts/user/following', { userId: props.args.user.id, limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [{
|
series: [{
|
||||||
|
@ -813,9 +816,9 @@ export default defineComponent({
|
||||||
data: format(raw.remote.followings.total),
|
data: format(raw.remote.followings.total),
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchPerUserFollowersChart = async (): Promise<typeof data> => {
|
const fetchPerUserFollowersChart = async (): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/user/following', { userId: props.args.user.id, limit: props.limit, span: props.span });
|
const raw = await os.api('charts/user/following', { userId: props.args.user.id, limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [{
|
series: [{
|
||||||
|
@ -828,9 +831,9 @@ export default defineComponent({
|
||||||
data: format(raw.remote.followers.total),
|
data: format(raw.remote.followers.total),
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchPerUserDriveChart = async (): Promise<typeof data> => {
|
const fetchPerUserDriveChart = async (): Promise<typeof chartData> => {
|
||||||
const raw = await os.api('charts/user/drive', { userId: props.args.user.id, limit: props.limit, span: props.span });
|
const raw = await os.api('charts/user/drive', { userId: props.args.user.id, limit: props.limit, span: props.span });
|
||||||
return {
|
return {
|
||||||
series: [{
|
series: [{
|
||||||
|
@ -843,9 +846,9 @@ export default defineComponent({
|
||||||
data: format(raw.decSize),
|
data: format(raw.decSize),
|
||||||
}],
|
}],
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const fetchAndRender = async () => {
|
const fetchAndRender = async () => {
|
||||||
const fetchData = () => {
|
const fetchData = () => {
|
||||||
switch (props.src) {
|
switch (props.src) {
|
||||||
case 'federation': return fetchFederationChart();
|
case 'federation': return fetchFederationChart();
|
||||||
|
@ -859,7 +862,6 @@ export default defineComponent({
|
||||||
case 'notes-total': return fetchNotesTotalChart();
|
case 'notes-total': return fetchNotesTotalChart();
|
||||||
case 'drive': return fetchDriveChart();
|
case 'drive': return fetchDriveChart();
|
||||||
case 'drive-files': return fetchDriveFilesChart();
|
case 'drive-files': return fetchDriveFilesChart();
|
||||||
|
|
||||||
case 'instance-requests': return fetchInstanceRequestsChart();
|
case 'instance-requests': return fetchInstanceRequestsChart();
|
||||||
case 'instance-users': return fetchInstanceUsersChart(false);
|
case 'instance-users': return fetchInstanceUsersChart(false);
|
||||||
case 'instance-users-total': return fetchInstanceUsersChart(true);
|
case 'instance-users-total': return fetchInstanceUsersChart(true);
|
||||||
|
@ -879,27 +881,21 @@ export default defineComponent({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
fetching.value = true;
|
fetching.value = true;
|
||||||
data = await fetchData();
|
chartData = await fetchData();
|
||||||
fetching.value = false;
|
fetching.value = false;
|
||||||
render();
|
render();
|
||||||
};
|
};
|
||||||
|
|
||||||
watch(() => [props.src, props.span], fetchAndRender);
|
watch(() => [props.src, props.span], fetchAndRender);
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchAndRender();
|
fetchAndRender();
|
||||||
});
|
|
||||||
|
|
||||||
onUnmounted(() => {
|
|
||||||
if (disposeTooltipComponent) disposeTooltipComponent();
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
chartEl,
|
|
||||||
fetching,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
if (disposeTooltipComponent) disposeTooltipComponent();
|
||||||
|
});
|
||||||
|
/* eslint-enable id-denylist */
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|
Loading…
Reference in a new issue