Skip to content

Commit

Permalink
Support more charts of habit (#207)
Browse files Browse the repository at this point in the history
Merge pull request #252 from sheepzh/habit
  • Loading branch information
sheepzh authored Jan 2, 2024
2 parents 633bde5 + 12ab7e3 commit 2515343
Show file tree
Hide file tree
Showing 80 changed files with 1,832 additions and 836 deletions.
14 changes: 13 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,19 @@
},
"javascript.format.insertSpaceBeforeFunctionParenthesis": true,
"cSpell.words": [
"Auths",
"echarts",
"Hengyang"
"Hengyang",
"Kanban"
],
"cSpell.ignorePaths": [
"package-lock.json",
"node_modules",
"vscode-extension",
".git/objects",
".vscode",
".vscode-insiders",
// Ignore i18n resources
"src/i18n/message/**/*.json",
],
}
25 changes: 0 additions & 25 deletions src/app/components/analysis/components/common/row-card.ts

This file was deleted.

13 changes: 2 additions & 11 deletions src/app/components/analysis/components/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { ref, h, defineComponent } from "vue"
import statService, { HostSet } from "@service/stat-service"
import siteService from "@service/site-service"
import { t } from "@app/locale"
import SelectFilterItem from "@app/components/common/select-filter-item"
import TimeFormatFilterItem from "@app/components/common/time-format-filter-item"
import { labelOfHostInfo } from "../util"

