define( function ( require, exports, module ) {
|
|
var Class = require( 'core/class' );
|
|
var Query = require( '../pathdiagram/dataquery' );
|
|
var Connection = require( '../graffle/bezierconnection' );
|
|
var Group = require( 'graphic/group' );
|
|
var Text = require( 'graphic/text' );
|
|
var LevelContainer = require( '../pathdiagram/levelcontainer' );
|
|
var colors = require( '../pathdiagram/colors' );
|
|
|
|
var R_SIZE = LevelContainer.RECT_SIZE;
|
|
|
|
var margin = 100;
|
|
|
|
function sign( number ) {
|
|
if ( number === 0 ) {
|
|
return 0;
|
|
}
|
|
return number > 0 ? 1 : -1;
|
|
}
|
|
|
|
var PathDiagram = Class.createClass( {
|
|
base: Group,
|
|
constructor: function ( keyword ) {
|
|
this.callBase();
|
|
this.levels = [
|
|
new LevelContainer( -2 ),
|
|
new LevelContainer( -1 ),
|
|
new LevelContainer( 0 ),
|
|
new LevelContainer( 1 ),
|
|
new LevelContainer( 2 )
|
|
];
|
|
this.headLevel = 0;
|
|
this.tailLevel = 0;
|
|
this.render();
|
|
this.bind();
|
|
this.showKeyword(keyword);
|
|
},
|
|
render: function () {
|
|
for ( var name in this.levels ) {
|
|
this.addShape( this.levels[ name ] );
|
|
}
|
|
return this;
|
|
},
|
|
getLevelContainer: function ( level ) {
|
|
return this.levels[ level + 2 ];
|
|
},
|
|
showKeyword: function (keyword) {
|
|
this.currentPath = keyword ? Query.search(keyword) : Query.random();
|
|
this.getLevelContainer(0).render( [ this.currentPath ], -R_SIZE.width / 2, 0 );
|
|
setTimeout( function() {
|
|
this.getLevelContainer(0).select(0);
|
|
}.bind(this));
|
|
},
|
|
bind: function () {
|
|
var levels = this.levels;
|
|
this.on( 'selected', function ( e ) {
|
|
if ( e.pathNode ) {
|
|
if ( e.level > 0 ) {
|
|
this.tailLevel = e.level;
|
|
}
|
|
if ( e.level < 0 ) {
|
|
this.headLevel = e.level;
|
|
}
|
|
} else {
|
|
if (e.level > 0) {
|
|
this.tailLevel = e.level - 1;
|
|
}
|
|
else if (e.level < 0 ) {
|
|
this.headLevel = e.level + 1;
|
|
}
|
|
}
|
|
this.updateConnection(e.pathNode, e.lastPathNode);
|
|
this.updateCurrentPath();
|
|
this.updateLevels();
|
|
} );
|
|
},
|
|
updateConnection: function( current, last ) {
|
|
if(last && last.connection) {
|
|
last.connection.stroke(colors.get('connect-stroke'), 1);
|
|
}
|
|
if(current && current.connection) {
|
|
this.removeShape(current.connection).addShape(current.connection);
|
|
current.connection.stroke(colors.get('connect-stroke-active'), 3);
|
|
}
|
|
},
|
|
updateCurrentPath: function() {
|
|
var data = {
|
|
seq: [],
|
|
length: 0
|
|
};
|
|
for(var level = this.headLevel; level <= this.tailLevel; level++) {
|
|
data.seq.push(this.getLevelContainer(level).levelWord);
|
|
data.length++;
|
|
}
|
|
this.currentPath = data;
|
|
},
|
|
updateLevels: function() {
|
|
var headClear = this.headLevel,
|
|
tailClear = this.tailLevel;
|
|
while(headClear >= -2) {
|
|
this.renderLevel(--headClear);
|
|
}
|
|
while(tailClear <= 2) {
|
|
this.renderLevel(++tailClear);
|
|
}
|
|
},
|
|
clearLevelContainer: function( container ) {
|
|
var nodes = container.getPathNodes();
|
|
for(var i = 0; i < nodes.length; i++) {
|
|
nodes[i].connection.remove();
|
|
}
|
|
container.clear();
|
|
},
|
|
renderLevel: function ( level ) {
|
|
var container = this.getLevelContainer( level );
|
|
var parent, dir, pbox, nbox, x, y, stream;
|
|
|
|
if ( !container ) {
|
|
return;
|
|
}
|
|
|
|
if(level < this.headLevel || level > this.tailLevel) {
|
|
this.clearLevelContainer(container);
|
|
if(level < this.headLevel - 1 || level > this.tailLevel + 1) {
|
|
return;
|
|
}
|
|
}
|
|
|
|
// 1 = right, -1 = left
|
|
dir = sign( level );
|
|
parent = this.getLevelContainer( level - dir );
|
|
pbox = parent.getRenderBox();
|
|
nbox = parent.getSelected().getRenderBox();
|
|
x = pbox.x + dir * ( R_SIZE.width + margin );
|
|
y = nbox.y;
|
|
|
|
if ( level === 0 ) {
|
|
stream = [ this.currentPath ];
|
|
} else if ( level > 0 ) {
|
|
stream = Query.downstream( this.currentPath );
|
|
} else if ( level < 0 ) {
|
|
stream = Query.upstream( this.currentPath );
|
|
}
|
|
|
|
container.render( stream, x, y );
|
|
|
|
this.renderConnection( container, parent, dir );
|
|
},
|
|
renderConnection: function ( container, parent, dir ) {
|
|
var childNodes = container.getPathNodes();
|
|
var parentNode = parent.getSelected();
|
|
var i, connection;
|
|
for ( i = 0; i < childNodes.length; i++ ) {
|
|
if ( dir === 1 ) {
|
|
connection = new Connection( parentNode, childNodes[ i ] );
|
|
} else if ( dir === -1 ) {
|
|
connection = new Connection( childNodes[ i ], parentNode );
|
|
}
|
|
if(connection) {
|
|
this.addShape( childNodes[i].connection = connection );
|
|
connection.stroke( colors.get( 'connect-stroke' ), 1 ).fill( 'none' );
|
|
}
|
|
}
|
|
}
|
|
} );
|
|
|
|
return PathDiagram;
|
|
} );
|