@@ -19,6 +19,7 @@ import noUiSlider, { Options, PipsMode } from 'nouislider';
19
19
import dayjs from 'dayjs' ;
20
20
import duration from 'dayjs/plugin/duration' ;
21
21
import dayOfYear from 'dayjs/plugin/dayOfYear' ;
22
+ import { memoize } from 'common' ;
22
23
23
24
interface Opts {
24
25
data : PerfRatingHistory [ ] ;
@@ -66,6 +67,21 @@ const styles: ChartPerf[] = [
66
67
67
68
const oneDay = 24 * 60 * 60 * 1000 ;
68
69
70
+ const dateFormat = memoize ( ( ) =>
71
+ window . Intl && Intl . DateTimeFormat
72
+ ? new Intl . DateTimeFormat (
73
+ document . documentElement . lang . startsWith ( 'ar-' ) ? 'ar-ly' : document . documentElement . lang ,
74
+ {
75
+ month : 'short' ,
76
+ day : '2-digit' ,
77
+ year : 'numeric' ,
78
+ } ,
79
+ ) . format
80
+ : ( d : Date ) => d . toLocaleDateString ( ) ,
81
+ ) ;
82
+
83
+ const utcOffset = - dayjs ( ) . utcOffset ( ) * 60 * 1000 ;
84
+
69
85
export function initModule ( { data, singlePerfName } : Opts ) {
70
86
$ ( '.spinner' ) . remove ( ) ;
71
87
@@ -76,9 +92,8 @@ export function initModule({ data, singlePerfName }: Opts) {
76
92
return ;
77
93
}
78
94
const allData = makeDatasets ( 1 , { data, singlePerfName } , singlePerfIndex ) ;
79
- let startDate = dayjs ( allData . startDate ) ;
80
- const endDate = dayjs ( allData . endDate ) ;
81
- if ( startDate . diff ( endDate , 'D' ) < 1 ) startDate = startDate . subtract ( 1 , 'day' ) ;
95
+ const startDate = allData . startDate ;
96
+ const endDate = allData . endDate ;
82
97
const weeklyData = makeDatasets ( 7 , { data, singlePerfName } , singlePerfIndex ) ;
83
98
const biweeklyData = makeDatasets ( 14 , { data, singlePerfName } , singlePerfIndex ) ;
84
99
const threeMonthsAgo = endDate . subtract ( 3 , 'M' ) ;
@@ -106,10 +121,6 @@ export function initModule({ data, singlePerfName }: Opts) {
106
121
max : endDate . valueOf ( ) ,
107
122
type : 'time' ,
108
123
display : false ,
109
- time : {
110
- tooltipFormat : 'MMM DD, YYYY' ,
111
- minUnit : 'day' ,
112
- } ,
113
124
clip : false ,
114
125
ticks : {
115
126
source : 'data' ,
@@ -175,6 +186,10 @@ export function initModule({ data, singlePerfName }: Opts) {
175
186
borderWidth : 1 ,
176
187
yAlign : 'center' ,
177
188
caretPadding : 10 ,
189
+ rtl : document . dir == 'rtl' ,
190
+ callbacks : {
191
+ title : items => dateFormat ( ) ( new Date ( items [ 0 ] . parsed . x + utcOffset ) ) ,
192
+ } ,
178
193
} ,
179
194
} ,
180
195
} ,
@@ -266,23 +281,23 @@ function makeDatasets(step: number, { data, singlePerfName }: Opts, singlePerfIn
266
281
const minMax = ( d : PerfRatingHistory ) => [ getDate ( d . points [ 0 ] ) , getDate ( d . points [ d . points . length - 1 ] ) ] ;
267
282
const filteredData = data . filter ( indexFilter ) ;
268
283
const dates = filteredData . filter ( p => p . points . length ) . flatMap ( minMax ) ;
269
- const startDate = Math . min ( ...dates ) ;
270
- const endDate = Math . max ( ...dates ) ;
284
+ let startDate = dayjs ( Math . min ( ...dates ) ) ;
285
+ let endDate = dayjs ( Math . max ( ...dates ) ) ;
271
286
const ds : ChartDataset < 'line' > [ ] = filteredData . map ( ( serie , i ) => {
272
287
const originalDatesAndRatings = serie . points . map ( r => ( {
273
288
ts : getDate ( r ) ,
274
289
rating : r [ 3 ] ,
275
290
} ) ) ;
276
291
const perfStyle = styles . filter ( indexFilter ) [ i ] ;
277
- const data = smoothDates ( originalDatesAndRatings , step , startDate ) ;
292
+ const data = smoothDates ( originalDatesAndRatings , step , startDate . valueOf ( ) ) ;
278
293
return {
279
294
indexAxis : 'x' ,
280
295
type : 'line' ,
281
296
label : serie . name ,
282
297
borderColor : perfStyle . color ,
283
298
hoverBorderColor : hoverBorderColor ,
284
299
backgroundColor : perfStyle . color ,
285
- pointRadius : 0 ,
300
+ pointRadius : data . length == 1 ? 3 : 0 ,
286
301
pointHoverRadius : 6 ,
287
302
data : data ,
288
303
pointStyle : perfStyle . symbol ,
@@ -293,20 +308,22 @@ function makeDatasets(step: number, { data, singlePerfName }: Opts, singlePerfIn
293
308
animation : false ,
294
309
} ;
295
310
} ) ;
311
+ if ( endDate . diff ( startDate , 'day' ) < 1 ) {
312
+ startDate = startDate . subtract ( 1 , 'day' ) ;
313
+ endDate = endDate . add ( 1 , 'day' ) ;
314
+ }
296
315
return { ds : ds . filter ( ds => ds . data . length ) , startDate, endDate } ;
297
316
}
298
317
function smoothDates ( data : TsAndRating [ ] , step : number , begin : number ) {
299
318
const oneStep = oneDay * step ;
300
319
if ( ! data . length ) return [ ] ;
301
- if ( data . length == 1 ) return [ { x : begin , y : data [ 0 ] . rating } ] ;
302
320
303
321
const end = data [ data . length - 1 ] . ts ;
304
322
const reversed = data . slice ( ) . reverse ( ) ;
305
323
const allDates : number [ ] = [ ] ;
306
324
for ( let i = begin ; i <= end ; i += oneStep ) allDates . push ( i ) ;
307
- if ( ! allDates . find ( d => d == end ) ) allDates . push ( end ) ;
308
325
const result : Point [ ] = [ ] ;
309
- for ( let j = 1 ; j < allDates . length ; j ++ ) {
326
+ for ( let j = 0 ; j < allDates . length ; j ++ ) {
310
327
const match = reversed . find ( x => x . ts <= allDates [ j ] ) ;
311
328
if ( match ) result . push ( { x : allDates [ j ] , y : match . rating } ) ;
312
329
}
0 commit comments