1
- /*! JointJS v0.9.5 - JavaScript diagramming library 2015-12-11
1
+ /*! JointJS v0.9.5 - JavaScript diagramming library 2015-12-17
2
2
3
3
4
4
This Source Code Form is subject to the terms of the Mozilla Public
@@ -3969,7 +3969,7 @@ joint.dia.Graph = Backbone.Model.extend({
3969
3969
3970
3970
var cellsAncestors = _ . map ( arguments , function ( cell ) {
3971
3971
3972
- var ancestors = [ cell . id ] ;
3972
+ var ancestors = [ ] ;
3973
3973
var parentId = cell . get ( 'parent' ) ;
3974
3974
3975
3975
while ( parentId ) {
@@ -5086,7 +5086,7 @@ joint.dia.CellView = joint.mvc.View.extend({
5086
5086
return this . render ( ) ;
5087
5087
}
5088
5088
5089
- return this . update ( ) ;
5089
+ return this . update ( cell , attrs , opt ) ;
5090
5090
} ,
5091
5091
5092
5092
// Override the Backbone `_ensureElement()` method in order to create a `<g>` node that wraps
@@ -6530,11 +6530,11 @@ joint.dia.Link = joint.dia.Cell.extend({
6530
6530
var vertices = this . get ( 'vertices' ) ;
6531
6531
6532
6532
if ( ! source . id ) {
6533
- attrs . source = { x : source . x + tx , y : source . y + ty } ;
6533
+ attrs . source = { x : ( source . x || 0 ) + tx , y : ( source . y || 0 ) + ty } ;
6534
6534
}
6535
6535
6536
6536
if ( ! target . id ) {
6537
- attrs . target = { x : target . x + tx , y : target . y + ty } ;
6537
+ attrs . target = { x : ( target . x || 0 ) + tx , y : ( target . y || 0 ) + ty } ;
6538
6538
}
6539
6539
6540
6540
if ( vertices && vertices . length ) {
@@ -6543,6 +6543,12 @@ joint.dia.Link = joint.dia.Cell.extend({
6543
6543
} ) ;
6544
6544
}
6545
6545
6546
+ // enrich the option object
6547
+ opt = opt || { } ;
6548
+ opt . translateBy = opt . translateBy || this . id ;
6549
+ opt . tx = tx ;
6550
+ opt . ty = ty ;
6551
+
6546
6552
return this . set ( attrs , opt ) ;
6547
6553
} ,
6548
6554
@@ -6560,7 +6566,7 @@ joint.dia.Link = joint.dia.Cell.extend({
6560
6566
newParent = this . graph . getCommonAncestor ( source , target ) ;
6561
6567
}
6562
6568
6563
- if ( prevParent && ( ! newParent || newParent . id != prevParent . id ) ) {
6569
+ if ( prevParent && ( ! newParent || newParent . id !== prevParent . id ) ) {
6564
6570
// Unembed the link if source and target has no common ancestor
6565
6571
// or common ancestor changed
6566
6572
prevParent . unembed ( this , opt ) ;
@@ -6619,6 +6625,35 @@ joint.dia.Link = joint.dia.Cell.extend({
6619
6625
var target = this . get ( 'target' ) ;
6620
6626
6621
6627
return ( target && target . id && this . graph && this . graph . getCell ( target . id ) ) || null ;
6628
+ } ,
6629
+
6630
+ // Returns the common ancestor for the source element,
6631
+ // target element and the link itself.
6632
+ getRelationshipAncestor : function ( ) {
6633
+
6634
+ var connectionAncestor ;
6635
+
6636
+ if ( this . graph ) {
6637
+
6638
+ var cells = _ . compact ( [
6639
+ this ,
6640
+ this . getSourceElement ( ) , // null if source is a point
6641
+ this . getTargetElement ( ) // null if target is a point
6642
+ ] ) ;
6643
+
6644
+ connectionAncestor = this . graph . getCommonAncestor . apply ( this . graph , cells ) ;
6645
+ }
6646
+
6647
+ return connectionAncestor || null ;
6648
+ } ,
6649
+
6650
+ // Is source, target and the link itself embedded in a given element?
6651
+ isRelationshipEmbeddedIn : function ( element ) {
6652
+
6653
+ var elementId = _ . isString ( element ) ? element : element . id ;
6654
+ var ancestor = this . getRelationshipAncestor ( ) ;
6655
+
6656
+ return ! ! ancestor && ( ancestor . id === elementId || ancestor . isEmbeddedIn ( elementId ) ) ;
6622
6657
}
6623
6658
} ) ;
6624
6659
@@ -6680,14 +6715,30 @@ joint.dia.LinkView = joint.dia.CellView.extend({
6680
6715
this . listenTo ( model , 'change:target' , this . onTargetChange ) ;
6681
6716
} ,
6682
6717
6683
- onSourceChange : function ( cell , source ) {
6718
+ onSourceChange : function ( cell , source , opt ) {
6684
6719
6685
- this . watchSource ( cell , source ) . update ( ) ;
6720
+ // Start watching the new source model.
6721
+ this . watchSource ( cell , source ) ;
6722
+ // This handler is called when the source attribute is changed.
6723
+ // This can happen either when someone reconnects the link (or moves arrowhead),
6724
+ // or when an embedded link is translated by its ancestor.
6725
+ // 1. Always do update.
6726
+ // 2. Do update only if the opposite end ('target') is also a point.
6727
+ if ( ! opt . translateBy || ! this . model . get ( 'target' ) . id ) {
6728
+ opt . updateConnectionOnly = true ;
6729
+ this . update ( this . model , null , opt ) ;
6730
+ }
6686
6731
} ,
6687
6732
6688
- onTargetChange : function ( cell , target ) {
6733
+ onTargetChange : function ( cell , target , opt ) {
6689
6734
6690
- this . watchTarget ( cell , target ) . update ( ) ;
6735
+ // Start watching the new target model.
6736
+ this . watchTarget ( cell , target ) ;
6737
+ // See `onSourceChange` method.
6738
+ if ( ! opt . translateBy ) {
6739
+ opt . updateConnectionOnly = true ;
6740
+ this . update ( this . model , null , opt ) ;
6741
+ }
6691
6742
} ,
6692
6743
6693
6744
onVerticesChange : function ( cell , changed , opt ) {
@@ -6698,10 +6749,11 @@ joint.dia.LinkView = joint.dia.CellView.extend({
6698
6749
// the only link that was translated. If the link was translated via another element which the link
6699
6750
// is embedded in, this element will be translated as well and that triggers an update.
6700
6751
// Note that all embeds in a model are sorted - first comes links, then elements.
6701
- if ( ! opt . translateBy || opt . translateBy === this . model . id || this . model . hasLoop ( ) ) {
6702
- // Vertices were changed (not as a reaction on translate) or link.translate() was called or
6703
- // we're dealing with a loop link that is embedded.
6704
- this . update ( ) ;
6752
+ if ( ! opt . translateBy || opt . translateBy === this . model . id ) {
6753
+ // Vertices were changed (not as a reaction on translate)
6754
+ // or link.translate() was called or
6755
+ opt . updateConnectionOnly = true ;
6756
+ this . update ( cell , null , opt ) ;
6705
6757
}
6706
6758
} ,
6707
6759
@@ -6727,7 +6779,8 @@ joint.dia.LinkView = joint.dia.CellView.extend({
6727
6779
// `.connection`, `.connection-wrap`, `.marker-source` and `.marker-target` selectors
6728
6780
// of elements with special meaning though. Therefore, those classes should be preserved in any
6729
6781
// special markup passed in `properties.markup`.
6730
- var children = V ( this . model . get ( 'markup' ) || this . model . markup ) ;
6782
+ var model = this . model ;
6783
+ var children = V ( model . get ( 'markup' ) || model . markup ) ;
6731
6784
6732
6785
// custom markup may contain only one children
6733
6786
if ( ! _ . isArray ( children ) ) children = [ children ] ;
@@ -6754,8 +6807,8 @@ joint.dia.LinkView = joint.dia.CellView.extend({
6754
6807
this . renderLabels ( ) ;
6755
6808
6756
6809
// start watching the ends of the link for changes
6757
- this . watchSource ( this . model , this . model . get ( 'source' ) )
6758
- . watchTarget ( this . model , this . model . get ( 'target' ) )
6810
+ this . watchSource ( model , model . get ( 'source' ) )
6811
+ . watchTarget ( model , model . get ( 'target' ) )
6759
6812
. update ( ) ;
6760
6813
6761
6814
return this ;
@@ -6914,7 +6967,70 @@ joint.dia.LinkView = joint.dia.CellView.extend({
6914
6967
//---------
6915
6968
6916
6969
// Default is to process the `attrs` object and set attributes on subelements based on the selectors.
6917
- update : function ( ) {
6970
+ update : function ( model , attributes , opt ) {
6971
+
6972
+ opt = opt || { } ;
6973
+
6974
+ if ( ! opt . updateConnectionOnly ) {
6975
+ // update SVG attributes defined by 'attrs/'.
6976
+ this . updateAttributes ( ) ;
6977
+ }
6978
+
6979
+ // update the link path, label position etc.
6980
+ this . updateConnection ( opt ) ;
6981
+ this . updateLabelPositions ( ) ;
6982
+ this . updateToolsPosition ( ) ;
6983
+ this . updateArrowheadMarkers ( ) ;
6984
+
6985
+ // Local perpendicular flag (as opposed to one defined on paper).
6986
+ // Could be enabled inside a connector/router. It's valid only
6987
+ // during the update execution.
6988
+ this . options . perpendicular = null ;
6989
+ // Mark that postponed update has been already executed.
6990
+ this . updatePostponed = false ;
6991
+
6992
+ return this ;
6993
+ } ,
6994
+
6995
+ updateConnection : function ( opt ) {
6996
+
6997
+ opt = opt || { } ;
6998
+
6999
+ var model = this . model ;
7000
+ var route ;
7001
+
7002
+ if ( opt . translateBy && model . isRelationshipEmbeddedIn ( opt . translateBy ) ) {
7003
+ // The link is being translated by an ancestor that will
7004
+ // shift source point, target point and all vertices
7005
+ // by an equal distance.
7006
+ var tx = opt . tx || 0 ;
7007
+ var ty = opt . ty || 0 ;
7008
+
7009
+ route = this . route = _ . map ( this . route , function ( point ) {
7010
+ // translate point by point by delta translation
7011
+ return g . point ( point ) . offset ( tx , ty ) ;
7012
+ } ) ;
7013
+
7014
+ // translate source and target connection and marker points.
7015
+ this . _translateConnectionPoints ( tx , ty ) ;
7016
+
7017
+ } else {
7018
+ // Necessary path finding
7019
+ route = this . route = this . findRoute ( model . get ( 'vertices' ) || [ ] , opt ) ;
7020
+ // finds all the connection points taking new vertices into account
7021
+ this . _findConnectionPoints ( route ) ;
7022
+ }
7023
+
7024
+ var pathData = this . getPathData ( route ) ;
7025
+
7026
+ // The markup needs to contain a `.connection`
7027
+ this . _V . connection . attr ( 'd' , pathData ) ;
7028
+ this . _V . connectionWrap && this . _V . connectionWrap . attr ( 'd' , pathData ) ;
7029
+
7030
+ this . _translateAndAutoOrientArrows ( this . _V . markerSource , this . _V . markerTarget ) ;
7031
+ } ,
7032
+
7033
+ updateAttributes : function ( ) {
6918
7034
6919
7035
// Update attributes.
6920
7036
_ . each ( this . model . get ( 'attrs' ) , function ( attrs , selector ) {
@@ -6953,31 +7069,6 @@ joint.dia.LinkView = joint.dia.CellView.extend({
6953
7069
this . findBySelector ( selector ) . attr ( attrs ) ;
6954
7070
6955
7071
} , this ) ;
6956
-
6957
- // Path finding
6958
- var vertices = this . route = this . findRoute ( this . model . get ( 'vertices' ) || [ ] ) ;
6959
-
6960
- // finds all the connection points taking new vertices into account
6961
- this . _findConnectionPoints ( vertices ) ;
6962
-
6963
- var pathData = this . getPathData ( vertices ) ;
6964
-
6965
- // The markup needs to contain a `.connection`
6966
- this . _V . connection . attr ( 'd' , pathData ) ;
6967
- this . _V . connectionWrap && this . _V . connectionWrap . attr ( 'd' , pathData ) ;
6968
-
6969
- this . _translateAndAutoOrientArrows ( this . _V . markerSource , this . _V . markerTarget ) ;
6970
-
6971
- //partials updates
6972
- this . updateLabelPositions ( ) ;
6973
- this . updateToolsPosition ( ) ;
6974
- this . updateArrowheadMarkers ( ) ;
6975
-
6976
- this . options . perpendicular = null ;
6977
- // Mark that postponed update has been already executed.
6978
- this . updatePostponed = false ;
6979
-
6980
- return this ;
6981
7072
} ,
6982
7073
6983
7074
_findConnectionPoints : function ( vertices ) {
@@ -7033,6 +7124,16 @@ joint.dia.LinkView = joint.dia.CellView.extend({
7033
7124
this . targetPoint = targetPoint ;
7034
7125
} ,
7035
7126
7127
+ _translateConnectionPoints : function ( tx , ty ) {
7128
+
7129
+ var cache = this . _markerCache ;
7130
+
7131
+ cache . sourcePoint . offset ( tx , ty ) ;
7132
+ cache . targetPoint . offset ( tx , ty ) ;
7133
+ this . sourcePoint . offset ( tx , ty ) ;
7134
+ this . targetPoint . offset ( tx , ty ) ;
7135
+ } ,
7136
+
7036
7137
updateLabelPositions : function ( ) {
7037
7138
7038
7139
if ( ! this . _V . labels ) return this ;
@@ -7213,13 +7314,14 @@ joint.dia.LinkView = joint.dia.CellView.extend({
7213
7314
onEndModelChange : function ( endType , endModel , opt ) {
7214
7315
7215
7316
var doUpdate = ! opt . cacheOnly ;
7216
- var end = this . model . get ( endType ) || { } ;
7317
+ var model = this . model ;
7318
+ var end = model . get ( endType ) || { } ;
7217
7319
7218
7320
if ( endModel ) {
7219
7321
7220
7322
var selector = this . constructor . makeSelector ( end ) ;
7221
7323
var oppositeEndType = endType == 'source' ? 'target' : 'source' ;
7222
- var oppositeEnd = this . model . get ( oppositeEndType ) || { } ;
7324
+ var oppositeEnd = model . get ( oppositeEndType ) || { } ;
7223
7325
var oppositeSelector = oppositeEnd . id && this . constructor . makeSelector ( oppositeEnd ) ;
7224
7326
7225
7327
// Caching end models bounding boxes.
@@ -7258,8 +7360,8 @@ joint.dia.LinkView = joint.dia.CellView.extend({
7258
7360
}
7259
7361
7260
7362
if ( opt . handleBy === this . cid && opt . translateBy &&
7261
- this . model . isEmbeddedIn ( endModel ) &&
7262
- ! _ . isEmpty ( this . model . get ( 'vertices' ) ) ) {
7363
+ model . isEmbeddedIn ( endModel ) &&
7364
+ ! _ . isEmpty ( model . get ( 'vertices' ) ) ) {
7263
7365
// Loop link whose element was translated and that has vertices (that need to be translated with
7264
7366
// the parent in which my element is embedded).
7265
7367
// If the link is embedded, has a loop and vertices and the end model
@@ -7306,10 +7408,10 @@ joint.dia.LinkView = joint.dia.CellView.extend({
7306
7408
this [ endType + 'View' ] = this [ endType + 'Magnet' ] = null ;
7307
7409
}
7308
7410
7309
- // keep track which end had been changed very last
7310
- this . lastEndChange = endType ;
7311
-
7312
- doUpdate && this . update ( ) ;
7411
+ if ( doUpdate ) {
7412
+ opt . updateConnectionOnly = true ;
7413
+ this . update ( model , null , opt ) ;
7414
+ }
7313
7415
} ,
7314
7416
7315
7417
_translateAndAutoOrientArrows : function ( sourceArrow , targetArrow ) {
0 commit comments