|
@@ -0,0 +1,410 @@
|
|
|
+/**
|
|
|
+ * Created by Mai on 2017/4/5.
|
|
|
+ */
|
|
|
+var cacheTree = {
|
|
|
+ createNew: function () {
|
|
|
+ var tools = {
|
|
|
+ findNode: function (nodes, check) {
|
|
|
+ for (var i = 0; i < nodes.length; i++) {
|
|
|
+ if (check(nodes[i])) {
|
|
|
+ return nodes[i];
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ },
|
|
|
+ reSortNodes: function (nodes, recursive) {
|
|
|
+ var temp = [], first;
|
|
|
+ var findFirstNode = function (nodes) {
|
|
|
+ return tools.findNode(nodes, function (node) {
|
|
|
+ return node.preSibling === null;
|
|
|
+ });
|
|
|
+ };
|
|
|
+ var moveNode = function (node, orgArray, newArray, newIndex) {
|
|
|
+ var next;
|
|
|
+ orgArray.splice(orgArray.indexOf(node), 1);
|
|
|
+ newArray.splice(newIndex, 0, node);
|
|
|
+ if (node.getNextSiblingID() !== -1) {
|
|
|
+ next = node.nextSibling;
|
|
|
+ if (next && (orgArray.indexOf(next) >= 0)) {
|
|
|
+ moveNode(next, orgArray, newArray, newIndex + 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+ if (nodes.length === 0) {
|
|
|
+ return nodes;
|
|
|
+ }
|
|
|
+ if (recursive) {
|
|
|
+ nodes.forEach(function (node) {
|
|
|
+ node.children = tools.reSortNodes(node.children, recursive);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ while (nodes.length > 0) {
|
|
|
+ first = findFirstNode(nodes);
|
|
|
+ first = first ? first : nodes[0];
|
|
|
+ moveNode(first, nodes, temp, temp.length);
|
|
|
+ }
|
|
|
+ nodes = null;
|
|
|
+ tools.reSiblingNodes(temp);
|
|
|
+ return temp;
|
|
|
+ },
|
|
|
+ reSiblingNodes: function (nodes) {
|
|
|
+ var i;
|
|
|
+ for (i = 0; i < nodes.length; i++) {
|
|
|
+ nodes[i].preSibling = (i === 0) ? null : nodes[i - 1];
|
|
|
+ nodes[i].nextSibling = (i === nodes.length - 1) ? null : nodes[i + 1];
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 在nodes中,从iIndex(包括)开始全部移除
|
|
|
+ removeNodes: function (tree, parent, iIndex, count) {
|
|
|
+ var children = parent ? parent.children : tree.roots;
|
|
|
+ var pre = (iIndex < 0 || iIndex >= children.length) ? null : children[iIndex].preSibling;
|
|
|
+ var next = (pre && iIndex + count - 1 < children.length) ? children[iIndex + count] : null;
|
|
|
+ if (pre) {
|
|
|
+ pre.nextSibling = next;
|
|
|
+ }
|
|
|
+ if (next) {
|
|
|
+ next.preSibling = pre;
|
|
|
+ }
|
|
|
+ if (arguments.length === 4) {
|
|
|
+ children.splice(iIndex, count);
|
|
|
+ } else {
|
|
|
+ children.splice(iIndex, children.length - iIndex);
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 在nodes中增加addNodes, 位置从index开始
|
|
|
+ addNodes: function (tree, parent, nodes, iIndex) {
|
|
|
+ var children = parent ? parent.children : tree.roots;
|
|
|
+ var pre, next, i;
|
|
|
+ if (nodes.length === 0) { return; }
|
|
|
+ if (arguments.length === 4) {
|
|
|
+ pre = (iIndex <= 0 || iIndex > children.length) ? null : children[iIndex - 1];
|
|
|
+ next = pre ? pre.nextSibling : null;
|
|
|
+ } else if (arguments.length === 3) {
|
|
|
+ pre = children.length === 0 ? null : children[children.length - 1];
|
|
|
+ next = null;
|
|
|
+ }
|
|
|
+ if (pre) {
|
|
|
+ pre.nextSibling = nodes[0];
|
|
|
+ }
|
|
|
+ nodes[0].preSibling = pre;
|
|
|
+ if (next) {
|
|
|
+ next.preSibling = nodes[nodes.length - 1];
|
|
|
+ }
|
|
|
+ nodes[nodes.length - 1].nextSibling = next;
|
|
|
+ for (i = 0; i < nodes.length; i++) {
|
|
|
+ if (arguments.length === 4) {
|
|
|
+ children.splice(iIndex + i, 0, nodes[i]);
|
|
|
+ } else if (arguments.length === 3) {
|
|
|
+ children.push(nodes[i]);
|
|
|
+ }
|
|
|
+ nodes[i].parent = parent;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ sortTreeItems: function (tree) {
|
|
|
+ var addItems = function (items) {
|
|
|
+ var i;
|
|
|
+ for (i = 0; i < items.length; i++) {
|
|
|
+ tree.items.push(items[i]);
|
|
|
+ addItems(items[i].children);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ tree.items.splice(0, tree.items.length);
|
|
|
+ addItems(tree.roots);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ var Node = function (tree, id) {
|
|
|
+ var ID = id;
|
|
|
+ // 以下的属性,本单元外均不可直接修改
|
|
|
+ this.tree = tree;
|
|
|
+ this.children = [];
|
|
|
+
|
|
|
+ this.parent = null;
|
|
|
+ this.nextSibling = null;
|
|
|
+ this.preSibling = null;
|
|
|
+
|
|
|
+ this.expanded = true;
|
|
|
+ this.visible = true;
|
|
|
+
|
|
|
+ this.nodeType = null;
|
|
|
+ this.source = null;
|
|
|
+
|
|
|
+ this.getID = function () {
|
|
|
+ return ID;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ Node.prototype.getParentID = function () {
|
|
|
+ return this.parent ? this.parent.getID() : -1;
|
|
|
+ };
|
|
|
+ Node.prototype.getNextSiblingID = function () {
|
|
|
+ return this.nextSibling ? this.nextSibling.getID() : -1;
|
|
|
+ };
|
|
|
+
|
|
|
+ Node.prototype.firstChild = function () {
|
|
|
+ return this.children.length === 0 ? null : this.children[0];
|
|
|
+ };
|
|
|
+ Node.prototype.depth = function () {
|
|
|
+ return this.parent ? this.parent.depth() + 1 : 0;
|
|
|
+ };
|
|
|
+ Node.prototype.isFirst = function () {
|
|
|
+ if (this.parent) {
|
|
|
+ return this.parent.children.indexOf(this) === 0 ? true : false;
|
|
|
+ } else {
|
|
|
+ return this.tree.roots.indexOf(this) === 0 ? true : false;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ Node.prototype.isLast = function () {
|
|
|
+ if (this.parent) {
|
|
|
+ return this.parent.children.indexOf(this) === this.parent.children.length - 1 ? true : false;
|
|
|
+ } else {
|
|
|
+ return this.tree.roots.indexOf(this) === this.tree.roots.length - 1 ? true : false;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ Node.prototype.siblingIndex = function () {
|
|
|
+ return this.parent ? this.parent.children.indexOf(this) : this.tree.roots.indexOf(this);
|
|
|
+ }
|
|
|
+ Node.prototype.posterityCount = function () {
|
|
|
+ var iCount = 0;
|
|
|
+ if (this.children.length !== 0) {
|
|
|
+ iCount += this.children.length;
|
|
|
+ this.children.forEach(function (child) {
|
|
|
+ iCount += child.posterityCount();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return iCount;
|
|
|
+ };
|
|
|
+
|
|
|
+ Node.prototype.setExpanded = function (expanded) {
|
|
|
+ var setNodesVisible = function (nodes, visible) {
|
|
|
+ nodes.forEach(function (node) {
|
|
|
+ node.visible = visible;
|
|
|
+ setNodesVisible(node.children, visible && node.expanded);
|
|
|
+ })
|
|
|
+ };
|
|
|
+ this.expanded = expanded;
|
|
|
+ setNodesVisible(this.children, expanded);
|
|
|
+ };
|
|
|
+ Node.prototype.serialNo = function () {
|
|
|
+ return this.tree.items.indexOf(this);
|
|
|
+ }
|
|
|
+
|
|
|
+ Node.prototype.addChild = function (node) {
|
|
|
+ var preSibling = this.children.length === 0 ? null : this.children[this.children.length - 1];
|
|
|
+ node.parent = this;
|
|
|
+ if (preSibling) {
|
|
|
+ preSibling.nextSibling = node;
|
|
|
+ }
|
|
|
+ node.preSibling = preSibling;
|
|
|
+ this.children.push(node);
|
|
|
+ };
|
|
|
+ Node.prototype.removeChild = function (node) {
|
|
|
+ var preSibling = node.preSibling, nextSibling = node.nextSibling;
|
|
|
+ if (preSibling) {
|
|
|
+ preSibling.nextSibling = nextSibling;
|
|
|
+ }
|
|
|
+ if (nextSibling) {
|
|
|
+ nextSibling.preSibling = preSibling;
|
|
|
+ }
|
|
|
+ this.children.splice(this.children.re)
|
|
|
+ };
|
|
|
+
|
|
|
+ Node.prototype.canUpLevel = function () {
|
|
|
+ if (this.nodeType === this.tree.nodeType.bills) {
|
|
|
+ return this.parent ? true : false;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ };
|
|
|
+ Node.prototype.canDownLevel = function () {
|
|
|
+ return this.nodeType === this.tree.nodeType.bills ? !this.isFirst() : false;
|
|
|
+ };
|
|
|
+ Node.prototype.canUpMove = function () {
|
|
|
+ return !this.isFirst();
|
|
|
+ };
|
|
|
+ Node.prototype.canDownMove = function () {
|
|
|
+ return !this.isLast();
|
|
|
+ }
|
|
|
+
|
|
|
+ Node.prototype.upLevel = function () {
|
|
|
+ var success = false,
|
|
|
+ iIndex = this.parent.children.indexOf(this), orgParent = this.parent, newNextSibling = this.parent.nextSibling;
|
|
|
+ if (this.canUpLevel) {
|
|
|
+ // NextSiblings become child
|
|
|
+ tools.addNodes(this.tree, this, this.parent.children.slice(iIndex + 1));
|
|
|
+ // Orginal Parent remove node and nextSiblings
|
|
|
+ tools.removeNodes(this.tree, this.parent, iIndex);
|
|
|
+ // New Parent add node
|
|
|
+ tools.addNodes(this.tree, this.parent.parent, [this], this.parent.siblingIndex() + 1);
|
|
|
+ if (!this.expanded) {
|
|
|
+ this.setExpanded(true);
|
|
|
+ }
|
|
|
+ success = true;
|
|
|
+ }
|
|
|
+ return success;
|
|
|
+ };
|
|
|
+ Node.prototype.downLevel = function () {
|
|
|
+ var success = false, iIndex = this.parent ? this.parent.children.indexOf(this) : this.tree.roots.indexOf(this);
|
|
|
+ var newParent = this.preSibling;
|
|
|
+ if (this.canDownLevel()) {
|
|
|
+ tools.removeNodes(this.tree, this.parent, this.siblingIndex(), 1);
|
|
|
+ tools.addNodes(this.tree, this.preSibling, [this]);
|
|
|
+ if (!newParent.expanded) {
|
|
|
+ newParent.setExpanded(true);
|
|
|
+ }
|
|
|
+ success = true;
|
|
|
+ }
|
|
|
+ return success;
|
|
|
+ };
|
|
|
+ Node.prototype.upMove = function () {
|
|
|
+ var success = false;
|
|
|
+ var iIndex = this.siblingIndex(), belongArray = this.parent ? this.parent.children : this.tree.roots, orgPre = this.preSibling;
|
|
|
+ if (this.canUpMove()) {
|
|
|
+ orgPre.nextSibling = this.nextSibling;
|
|
|
+ this.preSibling = orgPre.preSibling;
|
|
|
+ orgPre.preSibling = this;
|
|
|
+ this.nextSibling = orgPre;
|
|
|
+ belongArray.splice(iIndex, 1);
|
|
|
+ belongArray.splice(iIndex - 1, 0, this);
|
|
|
+ tools.sortTreeItems(this.tree);
|
|
|
+ success = true;
|
|
|
+ }
|
|
|
+ return success;
|
|
|
+ };
|
|
|
+ Node.prototype.downMove = function () {
|
|
|
+ var success = false;
|
|
|
+ var iIndex = this.siblingIndex(), belongArray = this.parent ? this.parent.children : this.tree.roots, orgNext = this.nextSibling;
|
|
|
+ if (this.canDownMove()) {
|
|
|
+ orgNext.preSibling = this.preSibling;
|
|
|
+ this.nextSibling = orgNext.nextSibling;
|
|
|
+ orgNext.nextSibling = this;
|
|
|
+ this.preSibling = orgNext;
|
|
|
+ belongArray.splice(iIndex, 1);
|
|
|
+ belongArray.splice(iIndex + 1, 0, this);
|
|
|
+ tools.sortTreeItems(this.tree);
|
|
|
+ success = true;
|
|
|
+ }
|
|
|
+ return success;
|
|
|
+ };
|
|
|
+
|
|
|
+ var Tree = function (setting) {
|
|
|
+ this.nodes = {};
|
|
|
+ this.roots = [];
|
|
|
+ this.items = [];
|
|
|
+ this.setting = setting;
|
|
|
+ this.prefix = 'id_';
|
|
|
+ this.selected = null;
|
|
|
+
|
|
|
+ this.nodeType = {bills: 'bills', ration: 'ration', zc: 'zhuCai'};
|
|
|
+ this.masterField = {ration: 'BillsID'};
|
|
|
+
|
|
|
+ var _MaxID = 0;
|
|
|
+ this.newNodeID = function (id) {
|
|
|
+ if (arguments.length === 0) {
|
|
|
+ _MaxID += 1;
|
|
|
+ return _MaxID;
|
|
|
+ } else {
|
|
|
+ _MaxID = Math.max(_MaxID, id);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ Tree.prototype.createNewNode = function () {
|
|
|
+ var node = new Node(this, this.newNodeID());
|
|
|
+ this.nodes[this.prefix + node.getID()] = node;
|
|
|
+ return node;
|
|
|
+ };
|
|
|
+
|
|
|
+ Tree.prototype.loadDatas = function (idTree, rations) {
|
|
|
+ var that = this;
|
|
|
+ var loadRationNode = function (rations, cacheNode) {
|
|
|
+ var newNode;
|
|
|
+ rations.forEach(function (ration) {
|
|
|
+ if (ration[that.masterField.ration] && ration[that.masterField.ration] === cacheNode.source.getID()) {
|
|
|
+ newNode = that.createNewNode();
|
|
|
+ newNode.source = ration;
|
|
|
+ newNode.nodeType = that.nodeType.ration;
|
|
|
+ newNode.data = ration;
|
|
|
+ tools.addNodes(that, cacheNode, [newNode]);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ };
|
|
|
+ var loadIdTreeNode = function (nodes, parent) {
|
|
|
+ var newNode, i;
|
|
|
+ for (i = 0; i < nodes.length; i++) {
|
|
|
+ newNode = that.createNewNode();
|
|
|
+ newNode.source = nodes[i];
|
|
|
+ newNode.nodeType = that.nodeType.bills;
|
|
|
+ newNode.data = nodes[i].data;
|
|
|
+ newNode.parent = parent;
|
|
|
+ tools.addNodes(that, parent, [newNode]);
|
|
|
+ if (nodes[i].children.length === 0) {
|
|
|
+ loadRationNode(rations, newNode);
|
|
|
+ };
|
|
|
+ loadIdTreeNode(nodes[i].children, newNode);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ loadIdTreeNode(idTree.roots, null);
|
|
|
+ tools.sortTreeItems(this);
|
|
|
+ };
|
|
|
+ Tree.prototype.firstNode = function () {
|
|
|
+ return this.roots.length === 0 ? null : this.roots[0];
|
|
|
+ };
|
|
|
+ Tree.prototype.findNode = function (id) {
|
|
|
+ return this.nodes[this.prefix + id];
|
|
|
+ };
|
|
|
+ Tree.prototype.count = function () {
|
|
|
+ var iCount = 0;
|
|
|
+ if (this.roots.length !== 0) {
|
|
|
+ iCount += this.roots.length;
|
|
|
+ this.roots.forEach(function (node) {
|
|
|
+ iCount += node.posterityCount();
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return iCount;
|
|
|
+ };
|
|
|
+
|
|
|
+ Tree.prototype.insert = function (parentID, nextSiblingID) {
|
|
|
+ var newID = this.newNodeID(), node = null, data = {};
|
|
|
+ var parent = parentID === -1 ? null : this.nodes[this.prefix + parentID];
|
|
|
+ var nextSibling = nextSiblingID === -1 ? null: this.nodes[this.prefix + nextSiblingID];
|
|
|
+ if (newID !== -1) {
|
|
|
+ data = {};
|
|
|
+ data[this.setting.id] = newID;
|
|
|
+ data[this.setting.pid] = parentID;
|
|
|
+ data[this.setting.nid] = nextSiblingID;
|
|
|
+ node = new Node(this, data);
|
|
|
+ if (nextSibling) {
|
|
|
+ tools.addNodes(this, parent, [node], nextSibling.siblingIndex());
|
|
|
+ } else {
|
|
|
+ tools.addNodes(this, parent, [node]);
|
|
|
+ }
|
|
|
+ this.nodes[this.prefix + newID] = node;
|
|
|
+ tools.sortTreeItems(this);
|
|
|
+ this.maxNodeID(newID);
|
|
|
+ }
|
|
|
+ return node;
|
|
|
+ };
|
|
|
+ Tree.prototype.delete = function (node) {
|
|
|
+ var success = false;
|
|
|
+ if (node) {
|
|
|
+ delete this.nodes[this.prefix + node.getID()];
|
|
|
+ if (node.preSibling) {
|
|
|
+ node.preSibling.nextSibling = node.nextSibling;
|
|
|
+ }
|
|
|
+ if (node.nextSibling) {
|
|
|
+ node.nextSibling.preSibling = node.preSibling;
|
|
|
+ }
|
|
|
+ if (node.parent) {
|
|
|
+ node.parent.children.splice(node.siblingIndex(), 1);
|
|
|
+ } else {
|
|
|
+ this.roots.splice(node.siblingIndex(), 1);
|
|
|
+ }
|
|
|
+ tools.sortTreeItems(this);
|
|
|
+ success = true;
|
|
|
+ }
|
|
|
+ return success;
|
|
|
+ };
|
|
|
+
|
|
|
+ return new Tree(setting);
|
|
|
+ }
|
|
|
+};
|