11import { t } from '@app/locale'
22import { InfoFilled } from '@element-plus/icons-vue'
3+ import { useShadow } from '@hooks/index'
34import Flex from '@pages/components/Flex'
45import { groupBy } from '@util/array'
56import { MILL_PER_HOUR , MILL_PER_MINUTE } from '@util/time'
67import { ElIcon , ElRate , ElText , ElTooltip } from 'element-plus'
7- import { computed , defineComponent , FunctionalComponent } from 'vue'
8-
9- type ScoreValue = 1 | 2 | 3 | 4 | 5
8+ import { computed , defineComponent , watch } from 'vue'
109
1110type AnalysisResult = {
12- busy : ScoreValue
13- focus : ScoreValue
11+ busy : number
12+ focus : number
1413}
1514
15+ const MAX_SCORE = 5
16+
1617const defaultResult = ( ) : AnalysisResult => ( {
1718 busy : 1 ,
1819 focus : 1 ,
1920} )
2021
21- const cvtRaw2Score = ( raw : number ) : ScoreValue => {
22- if ( raw < 1.5 ) return 1
23- else if ( raw < 2.5 ) return 2
24- else if ( raw < 3.5 ) return 3
25- else if ( raw < 4.5 ) return 4
26- else return 5
27- }
28-
2922const computeSessionScore = ( ticks : timer . timeline . Tick [ ] , hourCount : number ) => {
3023 let continuousSessions = 0
3124 let currentSession : timer . timeline . Tick [ ] = [ ]
@@ -50,7 +43,7 @@ const computeSessionScore = (ticks: timer.timeline.Tick[], hourCount: number) =>
5043 if ( currentSession . length > 1 ) continuousSessions ++
5144
5245 const sessionDensity = continuousSessions / Math . max ( 1 , hourCount / 10 )
53- return Math . min ( sessionDensity , 1 )
46+ return Math . min ( sessionDensity , MAX_SCORE )
5447}
5548
5649const analyze = ( ticks : timer . timeline . Tick [ ] ) : AnalysisResult => {
@@ -69,39 +62,42 @@ const analyze = (ticks: timer.timeline.Tick[]): AnalysisResult => {
6962
7063 // busyScore = timeDensity * 0.6 + hostCountPerHour * 0.4
7164 const timeDensity = totalActiveTime / totalRange
65+ const timeDensityScore = Math . min ( timeDensity / 0.3 , MAX_SCORE )
7266 const maxHostCount = Object . values ( hourlyData ) . map ( hosts => hosts . size ) . sort ( ( a , b ) => b - a ) [ 0 ] !
73- const busyRawScore = ( timeDensity * 0.6 + ( Math . min ( maxHostCount / 10 , 1 ) * 0.4 ) ) * 5
67+ const hostMaxScore = Math . min ( maxHostCount / 4 , MAX_SCORE )
68+ const busy = timeDensityScore * 0.6 + hostMaxScore * 0.4
7469
7570 // focusScore = duration * 0.7 + session * 0.3
7671 const avgDuration = totalActiveTime / ticks . length
77- const avgDurationScore = Math . min ( avgDuration / ( 2 * MILL_PER_MINUTE ) , 1 )
72+ const avgDurationScore = Math . min ( avgDuration / ( 2 * MILL_PER_MINUTE ) , MAX_SCORE )
7873 const sessionScore = computeSessionScore ( ticks , Object . keys ( hourlyData ) . length )
79- const focusRawScore = ( avgDurationScore * 0.7 + sessionScore * 0.3 ) * 5
74+ const focus = avgDurationScore * 0.7 + sessionScore * 0.3
8075
81- return {
82- busy : cvtRaw2Score ( busyRawScore ) ,
83- focus : cvtRaw2Score ( focusRawScore ) ,
84- }
76+ return { busy, focus }
8577}
8678
87- const Score : FunctionalComponent < { score : ScoreValue , label : string , desc : string } > = ( { score, label, desc } ) => (
88- < Flex align = 'center' column justify = 'center' gap = { 10 } >
89- < ElText >
90- { `${ label } ` }
91- < ElTooltip content = { desc } >
92- < ElText size = 'small' >
93- < ElIcon >
94- < InfoFilled />
95- </ ElIcon >
96- </ ElText >
97- </ ElTooltip >
98- </ ElText >
99- < ElRate disabled modelValue = { score } />
100- </ Flex >
101- )
79+ const Score = defineComponent < { score : number , label : string , desc : string } > ( props => {
80+ const [ score ] = useShadow ( ( ) => props . score )
81+ return ( ) => (
82+ < Flex align = 'center' column justify = 'center' gap = { 10 } >
83+ < ElText >
84+ { `${ props . label } ` }
85+ < ElTooltip content = { props . desc } >
86+ < ElText size = 'small' >
87+ < ElIcon >
88+ < InfoFilled />
89+ </ ElIcon >
90+ </ ElText >
91+ </ ElTooltip >
92+ </ ElText >
93+ < ElRate disabled modelValue = { parseFloat ( score . value . toFixed ( 1 ) ) } showScore />
94+ </ Flex >
95+ )
96+ } , { props : [ 'desc' , 'label' , 'score' ] } )
10297
10398const Summary = defineComponent < { data : timer . timeline . Tick [ ] } > ( props => {
10499 const ticks = computed ( ( ) => analyze ( props . data ) )
100+ watch ( [ ticks ] , ( ) => console . log ( ticks . value ) )
105101
106102 return ( ) => (
107103 < Flex column justify = 'center' gap = { 30 } height = '100%' >
0 commit comments