树形框设计理念

文档创建者:admin
浏览次数:59
最后更新:2025-06-24

树形框(Tree List)组件使用文档  
版本 v2.1  · 代码文件:树形框.js  

----------------------------------------------------------------  
一、组件简介  
----------------------------------------------------------------  
1. 纯 PIXI.js 渲染,支持任意深度的树状数据展示  
2. 节点可展开 / 折叠,可选自定义容器(按钮、输入框等)  
3. 行高自动匹配内容高度,支持单节点行高及全局行间距设置  
4. 内置滚动条,支持鼠标滚轮与拖动滑块  
5. 提供丰富的运行时 API 进行节点与样式的动态操作  

----------------------------------------------------------------  
二、主要属性(Options 字段)  
----------------------------------------------------------------  
宽度              Number 300      组件宽度  
高度              Number 400      组件高度  
背景颜色          Number 0xf8f8f8 背景填充色  
背景透明度        Number 1        范围 0-1  
边框颜色          Number 0xcccccc 边框颜色  
边框宽度          Number 1        边框线宽  
圆角              Number 4        背景圆角  
节点高度          Number 24       行高基准  
行间距            Number 4        相邻节点间垂直空隙  
缩进              Number 20       每层级向右缩进  
文本颜色          Number 0x333333 普通文本颜色  
文本大小          Number 14       字体大小  
文本字体          String Arial    字体  
选中颜色          Number 0x4a90e2 选中行背景色  
悬停颜色          Number 0xe8e8e8 鼠标悬停行色  
显示连接线        Boolean true    是否绘制父子连线  
连接线颜色        Number 0xcccccc 连线颜色  
显示展开图标      Boolean true    全局图标显隐  
展开图标颜色      Number 0x666666 三角形颜色  
展开图标宽度      Number 10       图标宽  
展开图标高度      Number 10       图标高  
展开图标偏移X     Number 5        图标水平偏移  
展开图标偏移Y     Number 0        图标垂直偏移  
滚动条宽度        Number 6        右侧滚动条宽度  
滚动条颜色        Number 0x999999 滑块颜色  
滚动条透明度      Number 0.8      滑块透明度  
滚动步长          Number 40       鼠标滚轮一次滚动像素  
允许穿透          Boolean false   是否让节点透传点击  
调试模式          Boolean false   输出调试日志  
节点列表          Array  []       初始化树数据  

----------------------------------------------------------------  
三、节点对象 TreeNode  
----------------------------------------------------------------  
文本              String            普通文字(与自定义容器二选一)  
自定义容器        PIXI.Container    复杂节点显示区域  
展开              Boolean           初始展开状态,默认 false  
显示展开图标      Boolean           覆盖全局图标显隐  
自定义行高        Number            指定行高像素值  
子节点            TreeNode[]        嵌套子节点数组  

----------------------------------------------------------------  
四、公开函数(全部可在业务代码调用)  
----------------------------------------------------------------  
初始化(x, y, 宽?, 高?, 选项?)       创建或重绘组件  
获取容器()                         返回 PIXI.Container 以加入舞台  
设置节点列表(list)                 整体替换树数据  
插入节点(parent, data, index?)     动态插入节点,返回句柄  
设置节点属性(handle, obj)          批量修改单节点字段  
设置节点行高(handle, height)       指定某节点行高  
设置行间距(pixels)                 修改全局行间距  
选择节点(nodeContainer)            手动高亮节点  
获取选中节点()                      返回当前选中节点或 null  
更新选项(obj)                      一次覆盖多个选项并刷新  
设置选项(key, value)               单项样式修改  
销毁()                              释放所有资源  

----------------------------------------------------------------  
五、事件  
----------------------------------------------------------------  
节点选择     在 tree.获取容器() 上触发  
             回调参数 (nodeData)  
             当节点被点击并设为选中时触发  

----------------------------------------------------------------  
六、典型操作示例  
----------------------------------------------------------------  
// 创建并加入舞台  
const tree = new 树形框();  
tree.初始化(20, 20, 300, 400);  
app.stage.addChild(tree.获取容器());  

// 设置初始树数据  
tree.设置节点列表([  
  { 文本:'目录 A', 展开:true, 子节点:[ { 文本:'文件 A-1' } ] },  
  { 文本:'目录 B' }  
]);  

// 动态插入节点  
const root = tree.插入节点(null, { 文本:'目录 C', 展开:true });  
tree.插入节点(root, { 文本:'子文件' });  

// 全局行间距和单行高度  
tree.设置行间距(8);             // 所有行间隔 8 像素  
tree.设置节点行高(root, 60);     // root 行高 60 像素  

// 修改滚动条颜色  
tree.设置选项('滚动条颜色', 0xff8800);  

// 监听节点选择  
tree.获取容器().on('节点选择', n => console.log('选中:', n));  

// 销毁  
tree.销毁();  

