1+ import { EChartOption } from "echarts"
2+ import { PeriodKey , PERIODS_PER_DATE } from "../../../../entity/dto/period-info"
3+ import PeriodResult from "../../../../entity/dto/period-result"
4+ import { formatPeriodCommon , formatTime } from "../../../../util/time"
5+ import { t } from "../../../locale"
6+
7+ const formatTimeOfEchart = ( params : EChartOption . Tooltip . Format | EChartOption . Tooltip . Format [ ] , merge : boolean ) => {
8+ const format : EChartOption . Tooltip . Format = params instanceof Array ? params [ 0 ] : params
9+ const { value } = format
10+ // If merge, don't show the date
11+ const start = formatTime ( value [ 2 ] , merge ? '{h}:{i}' : '{m}-{d} {h}:{i}' )
12+ const end = formatTime ( value [ 3 ] , '{h}:{i}' )
13+ return `${ formatPeriodCommon ( value [ 1 ] * 1000 ) } <br/>${ start } -${ end } `
14+ }
15+
16+ const title = t ( msg => msg . period . chart . title )
17+ const baseOptions : EChartOption < EChartOption . SeriesBar > = {
18+ title : {
19+ text : title ,
20+ left : 'center'
21+ } ,
22+ tooltip : { } ,
23+ toolbox : {
24+ show : true ,
25+ feature : {
26+ saveAsImage : {
27+ show : true ,
28+ title : t ( msg => msg . period . chart . saveAsImageTitle ) ,
29+ name : title , // file name
30+ excludeComponents : [ 'toolbox' ] ,
31+ pixelRatio : 1
32+ }
33+ }
34+ } ,
35+ xAxis : {
36+ axisLabel : { /** placeholder */ } ,
37+ type : 'time' ,
38+ axisLine : {
39+ show : false
40+ }
41+ } ,
42+ yAxis : {
43+ name : t ( msg => msg . period . chart . yAxisName ) ,
44+ type : 'value'
45+ } ,
46+ series : [ {
47+ type : "bar" ,
48+ large : true ,
49+ data : [ ] ,
50+ barGap : '0%' , // Make series be overlap
51+ barCategoryGap : '0%'
52+ } ]
53+ }
54+
55+ type _Props = {
56+ data : PeriodResult [ ]
57+ merge : boolean
58+ periodSize : number
59+ }
60+
61+ export type OptionProps = _Props
62+
63+ const merge2OneDay = ( data : PeriodResult [ ] , periodSize : number ) => {
64+ const map : Map < number , number > = new Map ( )
65+ data . forEach ( item => {
66+ const key = Math . floor ( item . getStartOrder ( ) / periodSize )
67+ const val = map . get ( key ) || 0
68+ map . set ( key , val + item . millseconds )
69+ } )
70+ const result = [ ]
71+ let period = PeriodKey . of ( new Date ( ) , 0 )
72+ for ( let i = 0 ; i < PERIODS_PER_DATE / periodSize ; i ++ ) {
73+ const key = period . order / periodSize
74+ result . push ( PeriodResult . of ( period . after ( periodSize - 1 ) , periodSize , map . get ( key ) || 0 ) )
75+ period = period . after ( periodSize )
76+ }
77+ return result
78+ }
79+
80+ function formatXAxis ( ts : number ) {
81+ const date = new Date ( ts )
82+ if ( date . getHours ( ) === 0 && date . getMinutes ( ) === 0 ) {
83+ return formatTime ( date , '{m}-{d}' )
84+ } else {
85+ return formatTime ( date , '{h}:{i}' )
86+ }
87+ }
88+
89+ const generateOptions = ( { data, merge, periodSize } : _Props ) => {
90+ const periodData : PeriodResult [ ] = merge ? merge2OneDay ( data , periodSize ) : data
91+ const valueData : any [ ] = [ ]
92+ periodData . forEach ( ( item ) => {
93+ const startTime = item . startTime . getTime ( )
94+ const endTime = item . endTime . getTime ( )
95+ const seconds = Math . floor ( item . millseconds / 1000 )
96+ const x = ( startTime + endTime ) / 2
97+ valueData . push ( [ x , seconds , startTime , endTime ] )
98+ } )
99+ const xAxis = baseOptions . xAxis as EChartOption . XAxis
100+ xAxis . min = periodData [ 0 ] . startTime . getTime ( )
101+ xAxis . max = periodData [ periodData . length - 1 ] . endTime . getTime ( )
102+ xAxis . axisLabel . formatter = merge ? '{HH}:{mm}' : formatXAxis
103+ baseOptions . series [ 0 ] . data = valueData
104+ baseOptions . tooltip . formatter = params => formatTimeOfEchart ( params , merge )
105+
106+ return baseOptions
107+ }
108+
109+ export default generateOptions
0 commit comments