@@ -315,13 +315,33 @@ export class LineChartService {
315315 this . _legendGroupHeight = Math . ceil ( labels . length / this . _legendGroupColumns ) * ChartCommons . LABEL_HEIGHT + 30 ;
316316 } ;
317317
318- return ( incomingData : EventResultDataDTO ) => {
318+ /**
319+ * Set the data for the legend after the incoming data is received
320+ */
321+ const setLegendData = ( incomingData : EventResultDataDTO ) => {
319322 if ( incomingData . series . length == 0 ) {
320323 return ;
321324 }
322325
326+ const labelDataMap = { } ;
327+ incomingData . series . forEach ( ( data : EventResultSeriesDTO ) => {
328+ if ( incomingData . summaryLabels . length > 0 && incomingData . summaryLabels [ 0 ] . key != "measurand" ) {
329+ data . identifier = this . translateMeasurand ( data ) ;
330+ }
331+ const key = this . generateKey ( data ) ;
332+ labelDataMap [ key ] = {
333+ text : data . identifier ,
334+ key : key ,
335+ show : true
336+ }
337+ } ) ;
338+ this . legendDataMap = labelDataMap ;
339+ } ;
340+
341+ return ( incomingData : EventResultDataDTO ) => {
323342 prepareCleanState ( ) ;
324343
344+ setLegendData ( incomingData ) ;
325345 const data : TimeSeries [ ] = prepareData ( incomingData ) ;
326346 const chart : D3Selection < D3BaseType , { } , D3ContainerElement , { } > = d3Select ( 'g#time-series-chart-drawing-area' ) ;
327347 const xScale : D3ScaleTime < number , number > = this . lineChartScaleService . getXScale ( data , this . _width ) ;
@@ -334,7 +354,7 @@ export class LineChartService {
334354 createContextMenu ( ) ;
335355 this . addBrush ( chart , xScale , yScale , data ) ;
336356
337- this . addLegendsToChart ( chart , incomingData ) ;
357+ this . addLegendsToChart ( chart , xScale , yScale , data ) ( ) ;
338358 this . setSummaryLabel ( chart , incomingData . summaryLabels ) ;
339359 this . addDataLinesToChart ( chart , xScale , yScale , data ) ;
340360
@@ -348,29 +368,6 @@ export class LineChartService {
348368 }
349369 } ) ( ) ;
350370
351- /**
352- * Set the data for the legend after the incoming data is received
353- */
354- public setLegendData ( incomingData : EventResultDataDTO ) {
355- if ( incomingData . series . length == 0 ) {
356- return ;
357- }
358-
359- const labelDataMap = { } ;
360- incomingData . series . forEach ( ( data : EventResultSeriesDTO ) => {
361- if ( incomingData . summaryLabels . length > 0 && incomingData . summaryLabels [ 0 ] . key != "measurand" ) {
362- data . identifier = this . translateMeasurand ( data ) ;
363- }
364- const key = this . generateKey ( data ) ;
365- labelDataMap [ key ] = {
366- text : data . identifier ,
367- key : key ,
368- show : true
369- }
370- } ) ;
371- this . legendDataMap = labelDataMap ;
372- }
373-
374371 private translateMeasurand ( data : EventResultSeriesDTO ) : string {
375372 const splitLabelList : string [ ] = data . identifier . split ( ' | ' ) ;
376373 const splitLabel : string = this . translationService . instant ( 'frontend.de.iteratec.isr.measurand.' + splitLabelList [ 0 ] ) ;
@@ -769,8 +766,8 @@ export class LineChartService {
769766 . transition ( )
770767 . duration ( 500 )
771768 . style ( 'opacity' , ( timeSeries : TimeSeries ) => {
772- return ( this . legendDataMap [ timeSeries . key ] . show ) ? '1' : '0.1' ;
773- } ) ;
769+ return ( this . legendDataMap [ timeSeries . key ] . show ) ? '1' : '0.1' ;
770+ } ) ;
774771 } ;
775772
776773 const addDataPointsToChart = ( timeSeries : TimeSeries [ ] , xScale : D3ScaleTime < number , number > , yScale : D3ScaleLinear < number , number > ) : void => {
@@ -860,18 +857,22 @@ export class LineChartService {
860857 } )
861858 }
862859
860+ private hideMarker ( ) {
861+ d3Select ( '.marker-line' ) . style ( 'opacity' , 0 ) ;
862+ d3Select ( '#marker-tooltip' ) . style ( 'opacity' , 0 ) ;
863+ this . hideOldDotsOnMarker ( ) ;
864+ } ;
865+
863866 private prepareMouseEventCatcher = ( ( ) => {
864867 const showMarker = ( ) => {
868+ if ( this . _dotsOnMarker && this . _dotsOnMarker . empty ( ) ) {
869+ return ;
870+ }
871+
865872 d3Select ( '.marker-line' ) . style ( 'opacity' , 1 ) ;
866873 d3Select ( '#marker-tooltip' ) . style ( 'opacity' , 1 ) ;
867874 } ;
868875
869- const hideMarker = ( ) => {
870- d3Select ( '.marker-line' ) . style ( 'opacity' , 0 ) ;
871- d3Select ( '#marker-tooltip' ) . style ( 'opacity' , 0 ) ;
872- this . hideOldDotsOnMarker ( ) ;
873- } ;
874-
875876 return ( chart : D3Selection < D3BaseType , { } , D3ContainerElement , { } > ) => {
876877 if ( ! chart . select ( '.chart-content' ) . empty ( ) ) {
877878 return ;
@@ -884,7 +885,7 @@ export class LineChartService {
884885 . attr ( 'height' , this . _height )
885886 . attr ( 'fill' , 'none' )
886887 . on ( 'mouseenter' , ( ) => showMarker ( ) )
887- . on ( 'mouseleave' , ( ) => hideMarker ( ) )
888+ . on ( 'mouseleave' , ( ) => this . hideMarker ( ) )
888889 . on ( "contextmenu" , ( ) => d3Event . preventDefault ( ) )
889890 . on ( 'mousemove' , ( _ , index , nodes : D3ContainerElement [ ] ) => {
890891 this . moveMarker ( nodes [ index ] , this . _height )
@@ -927,19 +928,13 @@ export class LineChartService {
927928 }
928929 } ;
929930
930- private moveMarker ( node : D3ContainerElement , containerHeight : number ) {
931- const mouseCoordinates = d3Mouse ( node ) ;
932-
933- if ( this . _xAxisCluster . length < 2 ) {
934- return ;
935- }
936-
931+ private moveMarker = ( ( ) => {
937932 const pointsCompareDistance = ( p1 , p2 ) : number => {
938933 // Taxicab/Manhattan approximation of euclidean distance
939934 return Math . abs ( p1 . x - p2 . x ) + Math . abs ( p1 . y - p2 . y ) ;
940935 } ;
941936
942- const findNearestDot = ( dots ) => {
937+ const findNearestDot = ( mouseCoordinates : [ number , number ] , dots ) => {
943938 const mousePosition = { x : mouseCoordinates [ 0 ] , y : mouseCoordinates [ 1 ] } ;
944939
945940 let nearestDot = null ;
@@ -983,21 +978,34 @@ export class LineChartService {
983978 } ) ;
984979 } ;
985980
986- const nearestDot = findNearestDot ( d3SelectAll ( '.dot' ) ) ;
987- const markerPositionX = nearestDot . attr ( 'cx' ) ;
988- //draw marker line
989- const markerPath = `M${ markerPositionX } ,${ containerHeight } ${ markerPositionX } ,0` ;
990- d3Select ( '.marker-line' ) . attr ( 'd' , markerPath ) ;
981+ return ( node : D3ContainerElement , containerHeight : number ) => {
982+ if ( this . _xAxisCluster . length < 2 ) {
983+ return ;
984+ }
991985
992- this . hideOldDotsOnMarker ( ) ;
993- const dotsOnMarker = findDotsOnMarker ( markerPositionX ) ;
994- showDotsOnMarker ( dotsOnMarker ) ;
995- nearestDot . attr ( 'r' , this . DOT_HIGHLIGHT_RADIUS ) ;
986+ const nearestDot = findNearestDot ( d3Mouse ( node ) , d3SelectAll ( '.dot' ) ) ;
996987
997- this . _dotsOnMarker = dotsOnMarker ;
988+ if ( ! nearestDot ) {
989+ this . _dotsOnMarker = d3Select ( null ) ;
990+ this . hideMarker ( ) ;
991+ return ;
992+ }
998993
999- this . showTooltip ( nearestDot , dotsOnMarker , nearestDot . datum ( ) . date ) ;
1000- }
994+ const markerPositionX = nearestDot . attr ( 'cx' ) ;
995+ //draw marker line
996+ const markerPath = `M${ markerPositionX } ,${ containerHeight } ${ markerPositionX } ,0` ;
997+ d3Select ( '.marker-line' ) . attr ( 'd' , markerPath ) ;
998+
999+ this . hideOldDotsOnMarker ( ) ;
1000+ const dotsOnMarker = findDotsOnMarker ( markerPositionX ) ;
1001+ showDotsOnMarker ( dotsOnMarker ) ;
1002+ nearestDot . attr ( 'r' , this . DOT_HIGHLIGHT_RADIUS ) ;
1003+
1004+ this . _dotsOnMarker = dotsOnMarker ;
1005+
1006+ this . showTooltip ( nearestDot , dotsOnMarker , nearestDot . datum ( ) . date ) ;
1007+ } ;
1008+ } ) ( ) ;
10011009
10021010 private showContextMenu ( menu : ContextMenuPosition [ ] ) {
10031011 // this gets executed when a contextmenu event occurs
@@ -1181,8 +1189,8 @@ export class LineChartService {
11811189 } ;
11821190 } ) ( ) ;
11831191
1184- private addLegendsToChart = ( ( ) => {
1185- const onLegendClick = ( labelKey : string , incomingData : EventResultDataDTO ) : void => {
1192+ private addLegendsToChart = ( ( chart , xScale , yScale , data : TimeSeries [ ] ) => {
1193+ const onLegendClick = ( labelKey : string ) : void => {
11861194 if ( d3Event . metaKey || d3Event . ctrlKey ) {
11871195 this . legendDataMap [ labelKey ] . show = ! this . legendDataMap [ labelKey ] . show ;
11881196 } else {
@@ -1204,7 +1212,9 @@ export class LineChartService {
12041212 }
12051213
12061214 //redraw chart
1207- this . drawLineChart ( incomingData ) ;
1215+ this . addDataLinesToChart ( chart , xScale , yScale , data ) ;
1216+ //redraw legend
1217+ drawLegend ( ) ;
12081218 } ;
12091219
12101220 const getPosition = ( index : number ) : string => {
@@ -1214,7 +1224,7 @@ export class LineChartService {
12141224 return "translate(" + x + "," + y + ")" ;
12151225 } ;
12161226
1217- return ( chart : D3Selection < D3BaseType , { } , D3ContainerElement , { } > , incomingData : EventResultDataDTO ) : void => {
1227+ const drawLegend = ( ) => {
12181228 const legendGroup = d3Select ( '.legend-group' ) ;
12191229
12201230 // Remove old legend elements
@@ -1239,7 +1249,7 @@ export class LineChartService {
12391249 . attr ( "rx" , 2 )
12401250 . attr ( "ry" , 2 )
12411251 . attr ( 'fill' , ( key : string , index : number ) => {
1242- return getColorScheme ( ) [ incomingData . series . length - index - 1 ]
1252+ return getColorScheme ( ) [ data . length - index - 1 ]
12431253 } ) ;
12441254 legendElement
12451255 . append ( 'text' )
@@ -1257,7 +1267,11 @@ export class LineChartService {
12571267 . remove ( )
12581268 )
12591269 . attr ( "transform" , ( _ , index : number ) => getPosition ( index ) )
1260- . on ( 'click' , ( datum : string ) => onLegendClick ( datum , incomingData ) ) ;
1270+ . on ( 'click' , ( datum : string ) => onLegendClick ( datum ) ) ;
12611271 } ;
1262- } ) ( ) ;
1272+
1273+ return ( ) : void => {
1274+ drawLegend ( ) ;
1275+ } ;
1276+ } ) ;
12631277}
0 commit comments