summaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2023-01-03 14:08:52 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2023-01-03 14:08:52 +0900
commitfb05e86db72740933292f105da3fce43b8fafb1f (patch)
tree350c5e7f18444a9fbcc46088d3ffaee3a09e43a6 /packages
parentperf(client): use shallowRef instead of ref for template reference (diff)
downloadsharkey-fb05e86db72740933292f105da3fce43b8fafb1f.tar.gz
sharkey-fb05e86db72740933292f105da3fce43b8fafb1f.tar.bz2
sharkey-fb05e86db72740933292f105da3fce43b8fafb1f.zip
:art:
Diffstat (limited to 'packages')
-rw-r--r--packages/frontend/src/components/MkChart.vue13
-rw-r--r--packages/frontend/src/components/MkChartLegend.vue75
-rw-r--r--packages/frontend/src/pages/user/activity.pv.vue15
-rw-r--r--packages/frontend/src/scripts/chart-legend.ts12
-rw-r--r--packages/frontend/src/scripts/chart-vline.ts4
5 files changed, 103 insertions, 16 deletions
diff --git a/packages/frontend/src/components/MkChart.vue b/packages/frontend/src/components/MkChart.vue
index c0562f02e3..ea28cfa794 100644
--- a/packages/frontend/src/components/MkChart.vue
+++ b/packages/frontend/src/components/MkChart.vue
@@ -1,6 +1,7 @@
<template>
<div class="cbbedffa">
<canvas ref="chartEl"></canvas>
+ <MkChartLegend ref="legendEl" style="margin-top: 8px;"/>
<div v-if="fetching" class="fetching">
<MkLoading/>
</div>
@@ -24,6 +25,8 @@ import { chartVLine } from '@/scripts/chart-vline';
import { alpha } from '@/scripts/color';
import date from '@/filters/date';
import { initChart } from '@/scripts/init-chart';
+import { chartLegend } from '@/scripts/chart-legend';
+import MkChartLegend from '@/components/MkChartLegend.vue';
initChart();
@@ -67,6 +70,8 @@ const props = defineProps({
},
});
+let legendEl = $shallowRef<InstanceType<typeof MkChartLegend>>();
+
const sum = (...arr) => arr.reduce((r, a) => r.map((b, i) => a[i] + b));
const negate = arr => arr.map(x => -x);
@@ -220,11 +225,7 @@ const render = () => {
},
plugins: {
legend: {
- display: props.detailed,
- position: 'bottom',
- labels: {
- boxWidth: 16,
- },
+ display: false,
},
tooltip: {
enabled: false,
@@ -264,7 +265,7 @@ const render = () => {
gradient,
},
},
- plugins: [chartVLine(vLineColor)],
+ plugins: [chartVLine(vLineColor), ...(props.detailed ? [chartLegend(legendEl)] : [])],
});
};
diff --git a/packages/frontend/src/components/MkChartLegend.vue b/packages/frontend/src/components/MkChartLegend.vue
new file mode 100644
index 0000000000..f33f753723
--- /dev/null
+++ b/packages/frontend/src/components/MkChartLegend.vue
@@ -0,0 +1,75 @@
+<template>
+<div :class="$style.root">
+ <button v-for="item in items" class="_button item" :class="{ disabled: item.hidden }" @click="onClick(item)">
+ <span class="box" :style="{ background: chart.config.type === 'line' ? item.strokeStyle?.toString() : item.fillStyle?.toString() }"></span>
+ {{ item.text }}
+ </button>
+</div>
+</template>
+
+<script lang="ts" setup>
+import { onMounted, ref, shallowRef, watch, PropType, onUnmounted } from 'vue';
+import { Chart, LegendItem } from 'chart.js';
+
+const props = defineProps({
+});
+
+let chart = $shallowRef<Chart>();
+let items = $shallowRef<LegendItem[]>([]);
+
+function update(_chart: Chart, _items: LegendItem[]) {
+ chart = _chart,
+ items = _items;
+}
+
+function onClick(item: LegendItem) {
+ if (chart == null) return;
+ const { type } = chart.config;
+ if (type === 'pie' || type === 'doughnut') {
+ // Pie and doughnut charts only have a single dataset and visibility is per item
+ chart.toggleDataVisibility(item.index);
+ } else {
+ chart.setDatasetVisibility(item.datasetIndex, !chart.isDatasetVisible(item.datasetIndex));
+ }
+ chart.update();
+}
+
+defineExpose({
+ update,
+});
+</script>
+
+<style lang="scss" module>
+.root {
+ display: flex;
+ flex-wrap: wrap;
+ justify-content: center;
+ gap: 8px;
+
+ &:global {
+ > .item {
+ font-size: 85%;
+ padding: 4px 12px 4px 8px;
+ border: solid 1px var(--divider);
+ border-radius: 999px;
+
+ &:hover {
+ border-color: var(--inputBorderHover);
+ }
+
+ &.disabled {
+ text-decoration: line-through;
+ opacity: 0.6;
+ }
+
+ > .box {
+ display: inline-block;
+ width: 12px;
+ height: 12px;
+ border-radius: 100%;
+ vertical-align: -10%;
+ }
+ }
+ }
+}
+</style>
diff --git a/packages/frontend/src/pages/user/activity.pv.vue b/packages/frontend/src/pages/user/activity.pv.vue
index 2d83d1ddc3..7715b66673 100644
--- a/packages/frontend/src/pages/user/activity.pv.vue
+++ b/packages/frontend/src/pages/user/activity.pv.vue
@@ -3,6 +3,7 @@
<MkLoading v-if="fetching"/>
<div v-show="!fetching" :class="$style.root" class="_panel">
<canvas ref="chartEl"></canvas>
+ <MkChartLegend ref="legendEl" style="margin-top: 8px;"/>
</div>
</div>
</template>
@@ -20,6 +21,8 @@ import { useChartTooltip } from '@/scripts/use-chart-tooltip';
import { chartVLine } from '@/scripts/chart-vline';
import { alpha } from '@/scripts/color';
import { initChart } from '@/scripts/init-chart';
+import { chartLegend } from '@/scripts/chart-legend';
+import MkChartLegend from '@/components/MkChartLegend.vue';
initChart();
@@ -28,6 +31,7 @@ const props = defineProps<{
}>();
const chartEl = $shallowRef<HTMLCanvasElement>(null);
+let legendEl = $shallowRef<InstanceType<typeof MkChartLegend>>();
const now = new Date();
let chartInstance: Chart = null;
const chartLimit = 30;
@@ -153,14 +157,7 @@ async function renderChart() {
},
},
legend: {
- display: true,
- position: 'bottom',
- padding: {
- left: 0,
- right: 0,
- top: 8,
- bottom: 0,
- },
+ display: false,
},
tooltip: {
enabled: false,
@@ -173,7 +170,7 @@ async function renderChart() {
gradient,
},
},
- plugins: [chartVLine(vLineColor)],
+ plugins: [chartVLine(vLineColor), chartLegend(legendEl)],
});
fetching = false;
diff --git a/packages/frontend/src/scripts/chart-legend.ts b/packages/frontend/src/scripts/chart-legend.ts
new file mode 100644
index 0000000000..6a5370cc87
--- /dev/null
+++ b/packages/frontend/src/scripts/chart-legend.ts
@@ -0,0 +1,12 @@
+import { Plugin } from 'chart.js';
+import MkChartLegend from '@/components/MkChartLegend.vue';
+
+export const chartLegend = (legend: InstanceType<typeof MkChartLegend>) => ({
+ id: 'htmlLegend',
+ afterUpdate(chart, args, options) {
+ // Reuse the built-in legendItems generator
+ const items = chart.options.plugins.legend.labels.generateLabels(chart);
+
+ legend.update(chart, items);
+ },
+}) as Plugin;
diff --git a/packages/frontend/src/scripts/chart-vline.ts b/packages/frontend/src/scripts/chart-vline.ts
index 10021583e0..f321443834 100644
--- a/packages/frontend/src/scripts/chart-vline.ts
+++ b/packages/frontend/src/scripts/chart-vline.ts
@@ -1,3 +1,5 @@
+import { Plugin } from 'chart.js';
+
export const chartVLine = (vLineColor: string) => ({
id: 'vLine',
beforeDraw(chart, args, options) {
@@ -18,4 +20,4 @@ export const chartVLine = (vLineColor: string) => ({
ctx.restore();
}
},
-});
+}) as Plugin;