----------------------------------------------------------------  
七、注意事项  
----------------------------------------------------------------  
1. 行高自动取节点高度、节点自定义行高、自定义容器高度三者的最大值  
2. 隐藏图标时仍保留占位,列对齐不变  
3. 内容超出高度时滚动条自动出现,滚轮或拖动均可滚动  
4. 调用 设置节点列表 会让旧节点句柄失效,需重新保存  
5. 若需禁用自定义容器交互,可给容器设置 eventMode = 'none'

发表评论已发布 3

admin

发表于 2025-6-24 19:33:12 | 显示全部楼层

树形框拖放功能使用方法:

1. **启用拖放功能**:
   ```javascript
   var 树组件 = new 树形框();
   树组件.初始化(x, y, 宽度, 高度, {
     允许拖动: true,  // 默认已启用
     拖动触发时间: 500  // 长按触发时间(毫秒)
   });
   ```

2. **拖放操作方式**:
   - 长按节点约500毫秒触发拖动模式
   - 拖动到目标位置,会显示三种放置指示:
     - 上区域:插入到目标节点之前
     - 中间区域:插入为目标节点的子节点
     - 下区域:插入到目标节点之后

3. **监听拖放事件**:
   ```javascript
   树组件.获取容器().on('节点拖动开始', function(节点数据, 节点容器) {
     console.log('开始拖动:', 节点数据.文本);
   });
   
   树组件.获取容器().on('节点拖放完成', function(源节点数据, 目标节点数据, 位置) {
     console.log('拖放完成:', 源节点数据.文本, '到', 目标节点数据.文本, '位置:', 位置);
   });
   
   树组件.获取容器().on('节点拖动取消', function(源节点数据) {
     console.log('拖动取消:', 源节点数据.文本);
   });
   ```

4. **自定义拖放外观**:
   ```javascript
   树组件.初始化(x, y, 宽度, 高度, {
     指示线颜色: 0xff3300,         // 指示线颜色
     指示线宽度: 3,               // 指示线宽度
     指示线闪烁间隔: 300,         // 闪烁间隔(毫秒)
     拖动副本透明度: 0.7,         // 拖动时节点副本透明度
     中间区域比例: 0.4,           // 中间区域所占比例(0-0.6)
     before放置颜色: 0xff3300,    // 前方放置指示线颜色
     after放置颜色: 0xff3300,     // 后方放置指示线颜色
     inside放置颜色: 0x00cc00,    // 子节点放置高亮颜色
     inside放置背景透明度: 0.3    // 子节点放置背景透明度
   });
   ```

5. **禁用特定节点的拖动**:
   ```javascript
   var 节点数据 = {
     文本: "不可拖动节点",
     禁止拖动: true,
     子节点: []
   };
   ```

6. **动态控制拖放功能**:
   ```javascript
   // 启用/禁用拖动功能
   树组件.设置允许拖动(true或false);
   
   // 修改长按触发时间
   树组件.设置拖动触发时间(800); // 单位毫秒
   ```

拖放操作会自动处理节点的移动,包括从原位置删除和添加到新位置,并会自动展开目标父节点。

admin

发表于 2025-6-24 19:42:15 | 显示全部楼层

树形框组件的项目操作方法:

## 1. 插入节点
```javascript
// 插入到根级
var 新节点 = 树组件.插入节点(null, {
    文本: "新节点",
    子节点: [],
    展开: false
});

// 插入到特定父节点
var 父节点 = 树组件.获取选中节点(); // 或其他方式获取节点引用
var 子节点 = 树组件.插入节点(父节点, {
    文本: "子节点",
    子节点: []
});

// 在特定位置插入
var 指定位置节点 = 树组件.插入节点(父节点, {
    文本: "指定位置节点"
}, 2); // 在父节点的子节点列表中索引2的位置插入
```

## 2. 修改节点
```javascript
// 修改节点属性
var 节点 = 树组件.获取选中节点();
树组件.设置节点属性(节点, {
    文本: "修改后的文本",
    展开: true,
    // 其他属性...
});

// 修改节点行高
树组件.设置节点行高(节点, 32); // 设置为32像素高
```

## 3. 删除节点
```javascript
// 删除节点需要找到其父节点和索引
function 删除节点(树组件, 要删除的节点) {
    // 查找父节点
    function 查找父节点(节点列表, 目标节点, 父节点) {
        for (var i = 0; i < 节点列表.length; i++) {
            var 当前节点 = 节点列表[i];
            if (当前节点 === 目标节点) {
                return { 父节点: 父节点, 索引: i };
            }
            
            if (当前节点.子节点 && 当前节点.子节点.length > 0) {
                var 结果 = 查找父节点(当前节点.子节点, 目标节点, 当前节点);
                if (结果) return 结果;
            }
        }
        return null;
    }
   
    // 获取所有节点列表
    var 所有节点 = 树组件.选项.节点列表;
   
    // 查找要删除的节点位置
    var 查找结果 = 查找父节点(所有节点, 要删除的节点, null);
   
    if (查找结果) {
        var 父节点 = 查找结果.父节点;
        var 索引 = 查找结果.索引;
        
        // 从父节点的子节点列表中删除
        if (父节点) {
            父节点.子节点.splice(索引, 1);
        } else {
            // 根级节点
            所有节点.splice(索引, 1);
        }
        
        // 更新显示
        树组件._更新节点显示();
    }
}

// 使用方法
var 要删除的节点 = 树组件.获取选中节点();
删除节点(树组件, 要删除的节点);
```

