@@ -560,8 +560,6 @@ export class Timeline implements powerbi.extensibility.visual.IVisual {
560560 private cursorGroupSelection : D3Selection < any , any , any , any > ;
561561 private selectorSelection : D3Selection < any , any , any , any > ;
562562
563- private selectionManager : powerbi . extensibility . ISelectionManager ;
564-
565563 private options : powerbi . extensibility . visual . VisualUpdateOptions ;
566564 private dataView : powerbi . DataView ;
567565
@@ -581,30 +579,16 @@ export class Timeline implements powerbi.extensibility.visual.IVisual {
581579
582580 private selectedGranulaPos : number = null ;
583581
582+ private isForceSelectionReset : boolean = false ;
583+
584584 private cursorDragBehavior = d3Drag < any , ICursorDataPoint > ( )
585585 . subject ( ( cursorDataPoint : ICursorDataPoint ) => {
586586 cursorDataPoint . x = cursorDataPoint . selectionIndex * this . timelineProperties . cellWidth ;
587587
588588 return cursorDataPoint ;
589589 } )
590- . on ( "drag" , ( cursorDataPoint : ICursorDataPoint ) => {
591- if ( this . settings . forceSelection . currentPeriod
592- || this . settings . forceSelection . latestAvailableDate
593- ) {
594- return ;
595- }
596-
597- this . onCursorDrag ( cursorDataPoint ) ;
598- } )
599- . on ( "end" , ( ) => {
600- if ( this . settings . forceSelection . currentPeriod
601- || this . settings . forceSelection . latestAvailableDate
602- ) {
603- return ;
604- }
605-
606- this . onCursorDragEnd ( ) ;
607- } ) ;
590+ . on ( "drag" , this . onCursorDrag . bind ( this ) )
591+ . on ( "end" , this . onCursorDragEnd . bind ( this ) ) ;
608592
609593 constructor ( options : powerbi . extensibility . visual . VisualConstructorOptions ) {
610594 const element : HTMLElement = options . element ;
@@ -614,7 +598,6 @@ export class Timeline implements powerbi.extensibility.visual.IVisual {
614598 this . initialized = false ;
615599 this . locale = this . host . locale ;
616600
617- this . selectionManager = this . host . createSelectionManager ( ) ;
618601 this . localizationManager = this . host . createLocalizationManager ( ) ;
619602
620603 this . timelineProperties = {
@@ -634,13 +617,7 @@ export class Timeline implements powerbi.extensibility.visual.IVisual {
634617 this . rootSelection = d3Select ( element )
635618 . append ( "div" )
636619 . classed ( "timeline-component" , true )
637- . on ( "click" , ( ) => {
638- if ( ! this . settings . forceSelection . currentPeriod
639- && ! this . settings . forceSelection . latestAvailableDate
640- ) {
641- this . clear ( ) ;
642- }
643- } ) ;
620+ . on ( "click" , ( ) => this . clearUserSelection ( ) ) ;
644621
645622 this . headerSelection = this . rootSelection
646623 . append ( "svg" )
@@ -658,14 +635,13 @@ export class Timeline implements powerbi.extensibility.visual.IVisual {
658635 this . addElements ( ) ;
659636 }
660637
661- public clear ( ) : void {
662- if ( this . initialized ) {
663- this . selectionManager . clear ( ) ;
664-
665- if ( this . timelineData ) {
666- this . clearSelection ( this . timelineData . filterColumnTarget ) ;
667- }
638+ public clearUserSelection ( ) : void {
639+ if ( ! this . initialized || ! this . timelineData ) {
640+ return ;
668641 }
642+
643+ this . clearSelection ( this . timelineData . filterColumnTarget ) ;
644+ this . toggleForceSelectionOptions ( ) ;
669645 }
670646
671647 public doesPeriodSlicerRectPositionNeedToUpdate ( granularity : GranularityType ) : boolean {
@@ -757,33 +733,44 @@ export class Timeline implements powerbi.extensibility.visual.IVisual {
757733 const datePeriod : ITimelineDatePeriodBase = this . datePeriod ;
758734
759735 const granularity = this . settings . granularity . granularity ;
760- const currentForceSelection : boolean = this . settings . forceSelection . currentPeriod ;
761- const latestAvailableDate : boolean = this . settings . forceSelection . latestAvailableDate ;
762- const isUserSelection : boolean = ! currentForceSelection && ! latestAvailableDate ;
736+
737+ const isCurrentPeriodSelected : boolean = ! this . isForceSelectionReset && this . settings . forceSelection . currentPeriod ;
738+ const isLatestAvailableDateSelected : boolean = ! this . isForceSelectionReset && this . settings . forceSelection . latestAvailableDate ;
739+ const isForceSelected : boolean = ! this . isForceSelectionReset && ( isCurrentPeriodSelected || isLatestAvailableDateSelected ) ;
740+
741+ this . isForceSelectionReset = false ; // Reset it to default state to allow re-enabling Force Selection
742+
763743 const target : IFilterColumnTarget = this . timelineData . filterColumnTarget ;
764744
765745 let currentForceSelectionResult = { startDate : null , endDate : null } ;
766746
767- if ( currentForceSelection ) {
747+ if ( isCurrentPeriodSelected ) {
768748 currentForceSelectionResult = ( {
769749 endDate : filterDatePeriod . endDate ,
770750 startDate : filterDatePeriod . startDate ,
771751 } = Timeline . selectCurrentPeriod ( datePeriod , granularity , this . calendar ) ) ;
772752 }
773- if ( latestAvailableDate && ( ! currentForceSelection ||
774- ( currentForceSelection && ! currentForceSelectionResult . startDate && ! currentForceSelectionResult . endDate ) ) ) {
753+ if ( isLatestAvailableDateSelected
754+ && (
755+ ! isCurrentPeriodSelected
756+ || ( isCurrentPeriodSelected
757+ && ! currentForceSelectionResult . startDate
758+ && ! currentForceSelectionResult . endDate
759+ )
760+ )
761+ ) {
775762 filterDatePeriod . endDate = adaptedDataEndDate ;
776763 ( {
777764 endDate : filterDatePeriod . endDate ,
778765 startDate : filterDatePeriod . startDate ,
779766 } = Timeline . selectPeriod ( datePeriod , granularity , this . calendar , this . datePeriod . endDate ) ) ;
780767 }
781768
782- const filterWasChanged : boolean =
769+ const wasFilterChanged : boolean =
783770 String ( this . prevFilteredStartDate ) !== String ( filterDatePeriod . startDate ) ||
784771 String ( this . prevFilteredEndDate ) !== String ( filterDatePeriod . endDate ) ;
785772
786- if ( ( ! isUserSelection && filterWasChanged ) ) {
773+ if ( isForceSelected && wasFilterChanged ) {
787774 this . applyDatePeriod ( filterDatePeriod . startDate , filterDatePeriod . endDate , target ) ;
788775 }
789776
@@ -876,25 +863,16 @@ export class Timeline implements powerbi.extensibility.visual.IVisual {
876863 . selectAll ( Timeline . TimelineSelectors . CellRect . selectorName )
877864 . data ( dataPoints ) ;
878865
879- const clickHandler = ( dataPoint : ITimelineDataPoint , index : number ) => {
880- // If something from Force Selection settings group is enabled, any user filters has no sense
881- if ( this . settings . forceSelection . currentPeriod || this . settings . forceSelection . latestAvailableDate ) {
882- return ;
883- }
884-
885- const event : MouseEvent = require ( "d3" ) . event as MouseEvent ;
886-
887- event . stopPropagation ( ) ;
888-
889- this . onCellClickHandler ( dataPoint , index , event . altKey || event . shiftKey ) ;
890- } ;
866+ cellsSelection
867+ . exit ( )
868+ . remove ( ) ;
891869
892870 cellsSelection
893871 . enter ( )
894872 . append ( "rect" )
895873 . classed ( Timeline . TimelineSelectors . CellRect . className , true )
896- . on ( "click" , clickHandler )
897- . on ( "touchstart" , clickHandler )
874+ . on ( "click" , this . handleClick . bind ( this ) )
875+ . on ( "touchstart" , this . handleClick . bind ( this ) )
898876 . merge ( cellsSelection )
899877 . attr ( "x" , ( dataPoint : ITimelineDataPoint ) => {
900878 const position : number = totalX ;
@@ -910,10 +888,6 @@ export class Timeline implements powerbi.extensibility.visual.IVisual {
910888 } ) ;
911889
912890 this . fillCells ( this . settings ) ;
913-
914- cellsSelection
915- . exit ( )
916- . remove ( ) ;
917891 }
918892
919893 public renderCursors (
@@ -1175,15 +1149,18 @@ export class Timeline implements powerbi.extensibility.visual.IVisual {
11751149
11761150 public onCursorDragEnd ( ) : void {
11771151 this . setSelection ( this . timelineData ) ;
1152+ this . toggleForceSelectionOptions ( ) ;
11781153 }
11791154
1180- private addElements ( ) : void {
1181- this . rootSelection . on ( "click" , ( ) => {
1182- if ( ! this . settings . forceSelection . currentPeriod && ! this . settings . forceSelection . latestAvailableDate ) {
1183- this . clear ( ) ;
1184- }
1185- } ) ;
1155+ private handleClick ( dataPoint : ITimelineDataPoint , index : number ) : void {
1156+ const event : MouseEvent = require ( "d3" ) . event as MouseEvent ;
1157+
1158+ event . stopPropagation ( ) ;
11861159
1160+ this . onCellClickHandler ( dataPoint , index , event . altKey || event . shiftKey ) ;
1161+ }
1162+
1163+ private addElements ( ) : void {
11871164 this . rangeTextSelection = this . headerSelection
11881165 . append ( "g" )
11891166 . classed ( Timeline . TimelineSelectors . RangeTextArea . className , true )
@@ -1537,7 +1514,9 @@ export class Timeline implements powerbi.extensibility.visual.IVisual {
15371514 ) ;
15381515
15391516 this . renderTimeRangeText ( timelineData , this . settings . rangeHeader ) ;
1517+
15401518 this . setSelection ( timelineData ) ;
1519+ this . toggleForceSelectionOptions ( ) ;
15411520 }
15421521
15431522 private scrollAutoFocusFunc ( selectedGranulaPos : number ) : void {
@@ -1547,4 +1526,28 @@ export class Timeline implements powerbi.extensibility.visual.IVisual {
15471526
15481527 this . mainSvgWrapperSelection . node ( ) . scrollLeft = selectedGranulaPos - this . horizontalAutoScrollingPositionOffset ;
15491528 }
1529+
1530+ private toggleForceSelectionOptions ( ) : void {
1531+ const isForceSelectionTurnedOn : boolean = this . settings . forceSelection . currentPeriod
1532+ || this . settings . forceSelection . latestAvailableDate ;
1533+
1534+ if ( isForceSelectionTurnedOn ) {
1535+ this . turnOffForceSelectionOptions ( ) ;
1536+ }
1537+ }
1538+
1539+ private turnOffForceSelectionOptions ( ) : void {
1540+ this . host . persistProperties ( {
1541+ merge : [ {
1542+ objectName : "forceSelection" ,
1543+ properties : {
1544+ currentPeriod : false ,
1545+ latestAvailableDate : false ,
1546+ } ,
1547+ selector : null ,
1548+ } ] ,
1549+ } ) ;
1550+
1551+ this . isForceSelectionReset = true ;
1552+ }
15501553}
0 commit comments