@@ -4,9 +4,6 @@ import debugLogger from 'ember-debug-logger';
4
4
import { Timestamp } from 'explorviz-frontend/utils/landscape-schemes/timestamp' ;
5
5
import Plotly from 'plotly.js-dist' ;
6
6
// #region Template Imports
7
- import { on } from ' @ember/modifier' ;
8
- import didInsert from ' @ember/render-modifiers/modifiers/did-insert' ;
9
- import didUpdate from ' @ember/render-modifiers/modifiers/did-update' ;
10
7
import { TimelineDataObject } from 'explorviz-frontend/utils/timeline/timeline-data-object-handler' ;
11
8
// #endregion
12
9
@@ -41,6 +38,9 @@ export default class PlotlyTimeline extends Component<IArgs> {
41
38
42
39
plotlyTimestampsWithoutNullValues : any ;
43
40
41
+ minRequestFilter = 10 ;
42
+ maxRequestFilter = Number . MAX_SAFE_INTEGER ;
43
+
44
44
// BEGIN template-argument getters for default values
45
45
get defaultMarkerColor ( ) {
46
46
return '#1f77b4' ;
@@ -356,7 +356,7 @@ export default class PlotlyTimeline extends Component<IArgs> {
356
356
}
357
357
358
358
this . debug ( 'updateMarkerStates' ) ;
359
- this .resetHighlingInStateObjects ();
359
+ this . resetHighlightInStateObjects ( ) ;
360
360
361
361
for ( const [
362
362
commitId ,
@@ -376,10 +376,12 @@ export default class PlotlyTimeline extends Component<IArgs> {
376
376
377
377
selectedTimestampsForCommit . forEach ( ( timestamp ) => {
378
378
const timestampId = timestamp . epochMilli ;
379
- markerStates [timestampId ].color =
380
- timelineDataForCommit .highlightedMarkerColor ;
381
- markerStates [timestampId ].size = this .highlightedMarkerSize ;
382
- markerStates [timestampId ].emberModel = timestamp ;
379
+ if ( markerStates [ timestampId ] ) {
380
+ markerStates [ timestampId ] . color =
381
+ timelineDataForCommit . highlightedMarkerColor ;
382
+ markerStates [ timestampId ] . size = this . highlightedMarkerSize ;
383
+ markerStates [ timestampId ] . emberModel = timestamp ;
384
+ }
383
385
} ) ;
384
386
this . markerStateMap . set ( commitId , markerStates ) ;
385
387
}
@@ -502,6 +504,30 @@ export default class PlotlyTimeline extends Component<IArgs> {
502
504
} ;
503
505
}
504
506
507
+ autoScale ( ) {
508
+ Plotly . relayout ( this . timelineDiv , {
509
+ 'xaxis.autorange' : true ,
510
+ 'yaxis.autorange' : true ,
511
+ } ) ;
512
+ }
513
+
514
+ @action
515
+ setMinRequestFilter ( event : any ) {
516
+ const minRequestInput = event . target . value ;
517
+ this . minRequestFilter = Number . parseInt ( minRequestInput ) || 0 ;
518
+ this . updatePlotlyTimelineChart ( ) ;
519
+ this . autoScale ( ) ;
520
+ }
521
+
522
+ @action
523
+ setMaxRequestFilter ( event : any ) {
524
+ const maxRequestInput = event . target . value ;
525
+ this . maxRequestFilter =
526
+ Number . parseInt ( maxRequestInput ) || Number . MAX_SAFE_INTEGER ;
527
+ this . updatePlotlyTimelineChart ( ) ;
528
+ this . autoScale ( ) ;
529
+ }
530
+
505
531
hoverText ( x : ( string | null ) [ ] , y : ( number | null ) [ ] , commit : string ) {
506
532
return x . map (
507
533
( xi , i ) =>
@@ -518,10 +544,10 @@ export default class PlotlyTimeline extends Component<IArgs> {
518
544
hoverdistance : 3 ,
519
545
hovermode : 'closest' ,
520
546
margin : {
521
- b: 40 ,
522
- pad: 5 ,
523
- t: 40 ,
524
- r: 40 ,
547
+ b : 50 ,
548
+ pad : 0 ,
549
+ t : 0 ,
550
+ r : 20 ,
525
551
} ,
526
552
yaxis : {
527
553
fixedrange : true ,
@@ -539,7 +565,7 @@ export default class PlotlyTimeline extends Component<IArgs> {
539
565
}
540
566
541
567
getUpdatedPlotlyDataObject (
542
- timestampsOfOneCommit : Timestamp [],
568
+ unfilteredTimestampsOfOneCommit : Timestamp [ ] ,
543
569
markerStatesOfOneCommit : IMarkerStates ,
544
570
commitId : string
545
571
) {
@@ -551,25 +577,39 @@ export default class PlotlyTimeline extends Component<IArgs> {
551
577
. replace ( '.000Z' , '' ) ;
552
578
}
553
579
554
- function getGapRectangleObj () {
580
+ function getDashedLine ( ) {
555
581
return {
556
582
layer : 'below' ,
557
- type: ' rect ' ,
583
+ type : 'line ' ,
558
584
xref : 'x' ,
559
- yref: ' paper ' ,
585
+ yref : 'y ' ,
560
586
x0 : '0' ,
561
587
y0 : 0.1 ,
562
588
x1 : '0' ,
563
589
y1 : 1 ,
564
590
fillcolor : '#d3d3d3' ,
565
591
opacity : 0.4 ,
566
592
line : {
567
- width: 3 ,
593
+ width : 1 ,
568
594
dash : 'dot' ,
569
595
} ,
570
596
} ;
571
597
}
572
598
599
+ function styleNewDayIndicator ( gapIndicator : any ) {
600
+ gapIndicator . type = 'rect' ;
601
+ gapIndicator . yref = 'paper' ;
602
+ gapIndicator . y0 = 0.05 ;
603
+ gapIndicator . y1 = 1 ;
604
+ gapIndicator . fillcolor = '#ff0000' ;
605
+ }
606
+
607
+ const timestampsOfOneCommit = unfilteredTimestampsOfOneCommit . filter (
608
+ ( timestamp ) =>
609
+ timestamp . spanCount > this . minRequestFilter &&
610
+ timestamp . spanCount < this . maxRequestFilter
611
+ ) ;
612
+
573
613
const colors : string [ ] = [ ] ;
574
614
const sizes : number [ ] = [ ] ;
575
615
@@ -580,59 +620,75 @@ export default class PlotlyTimeline extends Component<IArgs> {
580
620
581
621
const shapes = [ ] ;
582
622
583
- let tempGapRectObj = null ;
623
+ let tempGapIndicator = null ;
584
624
585
625
let nextExpectedTimestamp = 0 ;
586
626
let i = 0 ;
587
627
628
+ const TIMESTAMP_INTERVAL = 10000 ;
629
+
588
630
while ( i < timestampsOfOneCommit . length ) {
589
631
const timestamp = timestampsOfOneCommit [ i ] ;
590
632
const timestampId = timestamp . epochMilli ;
591
633
592
- // only add real timestamps and shapes in the data arrays
593
- let addCurentTimestampToDataObject = false ;
634
+ // Only add real timestamps and shapes in the data arrays
635
+ let addCurrentTimestampToDataObject = false ;
594
636
595
637
if ( nextExpectedTimestamp === 0 ) {
596
- // first timestamp in series
638
+ // First timestamp, must exist do to while loop condition
597
639
x . push ( getTimestampTickLabel ( timestampId ) ) ;
598
640
y . push ( timestamp . spanCount ) ;
599
- nextExpectedTimestamp = timestampId ;
641
+ nextExpectedTimestamp = timestampId + TIMESTAMP_INTERVAL ;
600
642
i ++ ;
601
- addCurentTimestampToDataObject = true ;
602
- } else if (nextExpectedTimestamp == = timestampId ) {
603
- // subsequent timestamps
643
+ addCurrentTimestampToDataObject = true ;
644
+ } else if ( nextExpectedTimestamp > = timestampId ) {
645
+ // Next timestamp is within expected time frame
604
646
x . push ( getTimestampTickLabel ( timestampId ) ) ;
605
647
y . push ( timestamp . spanCount ) ;
606
648
i ++ ;
607
- if (tempGapRectObj ) {
608
- tempGapRectObj .x1 = getTimestampTickLabel (timestampId );
609
- shapes .push (tempGapRectObj );
610
- tempGapRectObj = null ;
649
+ // Add missing coordinates to gap indicator
650
+ if ( tempGapIndicator ) {
651
+ tempGapIndicator . x1 = getTimestampTickLabel ( timestampId ) ;
652
+ tempGapIndicator . y1 = timestamp . spanCount ;
653
+ const END_OF_ISO_DATE = 10 ;
654
+ if (
655
+ tempGapIndicator . x0 . substring ( 0 , END_OF_ISO_DATE ) !=
656
+ tempGapIndicator . x1 . substring ( 0 , END_OF_ISO_DATE )
657
+ ) {
658
+ styleNewDayIndicator ( tempGapIndicator ) ;
659
+ }
660
+
661
+ shapes . push ( tempGapIndicator ) ;
662
+ tempGapIndicator = null ;
611
663
}
612
- addCurentTimestampToDataObject = true ;
664
+ addCurrentTimestampToDataObject = true ;
665
+ nextExpectedTimestamp = timestampId + TIMESTAMP_INTERVAL ;
613
666
} else if ( timestamp . epochMilli === null ) {
614
- // edge case if API will return null values in the future
667
+ // Edge case if API will return null values in the future
615
668
x . push ( null ) ;
616
669
y . push ( null ) ;
617
670
i ++ ;
618
671
} else {
619
- // gap fills for timestamps that did not occur
620
- if (! tempGapRectObj ) {
621
- addCurentTimestampToDataObject = true ;
672
+ // Gap fills for missing timestamps (outside of expected timestamp interval)
673
+ if ( ! tempGapIndicator ) {
674
+ addCurrentTimestampToDataObject = true ;
622
675
x . push ( null ) ;
623
676
y . push ( null ) ;
624
- tempGapRectObj = getGapRectangleObj ();
625
- tempGapRectObj .x0 = getTimestampTickLabel (
626
- nextExpectedTimestamp - 10000
627
- );
677
+ tempGapIndicator = getDashedLine ( ) ;
678
+ const lastNonNullTimestamp =
679
+ nextExpectedTimestamp - TIMESTAMP_INTERVAL ;
680
+ tempGapIndicator . x0 = getTimestampTickLabel ( lastNonNullTimestamp ) ;
681
+ // Get last non-null value
682
+ tempGapIndicator . y0 = y . filter ( ( y ) => y != null ) . at ( - 1 ) ! ;
628
683
}
684
+ nextExpectedTimestamp =
685
+ timestampsOfOneCommit [ i ] . epochMilli ||
686
+ timestampId + TIMESTAMP_INTERVAL ;
629
687
}
630
688
631
- nextExpectedTimestamp += 10000 ;
632
-
633
689
const markerState = markerStatesOfOneCommit [ timestampId ] ;
634
690
635
- if (addCurentTimestampToDataObject ) {
691
+ if ( addCurrentTimestampToDataObject ) {
636
692
if ( markerState ) {
637
693
colors . push ( markerState . color ) ;
638
694
sizes . push ( markerState . size ) ;
@@ -651,7 +707,7 @@ export default class PlotlyTimeline extends Component<IArgs> {
651
707
}
652
708
timestampIds . push ( timestampId ) ;
653
709
}
654
- addCurentTimestampToDataObject = false ;
710
+ addCurrentTimestampToDataObject = false ;
655
711
}
656
712
657
713
this . markerStateMap . set ( commitId , markerStatesOfOneCommit ) ;
@@ -690,7 +746,7 @@ export default class PlotlyTimeline extends Component<IArgs> {
690
746
} ;
691
747
}
692
748
693
- resetHighlingInStateObjects () {
749
+ resetHighlightInStateObjects ( ) {
694
750
this . selectedCommitTimestampsMap = new Map ( ) ;
695
751
this . markerStateMap = new Map ( ) ;
696
752
}
@@ -718,29 +774,4 @@ export default class PlotlyTimeline extends Component<IArgs> {
718
774
}
719
775
720
776
// END Helper functions
721
-
722
- <template >
723
- {{#if this . showDummyTimeline }}
724
- <div class =' timeline-no-timestamps-outer' >
725
- <div class =' timeline-no-timestamps-inner' >
726
- No timestamps available!
727
- </div >
728
- </div >
729
- <div
730
- class =' plotlyDiv timeline-blur-effect'
731
- {{didInsert this . setupPlotlyTimelineChart}}
732
- >
733
- </div >
734
-
735
- {{else }}
736
- <div
737
- class =' plotlyDiv'
738
- {{on ' mouseenter' this . handleMouseEnter}}
739
- {{on ' mouseleave' this . handleMouseLeave}}
740
- {{didUpdate this . updatePlotlyTimelineChart @ timelineDataObject}}
741
- {{didInsert this . setupPlotlyTimelineChart}}
742
- >
743
- </div >
744
- {{/if }}
745
- </template >
746
777
}
0 commit comments