Skip to content

Commit

Permalink
feat(analytics): switch between send and receive
Browse files Browse the repository at this point in the history
  • Loading branch information
shigma committed Dec 15, 2023
1 parent 1fd4481 commit cf59e2a
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 25 deletions.
9 changes: 5 additions & 4 deletions plugins/analytics/client/charts/bot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ export default (ctx: Context) => {
ctx.slot({
type: 'chart',
component: createChart({
title: '各平台占比',
title: '各平台消息占比',
fields: ['analytics'],
options({ analytics }) {
showTab: true,
options({ analytics }, tab) {
if (!Object.keys(analytics.messageByBot).length) return
const data = Object
.entries(analytics.messageByBot)
Expand All @@ -17,13 +18,13 @@ export default (ctx: Context) => {
.entries(value)
.map(([key, value]) => ({
name: value.name || key,
value: value.send,
value: value[tab],
})),
}))

return {
tooltip: Tooltip.item(({ data }) => {
return `${data.children ? '平台' : '昵称'}${data.name}<br>消息数量${data.value.toFixed(2)}`
return `${data.children ? '平台' : '昵称'}${data.name}<br>日均消息数量${data.value.toFixed(2)}`
}),
series: [{
type: 'sunburst',
Expand Down
9 changes: 5 additions & 4 deletions plugins/analytics/client/charts/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,16 @@ export default (ctx: Context) => {
ctx.slot({
type: 'chart',
component: createChart({
title: '历史发言数量',
title: '历史消息数量',
fields: ['analytics'],
options({ analytics }) {
showTab: true,
options({ analytics }, tab) {
if (!Object.keys(analytics.messageByDate).length) return

return {
tooltip: Tooltip.axis(([{ name, value }]) => {
const day = new Date(name).getDay()
return `${name} 星期${week[day]}<br>发言数量${value}`
return `${name} 星期${week[day]}<br>消息数量${value}`
}),
xAxis: {
type: 'category',
Expand All @@ -27,7 +28,7 @@ export default (ctx: Context) => {
series: {
type: 'line',
smooth: true,
data: Object.values(analytics.messageByDate).map(stats => stats.send),
data: Object.values(analytics.messageByDate).map(stats => stats[tab]),
},
}
},
Expand Down
9 changes: 5 additions & 4 deletions plugins/analytics/client/charts/hour.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ export default (ctx: Context) => {
ctx.slot({
type: 'chart',
component: createChart({
title: '每小时发言数量',
title: '每小时消息数量',
fields: ['analytics'],
options({ analytics }) {
showTab: true,
options({ analytics }, tab) {
return {
tooltip: Tooltip.axis<number[]>((params) => {
const [{ data: [x], dataIndex }] = params
const source = analytics.messageByHour[dataIndex]
const output = [
`${formatHour(x)}`,
`消息总量${+(source.send || 0).toFixed(1)}`,
`日均消息数量${+(source[tab] || 0).toFixed(1)}`,
]
return output.join('<br>')
}),
Expand All @@ -40,7 +41,7 @@ export default (ctx: Context) => {
},
series: [{
name: '其他',
data: analytics.messageByHour.map((val, index) => [index + 0.5, val.send || 0]),
data: analytics.messageByHour.map((val, index) => [index + 0.5, val[tab] || 0]),
type: 'bar',
stack: '1',
}],
Expand Down
23 changes: 23 additions & 0 deletions plugins/analytics/client/charts/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.analytics-card {
header {
display: flex;
justify-content: space-between;

.right {
font-size: 1rem;
font-weight: normal;
display: flex;
gap: 1rem;
}

.tab-item {
padding: 0 4px;
cursor: pointer;
}

.tab-item.active {
color: var(--primary);
border-bottom: 2px solid var(--primary);
}
}
}
47 changes: 34 additions & 13 deletions plugins/analytics/client/charts/utils.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,45 @@
import { defineAsyncComponent, h, resolveComponent } from 'vue'
import { Console } from '@koishijs/plugin-console'
import { Card, Store, store } from '@koishijs/client'
import { defineAsyncComponent, defineComponent, h, ref, resolveComponent } from 'vue'
import { Field, Store, store } from '@koishijs/client'
import type * as echarts from 'echarts'
import './index.scss'

const VChart = defineAsyncComponent(() => import('./echarts'))

export interface ChartOptions {
title: string
fields?: (keyof Console.Services)[]
options: (store: Store) => echarts.EChartsOption
fields?: Field[]
showTab?: boolean
options: (store: Store, tab: 'send' | 'receive') => echarts.EChartsOption
}

export function createChart({ title, fields, options }: ChartOptions) {
return Card.create(() => {
const option = options(store)
if (!option) return
return h(resolveComponent('k-card'), { class: 'frameless', title }, () => {
return h(VChart, { option, autoresize: true })
})
}, fields)
const tabValue = ref<'send' | 'receive'>('send')

export function createChart({ title, fields, showTab, options }: ChartOptions) {
return defineComponent({
render: () => {
if (!fields.every(key => store[key])) return null
const option = options(store, tabValue.value)
if (!option) return
return h(resolveComponent('k-card'), { class: 'frameless analytics-card' }, {
header: () => [
h('span', { class: 'left' }, [title]),
...showTab ? [h('span', { class: 'right' }, [
h('span', {
class: 'tab-item' + (tabValue.value === 'send' ? ' active' : ''),
onClick: () => tabValue.value = 'send',
}, ['发送']),
h('span', {
class: 'tab-item' + (tabValue.value === 'receive' ? ' active' : ''),
onClick: () => tabValue.value = 'receive',
}, ['接收']),
])] : [],
],
default: () => {
return h(VChart, { option, autoresize: true })
},
})
},
})
}

interface CommonData {
Expand Down

0 comments on commit cf59e2a

Please sign in to comment.