const calcUniqueKey = ({ host, virtual, merged }: timer.site.SiteInfo) => `${host}${virtual ? 1 : 0}${merged ? 1 : 0}`
Expand Down Expand Up @@ -45,13 +45,6 @@ async function handleRemoteSearch(queryStr: string, trendDomainOptions: Ref<time

const HOST_PLACEHOLDER = t(msg => msg.analysis.common.hostPlaceholder)

const TIME_FORMAT_LABELS: { [key in timer.app.TimeFormat]: string } = {
default: t(msg => msg.timeFormat.default),
second: t(msg => msg.timeFormat.second),
minute: t(msg => msg.timeFormat.minute),
hour: t(msg => msg.timeFormat.hour)
}

function keyOfHostInfo(option: timer.site.SiteKey): string {
const { merged, virtual, host } = option
let prefix = '_'
Expand Down Expand Up @@ -135,10 +128,8 @@ const _default = defineComponent({
label: labelOfHostInfo(siteInfo),
}, () => renderHostLabel(siteInfo))
)),
h(SelectFilterItem, {
historyName: 'timeFormat',
h(TimeFormatFilterItem, {
defaultValue: timeFormat.value,
options: TIME_FORMAT_LABELS,
onSelect: (newVal: timer.app.TimeFormat) => ctx.emit('timeFormatChange', timeFormat.value = newVal)
})
]
Expand Down
15 changes: 7 additions & 8 deletions src/app/components/analysis/components/summary/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import type { PropType, Ref, VNode } from "vue"
import { defineComponent, h, ref, watch } from "vue"
import siteService from "@service/site-service"
import Site from "./site"
import RowCard from "../common/row-card"
import Indicator from "../common/indicator"
import { KanbanIndicatorCell, KanbanCard, KanbanIndicatorRow } from "@app/components/common/kanban"
import "./summary.sass"
import { ElCol, ElRow } from "element-plus"
import { ElCol } from "element-plus"
import { t } from "@app/locale"
import { cvt2LocaleTime, periodFormatter } from "@app/util/time"

Expand Down Expand Up @@ -42,19 +41,19 @@ const VISIT_LABEL = t(msg => msg.analysis.common.visitTotal)

function renderContent(siteInfo: timer.site.SiteInfo, summary: Summary, timeFormat: timer.app.TimeFormat): VNode {
const { day, firstDay, focus, visit } = summary || {}
return h(ElRow, { class: "analysis-summary-container" }, () => [
return h(KanbanIndicatorRow, {}, () => [
h(ElCol, { span: 6 }, () => h(Site, { site: siteInfo })),
h(ElCol, { span: 6 }, () => h(Indicator, {
h(ElCol, { span: 6 }, () => h(KanbanIndicatorCell, {
mainName: DAYS_LABEL,
mainValue: day?.toString() || '-',
subTips: msg => msg.analysis.summary.firstDay,
subValue: firstDay ? `@${cvt2LocaleTime(firstDay)}` : ''
})),
h(ElCol, { span: 6 }, () => h(Indicator, {
h(ElCol, { span: 6 }, () => h(KanbanIndicatorCell, {
mainName: FOCUS_LABEL,
mainValue: focus === undefined ? '-' : periodFormatter(focus, timeFormat, false),
})),
h(ElCol, { span: 6 }, () => h(Indicator, {
h(ElCol, { span: 6 }, () => h(KanbanIndicatorCell, {
mainName: VISIT_LABEL,
mainValue: visit?.toString() || '-',
})),
Expand Down Expand Up @@ -87,7 +86,7 @@ const _default = defineComponent({

querySiteInfo()

return () => h(RowCard, {
return () => h(KanbanCard, {
title: t(msg => msg.analysis.summary.title)
}, () => renderContent(siteInfo.value, summaryInfo.value, timeFormat.value))
}
Expand Down
7 changes: 1 addition & 6 deletions src/app/components/analysis/components/summary/summary.sass
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@

.analysis-summary-container
height: 140px
margin-bottom: 0px !important
>.el-col:not(:first-child)
border-left: 1px var(--el-border-color) var(--el-border-style)
.kanban-indicator-row
.site-container
position: relative
top: 50%
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/**
* Copyright (c) 2023 Hengyang Zhang
*
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
Expand All @@ -20,7 +20,7 @@ const _default = defineComponent({
setup(props) {
const elRef: Ref<HTMLDivElement> = ref()
const wrapper: ChartWrapper = new ChartWrapper()
const render = () => wrapper.render(props.data, props.title, props.valueFormatter)
const render = () => wrapper.render({ entries: props.data, title: props.title, valueFormatter: props.valueFormatter })

watch(() => props.data, render)
watch(() => props.valueFormatter, render)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import type { PropType } from "vue"

import { computeRingText, formatValue } from "@app/components/analysis/util"
import { defineComponent, h } from "vue"
import Indicator from "../../common/indicator"
import { KanbanIndicatorCell } from "@app/components/common/kanban"
import Chart from "./chart"
import { cvt2LocaleTime } from "@app/util/time"

Expand All @@ -24,15 +24,15 @@ type RenderProps = {
}

const renderMax = ({ maxLabel, maxValue, valueFormatter: formatter, maxDate }: RenderProps) =>
h('div', { class: 'analysis-trend-dimension-indicator-item' }, h(Indicator, {
h('div', { class: 'analysis-trend-dimension-indicator-item' }, h(KanbanIndicatorCell, {
mainName: maxLabel,
mainValue: formatter ? formatter(maxValue) : maxValue?.toString() || '-',
subValue: maxDate ? `@${cvt2LocaleTime(maxDate)}` : '',
}))

const renderAverage = ({ averageLabel, valueFormatter, average }: RenderProps) => {
const currentAverage = average?.[0]
return h('div', { class: 'analysis-trend-dimension-indicator-item' }, h(Indicator, {
return h('div', { class: 'analysis-trend-dimension-indicator-item' }, h(KanbanIndicatorCell, {
mainName: averageLabel,
mainValue: formatValue(currentAverage, valueFormatter),
subTips: msg => msg.analysis.common.ringGrowth,
Expand Down
115 changes: 58 additions & 57 deletions src/app/components/analysis/components/trend/dimension/wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import type { DimensionEntry } from "../../../util"
import type { ECharts, ComposeOption } from "echarts/core"
import type { ComposeOption } from "echarts/core"
import type { LineSeriesOption } from "echarts/charts"
import type {
TitleComponentOption,
Expand All @@ -15,7 +15,7 @@ import type {
GridComponentOption,
} from "echarts/components"

import { init, use } from "@echarts/core"
import { use } from "@echarts/core"
import LineChart from "@echarts/chart/line"
import SVGRenderer from "@echarts/svg-renderer"
import TitleComponent from "@echarts/component/title"
Expand All @@ -24,6 +24,7 @@ import GridComponent from '@echarts/component/grid'

import { ValueFormatter } from "@app/components/analysis/util"
import { getSecondaryTextColor } from "@util/style"
import { EchartsWrapper } from "@app/components/common/echarts-wrapper"

use([
LineChart,
Expand All @@ -41,66 +42,66 @@ type EcOption = ComposeOption<
| GridComponentOption
>

class ChartWrapper {
instance: ECharts

init(container: HTMLDivElement) {
this.instance = init(container)
}
type BizOption = {
entries: DimensionEntry[]
title: string
valueFormatter: ValueFormatter
}

async render(entries: DimensionEntry[], title: string, valueFormatter: ValueFormatter) {
const xAxis = entries.map(r => r.date)
const yAxis = entries.map(r => r.value)
const generateOption = ({ entries, title, valueFormatter }: BizOption) => {
const xAxis = entries.map(r => r.date)
const yAxis = entries.map(r => r.value)

const secondaryTextColor = getSecondaryTextColor()
const option: EcOption = {
backgroundColor: 'rgba(0,0,0,0)',
title: {
text: title,
textStyle: {
color: secondaryTextColor,
fontSize: '14px',
fontWeight: 'normal',
},
left: 'center',
top: '9%',
},
grid: {
top: '30%',
bottom: '10px',
left: '5%',
right: '5%',
const secondaryTextColor = getSecondaryTextColor()
const option: EcOption = {
backgroundColor: 'rgba(0,0,0,0)',
title: {
text: title,
textStyle: {
color: secondaryTextColor,
fontSize: '14px',
fontWeight: 'normal',
},
tooltip: {
trigger: 'axis',
formatter(params: any) {
const format = params instanceof Array ? params[0] : params
const { name, value } = format
const valStr = valueFormatter?.(value) || value?.toString() || "NaN"
return `${name}<br/>${valStr}`
},
left: 'center',
top: '9%',
},
grid: {
top: '30%',
bottom: '10px',
left: '5%',
right: '5%',
},
tooltip: {
trigger: 'axis',
formatter(params: any) {
const format = params instanceof Array ? params[0] : params
const { name, value } = format
const valStr = valueFormatter?.(value) || value?.toString() || "NaN"
return `${name}<br/>${valStr}`
},
xAxis: {
type: 'category',
data: xAxis,
show: false,
},
yAxis: {
type: 'value',
axisLabel: { show: false },
axisTick: { show: false },
splitLine: { show: false },
},
series: {
data: yAxis,
type: 'line',
symbol: 'none',
areaStyle: {},
smooth: true,
}
},
xAxis: {
type: 'category',
data: xAxis,
show: false,
},
yAxis: {
type: 'value',
axisLabel: { show: false },
axisTick: { show: false },
splitLine: { show: false },
},
series: {
data: yAxis,
type: 'line',
symbol: 'none',
areaStyle: {},
smooth: true,
}
this.instance?.setOption(option)
}
return option
}

export default ChartWrapper
export default class ChartWrapper extends EchartsWrapper<BizOption, EcOption> {
generateOption = generateOption
}
2 changes: 1 addition & 1 deletion src/app/components/analysis/components/trend/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const _default = defineComponent({
d: 'DD'
})
const dateRange: Ref<[Date, Date]> = ref(props.dateRange)
return () => h('div', { class: 'analysis-trend-filter' }, [
return () => h('div', [
h(ElDatePicker, {
modelValue: dateRange.value,
disabledDate: (date: Date) => date.getTime() > new Date().getTime(),
Expand Down
Loading

0 comments on commit 2515343

Please sign in to comment.