| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- define(function(require, exports, module) {
- var kity = require('../core/kity');
- var utils = require('../core/utils');
- var keymap = require('../core/keymap');
- var MinderNode = require('../core/node');
- var Command = require('../core/command');
- var Module = require('../core/module');
- var Renderer = require('../core/render');
- Module.register('Expand', function() {
- var minder = this;
- var EXPAND_STATE_DATA = 'expandState',
- STATE_EXPAND = 'expand',
- STATE_COLLAPSE = 'collapse';
- // 将展开的操作和状态读取接口拓展到 MinderNode 上
- kity.extendClass(MinderNode, {
- /**
- * 展开节点
- * @param {Policy} policy 展开的策略,默认为 KEEP_STATE
- */
- expand: function() {
- this.setData(EXPAND_STATE_DATA, STATE_EXPAND);
- return this;
- },
- /**
- * 收起节点
- */
- collapse: function() {
- this.setData(EXPAND_STATE_DATA, STATE_COLLAPSE);
- return this;
- },
- /**
- * 判断节点当前的状态是否为展开
- */
- isExpanded: function() {
- var expanded = this.getData(EXPAND_STATE_DATA) !== STATE_COLLAPSE;
- return expanded && (this.isRoot() || this.parent.isExpanded());
- },
- /**
- * 判断节点当前的状态是否为收起
- */
- isCollapsed: function() {
- return !this.isExpanded();
- }
- });
- /**
- * @command Expand
- * @description 展开当前选中的节点,保证其可见
- * @param {bool} justParents 是否只展开到父亲
- * * `false` - (默认)保证选中的节点以及其子树可见
- * * `true` - 只保证选中的节点可见,不展开其子树
- * @state
- * 0: 当前有选中的节点
- * -1: 当前没有选中的节点
- */
- var ExpandCommand = kity.createClass('ExpandCommand', {
- base: Command,
- execute: function(km, justParents) {
- var node = km.getSelectedNode();
- if (!node) return;
- if (justParents) {
- node = node.parent;
- }
- while (node.parent) {
- node.expand();
- node = node.parent;
- }
- node.renderTree();
- km.layout(100);
- },
- queryState: function(km) {
- var node = km.getSelectedNode();
- return node && !node.isRoot() && !node.isExpanded() ? 0 : -1;
- }
- });
- /**
- * @command ExpandToLevel
- * @description 展开脑图到指定的层级
- * @param {number} level 指定展开到的层级,最少值为 1。
- * @state
- * 0: 一直可用
- */
- var ExpandToLevelCommand = kity.createClass('ExpandToLevelCommand', {
- base: Command,
- execute: function(km, level) {
- km.getRoot().traverse(function(node) {
- if (node.getLevel() < level) node.expand();
- if (node.getLevel() == level && !node.isLeaf()) node.collapse();
- });
- km.refresh(100);
- },
- enableReadOnly: true
- });
- /**
- * @command Collapse
- * @description 收起当前节点的子树
- * @state
- * 0: 当前有选中的节点
- * -1: 当前没有选中的节点
- */
- var CollapseCommand = kity.createClass('CollapseCommand', {
- base: Command,
- execute: function(km) {
- var node = km.getSelectedNode();
- if (!node) return;
- node.collapse();
- node.renderTree();
- km.layout();
- },
- queryState: function(km) {
- var node = km.getSelectedNode();
- return node && !node.isRoot() && node.isExpanded() ? 0 : -1;
- }
- });
- var Expander = kity.createClass('Expander', {
- base: kity.Group,
- constructor: function(node) {
- this.callBase();
- this.radius = 6;
- this.outline = new kity.Circle(this.radius).stroke('gray').fill('white');
- this.sign = new kity.Path().stroke('gray');
- this.addShapes([this.outline, this.sign]);
- this.initEvent(node);
- this.setId(utils.uuid('node_expander'));
- this.setStyle('cursor', 'pointer');
- },
- initEvent: function(node) {
- this.on('mousedown', function(e) {
- minder.select([node], true);
- if (node.isExpanded()) {
- node.collapse();
- } else {
- node.expand();
- }
- node.renderTree().getMinder().layout(100);
- node.getMinder().fire('contentchange');
- e.stopPropagation();
- e.preventDefault();
- });
- this.on('dblclick click mouseup', function(e) {
- e.stopPropagation();
- e.preventDefault();
- });
- },
- setState: function(state) {
- if (state == 'hide') {
- this.setVisible(false);
- return;
- }
- this.setVisible(true);
- var pathData = ['M', 1.5 - this.radius, 0, 'L', this.radius - 1.5, 0];
- if (state == STATE_COLLAPSE) {
- pathData.push(['M', 0, 1.5 - this.radius, 'L', 0, this.radius - 1.5]);
- }
- this.sign.setPathData(pathData);
- }
- });
- var ExpanderRenderer = kity.createClass('ExpanderRenderer', {
- base: Renderer,
- create: function(node) {
- if (node.isRoot()) return;
- this.expander = new Expander(node);
- node.getRenderContainer().prependShape(this.expander);
- node.expanderRenderer = this;
- this.node = node;
- return this.expander;
- },
- shouldRender: function(node) {
- return !node.isRoot();
- },
- update: function(expander, node, box) {
- if (!node.parent) return;
- var visible = node.parent.isExpanded();
- expander.setState(visible && node.children.length ? node.getData(EXPAND_STATE_DATA) : 'hide');
- var vector = node.getLayoutVectorIn().normalize(expander.radius + node.getStyle('stroke-width'));
- var position = node.getVertexIn().offset(vector.reverse());
- this.expander.setTranslate(position);
- }
- });
- return {
- commands: {
- 'expand': ExpandCommand,
- 'expandtolevel': ExpandToLevelCommand,
- 'collapse': CollapseCommand
- },
- events: {
- 'layoutapply': function(e) {
- var r = e.node.getRenderer('ExpanderRenderer');
- if (r.getRenderShape()) {
- r.update(r.getRenderShape(), e.node);
- }
- },
- 'beforerender': function(e) {
- var node = e.node;
- var visible = !node.parent || node.parent.isExpanded();
- var minder = this;
- node.getRenderContainer().setVisible(visible);
- if (!visible) e.stopPropagation();
- },
- 'normal.keydown': function(e) {
- if (this.getStatus() == 'textedit') return;
- if (e.originEvent.keyCode == keymap['/']) {
- var node = this.getSelectedNode();
- if (!node || node == this.getRoot()) return;
- var expanded = node.isExpanded();
- this.getSelectedNodes().forEach(function(node) {
- if (expanded) node.collapse();
- else node.expand();
- node.renderTree();
- });
- this.layout(100);
- this.fire('contentchange');
- e.preventDefault();
- e.stopPropagationImmediately();
- }
- if (e.isShortcutKey('Alt+`')) {
- this.execCommand('expandtolevel', 9999);
- }
- for (var i = 1; i < 6; i++) {
- if (e.isShortcutKey('Alt+' + i)) {
- this.execCommand('expandtolevel', i);
- }
- }
- }
- },
- renderers: {
- outside: ExpanderRenderer
- },
- contextmenu: [{
- command: 'expandtoleaf',
- query: function() {
- return !minder.getSelectedNode();
- },
- fn: function(minder) {
- minder.execCommand('expandtolevel', 9999);
- }
- }, {
- command: 'expandtolevel1',
- query: function() {
- return !minder.getSelectedNode();
- },
- fn: function(minder) {
- minder.execCommand('expandtolevel', 1);
- }
- }, {
- command: 'expandtolevel2',
- query: function() {
- return !minder.getSelectedNode();
- },
- fn: function(minder) {
- minder.execCommand('expandtolevel', 2);
- }
- },{
- command: 'expandtolevel3',
- query: function() {
- return !minder.getSelectedNode();
- },
- fn: function(minder) {
- minder.execCommand('expandtolevel', 3);
- }
- }, {
- divider: true
- }]
- };
- });
- });
|