@@ -113,6 +113,64 @@ export class ParallelPlot extends React.Component<ParallelPlotData, ParallelPlot
113113 return text . length ? text : fallback ;
114114 }
115115
116+ private normalizeBrushSelection ( sel : d3 . BrushSelection ) : [ number , number ] | null {
117+ if ( ! sel ) {
118+ return null ;
119+ }
120+ if ( Array . isArray ( sel [ 0 ] ) ) {
121+ const box = sel as [ [ number , number ] , [ number , number ] ] ;
122+ return [ box [ 0 ] [ 1 ] , box [ 1 ] [ 1 ] ] ;
123+ }
124+ return sel as [ number , number ] ;
125+ }
126+
127+ private getBrushExtents ( ) {
128+ const extents : { [ key : string ] : [ number , number ] | null } = { } ;
129+ if ( ! this . dimensions_dom ) {
130+ return extents ;
131+ }
132+ const self = this ;
133+ this . dimensions_dom . selectAll ( "." + style . brush ) . each ( function ( this : SVGGElement , dim : string ) {
134+ extents [ dim ] = self . normalizeBrushSelection ( d3 . brushSelection ( this ) ) ;
135+ } ) ;
136+ return extents ;
137+ }
138+
139+ toggleInvertAxis ( d : string ) {
140+ // save extent before inverting
141+ const extents = this . getBrushExtents ( ) ;
142+ const currentExtent = extents [ d ] ;
143+ const extent = currentExtent ? [ this . h - currentExtent [ 1 ] , this . h - currentExtent [ 0 ] ] : null ;
144+ const div = d3 . select ( this . root_ref . current ) ;
145+
146+ if ( this . state . invert . has ( d ) ) {
147+ this . setState ( function ( prevState ) {
148+ var newInvert = new Set ( prevState . invert ) ;
149+ newInvert . delete ( d ) ;
150+ return {
151+ invert : newInvert
152+ } ;
153+ } ) ;
154+ this . setScaleRange ( d ) ;
155+ div . selectAll ( "." + style . label )
156+ . filter ( function ( p ) { return p == d ; } )
157+ . style ( "text-decoration" , null ) ;
158+ } else {
159+ this . setState ( function ( prevState ) {
160+ var newInvert = new Set ( prevState . invert ) ;
161+ newInvert . add ( d ) ;
162+ return {
163+ invert : newInvert
164+ } ;
165+ } ) ;
166+ this . setScaleRange ( d ) ;
167+ div . selectAll ( "." + style . label )
168+ . filter ( function ( p ) { return p == d ; } )
169+ . style ( "text-decoration" , "underline" ) ;
170+ }
171+ return extent ;
172+ }
173+
116174 constructor ( props : ParallelPlotData ) {
117175 super ( props ) ;
118176 this . state = {
@@ -389,8 +447,10 @@ export class ParallelPlot extends React.Component<ParallelPlotData, ParallelPlot
389447 . on ( "end" , function ( event , d : string ) {
390448 if ( ! me . state . dragging . dragging ) {
391449 // no movement, invert axis
392- var extent = invert_axis ( d ) ;
393- me . update_ticks ( d , extent ) ;
450+ if ( ! IS_MOBILE ) {
451+ var extent = me . toggleInvertAxis ( d ) ;
452+ me . update_ticks ( d , extent ) ;
453+ }
394454 } else {
395455 // remove axis if dragged all the way left
396456 if ( me . state . dragging . pos < 12 || me . state . dragging . pos > me . w - 12 ) {
@@ -458,20 +518,42 @@ export class ParallelPlot extends React.Component<ParallelPlotData, ParallelPlot
458518 if ( ! me . props . context_menu_ref || ! me . props . context_menu_ref . current ) {
459519 return ;
460520 }
521+ event . preventDefault ( ) ;
522+ event . stopPropagation ( ) ;
523+ ( target as any ) . __longPressFired = false ;
461524 const touch = ( event as TouchEvent ) . touches [ 0 ] ;
462525 const timer = window . setTimeout ( ( ) => {
463526 me . props . context_menu_ref . current . show ( touch . pageX , touch . pageY , dim ) ;
527+ ( target as any ) . __longPressFired = true ;
464528 ( target as any ) . __longPressTimer = null ;
465529 } , 500 ) ;
466530 ( target as any ) . __longPressTimer = timer ;
467531 } )
468- . on ( "touchend touchcancel touchmove" , function ( ) {
532+ . on ( "touchend touchcancel touchmove" , function ( event , dim : string ) {
469533 const target = this as SVGTextElement ;
470534 const timer = ( target as any ) . __longPressTimer ;
471535 if ( timer ) {
472536 window . clearTimeout ( timer ) ;
473537 ( target as any ) . __longPressTimer = null ;
474538 }
539+ if ( ( target as any ) . __longPressFired ) {
540+ event . preventDefault ( ) ;
541+ event . stopPropagation ( ) ;
542+ return ;
543+ }
544+ if ( event . type !== "touchend" ) {
545+ return ;
546+ }
547+ const isDragging = me . state . dragging && me . state . dragging . dragging ;
548+ if ( isDragging ) {
549+ return ;
550+ }
551+ if ( me . props . context_menu_ref && me . props . context_menu_ref . current ) {
552+ const touch = ( event as TouchEvent ) . changedTouches [ 0 ] ;
553+ me . props . context_menu_ref . current . show ( touch . pageX , touch . pageY , dim ) ;
554+ event . preventDefault ( ) ;
555+ event . stopPropagation ( ) ;
556+ }
475557 } ) ;
476558 me . updateAxisTitlesAnglesAndFontSize ( ) ;
477559 me . dimensions_dom . selectAll ( ".pplot-label" ) . call ( create_drag_beh ( ) ) ;
@@ -491,45 +573,8 @@ export class ParallelPlot extends React.Component<ParallelPlotData, ParallelPlot
491573 . text ( "Drag or resize this filter" ) ;
492574 } ;
493575
494- function invert_axis ( d : string ) {
495- // save extent before inverting
496- var extents = brush_extends ( ) ;
497- var extent = extents [ d ] !== null ? [ me . h - extents [ d ] [ 1 ] , me . h - extents [ d ] [ 0 ] ] : null ;
498-
499- if ( me . state . invert . has ( d ) ) {
500- me . setState ( function ( prevState , props ) {
501- var newInvert = new Set ( prevState . invert ) ;
502- newInvert . delete ( d ) ;
503- return {
504- invert : newInvert
505- } ;
506- } ) ;
507- me . setScaleRange ( d ) ;
508- div . selectAll ( "." + style . label )
509- . filter ( function ( p ) { return p == d ; } )
510- . style ( "text-decoration" , null ) ;
511- } else {
512- me . setState ( function ( prevState , props ) {
513- var newInvert = new Set ( prevState . invert ) ;
514- newInvert . add ( d ) ;
515- return {
516- invert : newInvert
517- } ;
518- } ) ;
519- me . setScaleRange ( d ) ;
520- div . selectAll ( "." + style . label )
521- . filter ( function ( p ) { return p == d ; } )
522- . style ( "text-decoration" , "underline" ) ;
523- }
524- return extent ;
525- }
526-
527576 function brush_extends ( ) {
528- var extents = { } ;
529- me . dimensions_dom . selectAll ( "." + style . brush ) . each ( function ( this : SVGGElement , dim : string ) {
530- extents [ dim ] = d3 . brushSelection ( this ) ;
531- } ) ;
532- return extents ;
577+ return me . getBrushExtents ( ) ;
533578 }
534579
535580 function brush ( ) {
@@ -539,7 +584,7 @@ export class ParallelPlot extends React.Component<ParallelPlotData, ParallelPlot
539584 if ( me . props . context_menu_ref !== undefined ) {
540585 me . props . context_menu_ref . current . hide ( ) ;
541586 }
542- var extents = brush_extends ( ) ;
587+ const extents : { [ key : string ] : [ number , number ] | null } = brush_extends ( ) ;
543588 var actives = me . state . dimensions . filter ( function ( p ) { return extents [ p ] !== null && extents [ p ] !== undefined ; } ) ;
544589
545590 // hack to hide ticks beyond extent
@@ -580,7 +625,7 @@ export class ParallelPlot extends React.Component<ParallelPlotData, ParallelPlot
580625 // Get lines within extents
581626 var filters : Array < Filter > = actives . map ( function ( dimension ) {
582627 const scale = me . yscale [ dimension ] ;
583- var extent = extents [ dimension ] ;
628+ const extent = extents [ dimension ] as [ number , number ] ;
584629 const range = scale_pixels_range ( scale , extent ) ;
585630 if ( range . type == ParamType . CATEGORICAL && ! range . values ) {
586631 // Select nothing
@@ -632,15 +677,15 @@ export class ParallelPlot extends React.Component<ParallelPlotData, ParallelPlot
632677 . forEach ( function ( d ) {
633678 if ( actives . every ( function ( dimension ) {
634679 var scale = me . yscale [ dimension ] ;
635- var extent = extents [ dimension ] ;
680+ var extent = extents [ dimension ] as [ number , number ] ;
636681 var value = d [ dimension ] ;
637682 return extent [ 0 ] + 1 <= scale ( value ) && scale ( value ) <= extent [ 1 ] - 1 ;
638683 } ) ) {
639684 selected_pixels_minset . push ( d ) ;
640685 }
641686 if ( actives . every ( function ( dimension ) {
642687 var scale = me . yscale [ dimension ] ;
643- var extent = extents [ dimension ] ;
688+ var extent = extents [ dimension ] as [ number , number ] ;
644689 var value = d [ dimension ] ;
645690 return extent [ 0 ] - 1 <= scale ( value ) && scale ( value ) <= extent [ 1 ] + 1 ;
646691 } ) ) {
0 commit comments