## 4. 结合事件处理
```javascript
// 示例:右键菜单处理节点操作
树组件.获取容器().on('节点选择', function(节点数据) {
    var 菜单 = [
        {
            文本: "添加子节点",
            点击: function() {
                树组件.插入节点(节点数据, {
                    文本: "新子节点",
                    子节点: []
                });
            }
        },
        {
            文本: "修改节点",
            点击: function() {
                var 新文本 = prompt("输入新名称:", 节点数据.文本);
                if (新文本) {
                    树组件.设置节点属性(节点数据, {
                        文本: 新文本
                    });
                }
            }
        },
        {
            文本: "删除节点",
            点击: function() {
                if (confirm("确定删除节点?")) {
                    删除节点(树组件, 节点数据);
                }
            }
        }
    ];
   
    显示右键菜单(菜单); // 假设有显示右键菜单的函数
});
```

## 5. 拖放操作自动处理节点移动
拖放功能已经内置了节点移动逻辑,会自动处理:
- 从源位置删除节点
- 添加到目标位置
- 自动展开目标父节点

您只需启用拖放功能,不需要额外编写移动代码。

admin

发表于 2025-6-24 19:45:37 | 显示全部楼层

在树形框组件中,每个节点默认没有自动生成的唯一标识符,但您可以很容易地为节点添加唯一ID或其他标识信息。这是处理节点标识和关联对象的几种方法:

## 1. 添加唯一ID字段

在创建节点时,可以手动添加ID字段:

```javascript
var 节点数据 = {
    id: "node_" + Math.random().toString(36).substr(2, 9), // 生成随机ID
    文本: "节点名称",
    子节点: [],
    // 可以添加其他自定义字段
    关联对象ID: "obj_123", // 关联到其他对象的ID
    自定义数据: { ... }    // 存储任何相关数据
};

树组件.插入节点(null, 节点数据);
```

## 2. 直接关联对象引用

节点数据对象可以直接包含对其他对象的引用:

```javascript
var 业务对象 = {
    名称: "某业务对象",
    属性1: "值1",
    属性2: "值2"
};

var 节点数据 = {
    文本: 业务对象.名称,
    子节点: [],
    关联对象: 业务对象 // 直接引用对象
};

树组件.插入节点(null, 节点数据);
```

## 3. 使用事件处理关联

```javascript
// 全局对象映射表
var 对象映射 = {};

// 创建节点时,存储映射关系
function 创建节点(业务对象) {
    var 节点ID = "node_" + Date.now();
    var 节点数据 = {
        id: 节点ID,
        文本: 业务对象.名称,
        子节点: []
    };
   
    // 存储映射关系
    对象映射[节点ID] = 业务对象;
   
    return 树组件.插入节点(null, 节点数据);
}

// 在事件处理中使用映射查找对象
树组件.获取容器().on('节点选择', function(节点数据) {
    if (节点数据.id && 对象映射[节点数据.id]) {
        var 关联对象 = 对象映射[节点数据.id];
        console.log("找到关联对象:", 关联对象);
        // 进行相关操作...
    }
});
```

## 4. 使用节点路径作为标识

```javascript
// 根据节点路径查找节点
function 获取节点路径(节点数据) {
    var 路径 = [];
   
    function 查找路径(节点列表, 目标节点, 当前路径) {
        for (var i = 0; i < 节点列表.length; i++) {
            var 节点 = 节点列表[i];
            var 新路径 = 当前路径.concat([i]);
            
            if (节点 === 目标节点) {
                return 新路径;
            }
            
            if (节点.子节点 && 节点.子节点.length > 0) {
                var 子路径 = 查找路径(节点.子节点, 目标节点, 新路径);
                if (子路径) return 子路径;
            }
        }
        return null;
    }
   
    return 查找路径(树组件.选项.节点列表, 节点数据, []);
}

// 使用路径查找节点
function 根据路径查找节点(路径) {
    var 当前节点列表 = 树组件.选项.节点列表;
    var 节点 = null;
   
    for (var i = 0; i < 路径.length; i++) {
        var 索引 = 路径[i];
        节点 = 当前节点列表[索引];
        当前节点列表 = 节点.子节点 || [];
    }
   
    return 节点;
}
```

## 5. 在修改节点后保持关联

当修改节点时,您可以保留原有的ID或关联信息:

```javascript
// 修改节点但保留ID和关联信息
var 节点 = 树组件.获取选中节点();
树组件.设置节点属性(节点, {
    文本: "新文本"
    // 不修改id和关联对象字段,它们会被保留
});
```

通过以上方法,您可以确保即使在节点被修改或移动后,仍能找到它关联的业务对象。最常用的方法是添加唯一ID和直接引用对象,这样可以在任何时候轻松找到节点与业务对象之间的对应关系。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则