@@ -306,28 +306,40 @@ describe('Test shapes', function() {
306
306
var testCases = [
307
307
// xref: 'paper', yref: 'paper'
308
308
{
309
- title : 'linked to paper should be draggable '
309
+ title : 'linked to paper'
310
310
} ,
311
311
312
312
// xaxis.type: 'linear', yaxis.type: 'log'
313
313
{
314
- title : 'linked to linear and log axes should be draggable ' ,
314
+ title : 'linked to linear and log axes' ,
315
315
xaxis : { type : 'linear' , range : [ 0 , 10 ] } ,
316
316
yaxis : { type : 'log' , range : [ Math . log10 ( 1 ) , Math . log10 ( 1000 ) ] }
317
317
} ,
318
318
319
319
// xaxis.type: 'date', yaxis.type: 'category'
320
320
{
321
- title : 'linked to date and category axes should be draggable ' ,
321
+ title : 'linked to date and category axes' ,
322
322
xaxis : { type : 'date' , range : [ '2000-01-01' , '2000-01-02' ] } ,
323
323
yaxis : { type : 'category' , range : [ 'a' , 'b' ] }
324
324
}
325
325
] ;
326
326
327
327
testCases . forEach ( function ( testCase ) {
328
- it ( testCase . title , function ( done ) {
328
+ it ( testCase . title + 'should be draggable' , function ( done ) {
329
329
setupLayout ( testCase ) ;
330
- testAllShapes ( done ) ;
330
+ testDragEachShape ( done ) ;
331
+ } ) ;
332
+ } ) ;
333
+
334
+ testCases . forEach ( function ( testCase ) {
335
+ [ 'n' , 's' , 'w' , 'e' , 'nw' , 'se' , 'ne' , 'sw' ] . forEach ( function ( direction ) {
336
+ var testTitle = testCase . title +
337
+ 'should be resizeable over direction ' +
338
+ direction ;
339
+ it ( testTitle , function ( done ) {
340
+ setupLayout ( testCase ) ;
341
+ testResizeEachShape ( direction , done ) ;
342
+ } ) ;
331
343
} ) ;
332
344
} ) ;
333
345
@@ -392,21 +404,60 @@ describe('Test shapes', function() {
392
404
layout . shapes = layoutShapes ;
393
405
}
394
406
395
- function testAllShapes ( done ) {
407
+ function testDragEachShape ( done ) {
396
408
var promise = Plotly . plot ( gd , data , layout , config ) ;
397
409
398
410
var layoutShapes = gd . layout . shapes ;
399
411
400
412
expect ( layoutShapes . length ) . toBe ( 4 ) ; // line, rect, circle and path
401
413
402
414
layoutShapes . forEach ( function ( layoutShape , index ) {
415
+ var dx = 100 ,
416
+ dy = 100 ;
403
417
promise = promise . then ( function ( ) {
404
418
var node = getShapeNode ( index ) ;
405
419
expect ( node ) . not . toBe ( null ) ;
406
420
407
421
return ( layoutShape . path ) ?
408
- testPath ( layoutShape , node ) :
409
- testShape ( layoutShape , node ) ;
422
+ testPathDrag ( dx , dy , layoutShape , node ) :
423
+ testShapeDrag ( dx , dy , layoutShape , node ) ;
424
+ } ) ;
425
+ } ) ;
426
+
427
+ return promise . then ( done ) ;
428
+ }
429
+
430
+ function testResizeEachShape ( direction , done ) {
431
+ var promise = Plotly . plot ( gd , data , layout , config ) ;
432
+
433
+ var layoutShapes = gd . layout . shapes ;
434
+
435
+ expect ( layoutShapes . length ) . toBe ( 4 ) ; // line, rect, circle and path
436
+
437
+ var dxToShrinkWidth = {
438
+ n : 0 , s : 0 , w : 10 , e : - 10 , nw : 10 , se : - 10 , ne : - 10 , sw : 10
439
+ } ,
440
+ dyToShrinkHeight = {
441
+ n : 10 , s : - 10 , w : 0 , e : 0 , nw : 10 , se : - 10 , ne : 10 , sw : - 10
442
+ } ;
443
+ layoutShapes . forEach ( function ( layoutShape , index ) {
444
+ if ( layoutShape . path ) return ;
445
+
446
+ var dx = dxToShrinkWidth [ direction ] ,
447
+ dy = dyToShrinkHeight [ direction ] ;
448
+
449
+ promise = promise . then ( function ( ) {
450
+ var node = getShapeNode ( index ) ;
451
+ expect ( node ) . not . toBe ( null ) ;
452
+
453
+ return testShapeResize ( direction , dx , dy , layoutShape , node ) ;
454
+ } ) ;
455
+
456
+ promise = promise . then ( function ( ) {
457
+ var node = getShapeNode ( index ) ;
458
+ expect ( node ) . not . toBe ( null ) ;
459
+
460
+ return testShapeResize ( direction , - dx , - dy , layoutShape , node ) ;
410
461
} ) ;
411
462
} ) ;
412
463
@@ -419,15 +470,13 @@ describe('Test shapes', function() {
419
470
} ) . node ( ) ;
420
471
}
421
472
422
- function testShape ( layoutShape , node ) {
473
+ function testShapeDrag ( dx , dy , layoutShape , node ) {
423
474
var xa = Axes . getFromId ( gd , layoutShape . xref ) ,
424
475
ya = Axes . getFromId ( gd , layoutShape . yref ) ,
425
476
x2p = getDataToPixel ( gd , xa ) ,
426
477
y2p = getDataToPixel ( gd , ya , true ) ;
427
478
428
- var initialCoordinates = getShapeCoordinates ( layoutShape , x2p , y2p ) ,
429
- dx = 100 ,
430
- dy = 100 ;
479
+ var initialCoordinates = getShapeCoordinates ( layoutShape , x2p , y2p ) ;
431
480
432
481
return drag ( node , dx , dy ) . then ( function ( ) {
433
482
var finalCoordinates = getShapeCoordinates ( layoutShape , x2p , y2p ) ;
@@ -448,16 +497,14 @@ describe('Test shapes', function() {
448
497
} ;
449
498
}
450
499
451
- function testPath ( layoutShape , node ) {
500
+ function testPathDrag ( dx , dy , layoutShape , node ) {
452
501
var xa = Axes . getFromId ( gd , layoutShape . xref ) ,
453
502
ya = Axes . getFromId ( gd , layoutShape . yref ) ,
454
503
x2p = getDataToPixel ( gd , xa ) ,
455
504
y2p = getDataToPixel ( gd , ya , true ) ;
456
505
457
506
var initialPath = layoutShape . path ,
458
- initialCoordinates = getPathCoordinates ( initialPath , x2p , y2p ) ,
459
- dx = 100 ,
460
- dy = 100 ;
507
+ initialCoordinates = getPathCoordinates ( initialPath , x2p , y2p ) ;
461
508
462
509
expect ( initialCoordinates . length ) . toBe ( 6 ) ;
463
510
@@ -483,6 +530,51 @@ describe('Test shapes', function() {
483
530
} ) ;
484
531
}
485
532
533
+ function testShapeResize ( direction , dx , dy , layoutShape , node ) {
534
+ var xa = Axes . getFromId ( gd , layoutShape . xref ) ,
535
+ ya = Axes . getFromId ( gd , layoutShape . yref ) ,
536
+ x2p = getDataToPixel ( gd , xa ) ,
537
+ y2p = getDataToPixel ( gd , ya , true ) ;
538
+
539
+ var initialCoordinates = getShapeCoordinates ( layoutShape , x2p , y2p ) ;
540
+
541
+ return resize ( direction , node , dx , dy ) . then ( function ( ) {
542
+ var finalCoordinates = getShapeCoordinates ( layoutShape , x2p , y2p ) ;
543
+
544
+ var keyN , keyS , keyW , keyE ;
545
+ if ( initialCoordinates . y0 < initialCoordinates . y1 ) {
546
+ keyN = 'y0' ; keyS = 'y1' ;
547
+ }
548
+ else {
549
+ keyN = 'y1' ; keyS = 'y0' ;
550
+ }
551
+ if ( initialCoordinates . x0 < initialCoordinates . x1 ) {
552
+ keyW = 'x0' ; keyE = 'x1' ;
553
+ }
554
+ else {
555
+ keyW = 'x1' ; keyE = 'x0' ;
556
+ }
557
+
558
+ if ( ~ direction . indexOf ( 'n' ) ) {
559
+ expect ( finalCoordinates [ keyN ] - initialCoordinates [ keyN ] )
560
+ . toBeCloseTo ( dy ) ;
561
+ }
562
+ else if ( ~ direction . indexOf ( 's' ) ) {
563
+ expect ( finalCoordinates [ keyS ] - initialCoordinates [ keyS ] )
564
+ . toBeCloseTo ( dy ) ;
565
+ }
566
+
567
+ if ( ~ direction . indexOf ( 'w' ) ) {
568
+ expect ( finalCoordinates [ keyW ] - initialCoordinates [ keyW ] )
569
+ . toBeCloseTo ( dx ) ;
570
+ }
571
+ else if ( ~ direction . indexOf ( 'e' ) ) {
572
+ expect ( finalCoordinates [ keyE ] - initialCoordinates [ keyE ] )
573
+ . toBeCloseTo ( dx ) ;
574
+ }
575
+ } ) ;
576
+ }
577
+
486
578
// Adapted from src/components/shapes/index.js
487
579
var segmentRE = / [ M L H V Q C T S Z ] [ ^ M L H V Q C T S Z ] * / g,
488
580
paramRE = / [ ^ \s , ] + / g,
@@ -639,6 +731,34 @@ function drag(node, dx, dy) {
639
731
return promise ;
640
732
}
641
733
734
+ function resize ( direction , node , dx , dy ) {
735
+ var bbox = node . getBoundingClientRect ( ) ;
736
+
737
+ var fromX , fromY , toX , toY ;
738
+
739
+ if ( ~ direction . indexOf ( 'n' ) ) fromY = bbox . top ;
740
+ else if ( ~ direction . indexOf ( 's' ) ) fromY = bbox . bottom ;
741
+ else fromY = ( bbox . bottom + bbox . top ) / 2 ;
742
+
743
+ if ( ~ direction . indexOf ( 'w' ) ) fromX = bbox . left ;
744
+ else if ( ~ direction . indexOf ( 'e' ) ) fromX = bbox . right ;
745
+ else fromX = ( bbox . left + bbox . right ) / 2 ;
746
+
747
+ toX = fromX + dx ;
748
+ toY = fromY + dy ;
749
+
750
+ mouseMove ( node , fromX , fromY ) ;
751
+ mouseDown ( node , fromX , fromY ) ;
752
+
753
+ var promise = waitForDragCover ( ) . then ( function ( dragCoverNode ) {
754
+ mouseMove ( dragCoverNode , toX , toY ) ;
755
+ mouseUp ( dragCoverNode , toX , toY ) ;
756
+ return waitForDragCoverRemoval ( ) ;
757
+ } ) ;
758
+
759
+ return promise ;
760
+ }
761
+
642
762
function waitForDragCover ( ) {
643
763
return new Promise ( function ( resolve ) {
644
764
var interval = DBLCLICKDELAY / 4 ,
0 commit comments