1
- import { useState } from 'react' ;
1
+ import { useState , useCallback } from 'react' ;
2
2
import { Story , Meta } from '@storybook/react/types-6-0' ;
3
3
import { LinePlotProps } from '../../plots/LinePlot' ;
4
4
import TimeSlider , {
5
5
TimeSliderDataProp ,
6
6
} from '../../components/plotControls/TimeSlider' ;
7
7
import { DraggablePanel } from '@veupathdb/coreui/lib/components/containers' ;
8
8
9
+ import AxisRangeControl from '../../components/plotControls/AxisRangeControl' ;
10
+ import { NumberOrDateRange } from '../../types/general' ;
11
+
9
12
export default {
10
13
title : 'Plot Controls/TimeSlider' ,
11
14
component : TimeSlider ,
@@ -301,7 +304,56 @@ export const TimeFilter: Story<LinePlotProps> = (args: any) => {
301
304
302
305
// set constant values
303
306
const defaultSymbolSize = 0.8 ;
304
- const defaultColor = '#333' ;
307
+
308
+ // control selectedRange
309
+ const handleAxisRangeChange = useCallback (
310
+ ( newRange ?: NumberOrDateRange ) => {
311
+ if ( newRange )
312
+ setSelectedRange ( {
313
+ start : newRange . min as string ,
314
+ end : newRange . max as string ,
315
+ } ) ;
316
+ } ,
317
+ [ setSelectedRange ]
318
+ ) ;
319
+
320
+ const handleArrowClick = useCallback (
321
+ ( arrow : string ) => {
322
+ // let's assume that selectedRange has the format of 'yyyy-mm-dd'
323
+ if (
324
+ selectedRange &&
325
+ selectedRange . start != null &&
326
+ selectedRange . end != null
327
+ ) {
328
+ const selectedRangeArray =
329
+ arrow === 'left'
330
+ ? selectedRange . start . split ( '-' )
331
+ : selectedRange . end . split ( '-' ) ;
332
+ const addSubtractYear =
333
+ arrow === 'left'
334
+ ? String ( Number ( selectedRangeArray [ 0 ] ) - 1 )
335
+ : String ( Number ( selectedRangeArray [ 0 ] ) + 1 ) ;
336
+ const changeYear =
337
+ addSubtractYear +
338
+ '-' +
339
+ selectedRangeArray [ 1 ] +
340
+ '-' +
341
+ selectedRangeArray [ 2 ] ;
342
+ setSelectedRange ( ( prev ) => {
343
+ return arrow === 'left'
344
+ ? {
345
+ start : changeYear as string ,
346
+ end : prev ?. end as string ,
347
+ }
348
+ : {
349
+ start : prev ?. start as string ,
350
+ end : changeYear as string ,
351
+ } ;
352
+ } ) ;
353
+ }
354
+ } ,
355
+ [ selectedRange , setSelectedRange ]
356
+ ) ;
305
357
306
358
return (
307
359
< DraggablePanel
@@ -322,16 +374,47 @@ export const TimeFilter: Story<LinePlotProps> = (args: any) => {
322
374
>
323
375
< div
324
376
style = { {
325
- display : 'grid ' ,
326
- gridTemplateColumns : '1fr repeat(1, auto) 1fr ' ,
327
- gridColumnGap : '5px ' ,
377
+ display : 'flex ' ,
378
+ flexDirection : 'row ' ,
379
+ alignItems : 'center ' ,
328
380
justifyContent : 'center' ,
329
- paddingTop : '1em' ,
330
381
} }
331
382
>
332
- { /* display start to end value */ }
333
- < div style = { { gridColumnStart : 2 } } >
334
- { selectedRange ?. start } ~ { selectedRange ?. end }
383
+ < div >
384
+ < button
385
+ style = { { marginRight : '1em' } }
386
+ onClick = { ( ) => handleArrowClick ( 'left' ) }
387
+ >
388
+ < i className = "fa fa-arrow-left" aria-hidden = "true" > </ i >
389
+ </ button >
390
+ </ div >
391
+ { /* add axis range control */ }
392
+ < AxisRangeControl
393
+ range = {
394
+ selectedRange != null
395
+ ? {
396
+ min : selectedRange . start ,
397
+ max : selectedRange . end ,
398
+ }
399
+ : undefined
400
+ }
401
+ onRangeChange = { handleAxisRangeChange }
402
+ valueType = { 'date' }
403
+ // set maxWidth
404
+ containerStyles = { {
405
+ maxWidth : '350px' ,
406
+ } }
407
+ // default height of the input element is 36.5 which may be too high for timeSlider
408
+ // thus, introduced new prop to control it
409
+ inputHeight = { 20 }
410
+ />
411
+ < div >
412
+ < button
413
+ style = { { marginLeft : '2em' } }
414
+ onClick = { ( ) => handleArrowClick ( 'right' ) }
415
+ >
416
+ < i className = "fa fa-arrow-right" aria-hidden = "true" > </ i >
417
+ </ button >
335
418
</ div >
336
419
</ div >
337
420
< TimeSlider
0 commit comments