168 行
5.9 KiB

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;
} );