在vue2使用百度脑图的kityminder-core进行二次开发思维导图。节点收起时显示子节点的数量

需求描述

   用户收起某节点后要展示出当前节点的子节点数量,当节点展开后不显示子节点数量。

功能效果

 

分析

      1、找到跟节点收起/展开相关的菜单按钮。

 2、找到节点收起/展开的事件,添加一个childrenSize字段用于存储 收起状态下节点的子数量,当节点收起时添加一个图标显示该childrenSize的值。

节点收起时,设置childrenSize的值为当前节点的子节点数量

 

 节点展开时,设置childrenSize的值为null

 

 

3、注册显示子节点数量的图标。当childrenSize有值时则显示该图标。

  var BACK_PATH = 'M 0 10 A 1 1 0 0 0 22 10 A 1 1 0 0 0 0 10';
        var MASK_PATH = 'M 0 10 A 1 1 0 0 0 22 10 A 1 1 0 0 0 0 10';
        // 节点收缩时的图形 显示子节点数量
        var ChildrenSizeIcon = kity.createClass('ChildrenSizeIcon', {
            base: kity.Group,
            constructor: function () {
                this.callBase();
                this.setSize(20);
                this.create();
                // this.setId(utils.uuid('node_priority'));
            },

            setSize: function (size) {
                this.width = this.height = size;
            },

            create: function () {
                var white, back, mask, number; // 4 layer

                white = new kity.Path().setPathData(MASK_PATH).fill('white');
                back = new kity.Path().setPathData(BACK_PATH).setTranslate(0.5, 0.5);
                mask = new kity.Path().setPathData(MASK_PATH).setOpacity(0.8).setTranslate(0.5, 0.5);

                number = new kity.Text()
                    .setX(this.width / 2 - 0.5).setY(this.height / 2)
                    .setTextAnchor('middle')
                    .setVerticalAlign('middle')
                    .setFontItalic(true)
                    .setFontSize(12)
                    .fill('white');

                this.addShapes([back, mask, number]);
                this.mask = mask;
                this.back = back;
                this.number = number;
            },

            setValue: function (value) {
                var back = this.back,
                    mask = this.mask,
                    number = this.number;

                var color = ['#000000', '#000000'];

                if (color) {
                    back.fill(color[1]);
                    mask.fill(color[0]);
                }

                number.setContent(value);
            }
        });
        var childrenSizeRenderer = kity.createClass('childrenSizeRenderer', {
            base: Renderer,

            create: function (node) {
                return new ChildrenSizeIcon();
            },

            shouldRender: function (node) {
                return node.getData('childrenSize');
            },

            update: function (icon, node, box) {
                var data = node.getData('childrenSize');
                var spaceLeft = node.getStyle('space-left'),
                    x, y;

                icon.setValue(data);
                x = box.left - icon.width - spaceLeft;
                y = -icon.height / 2;

                icon.setTranslate(x, y);

                return new kity.Box({
                    x: x,
                    y: y,
                    width: icon.width,
                    height: icon.height
                });
            }
        });

 注册图标

完整代码

在kityminder.core.js文件中找到_p[46],将其中的代码照着expand.js的修改。

 

 expand.js  中的完整代码

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.setData('childrenSize', null)
                    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();
                        node.setData('childrenSize', null);
                    }
                    if (node.getLevel() == level && !node.isLeaf()) {
                        node.collapse();
                        node.setData('childrenSize', node.children.length);
                    }
                });
                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.setData('childrenSize', node.children.length)
                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();
                        node.setData('childrenSize', node.children.length)
                    } else {
                        node.expand();
                        node.setData('childrenSize', null)
                    }
                    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 BACK_PATH = 'M 0 10 A 1 1 0 0 0 22 10 A 1 1 0 0 0 0 10';
        var MASK_PATH = 'M 0 10 A 1 1 0 0 0 22 10 A 1 1 0 0 0 0 10';
        // 节点收缩时的图形 显示子节点数量
        var ChildrenSizeIcon = kity.createClass('ChildrenSizeIcon', {
            base: kity.Group,
            constructor: function () {
                this.callBase();
                this.setSize(20);
                this.create();
                // this.setId(utils.uuid('node_priority'));
            },

            setSize: function (size) {
                this.width = this.height = size;
            },

            create: function () {
                var white, back, mask, number; // 4 layer

                white = new kity.Path().setPathData(MASK_PATH).fill('white');
                back = new kity.Path().setPathData(BACK_PATH).setTranslate(0.5, 0.5);
                mask = new kity.Path().setPathData(MASK_PATH).setOpacity(0.8).setTranslate(0.5, 0.5);

                number = new kity.Text()
                    .setX(this.width / 2 - 0.5).setY(this.height / 2)
                    .setTextAnchor('middle')
                    .setVerticalAlign('middle')
                    .setFontItalic(true)
                    .setFontSize(12)
                    .fill('white');

                this.addShapes([back, mask, number]);
                this.mask = mask;
                this.back = back;
                this.number = number;
            },

            setValue: function (value) {
                var back = this.back,
                    mask = this.mask,
                    number = this.number;

                var color = ['#000000', '#000000'];

                if (color) {
                    back.fill(color[1]);
                    mask.fill(color[0]);
                }

                number.setContent(value);
            }
        });
        var childrenSizeRenderer = kity.createClass('childrenSizeRenderer', {
            base: Renderer,

            create: function (node) {
                return new ChildrenSizeIcon();
            },

            shouldRender: function (node) {
                return node.getData('childrenSize');
            },

            update: function (icon, node, box) {
                var data = node.getData('childrenSize');
                var spaceLeft = node.getStyle('space-left'),
                    x, y;

                icon.setValue(data);
                x = box.left - icon.width - spaceLeft;
                y = -icon.height / 2;

                icon.setTranslate(x, y);

                return new kity.Box({
                    x: x,
                    y: y,
                    width: icon.width,
                    height: icon.height
                });
            }
        });
        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,
                left: childrenSizeRenderer,
            },
            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
            }]
        };
    });
});

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值