节点、连线与选择
以下接口由SkyNoteEditor提供。Point中的坐标单位为画布世界单位,嵌套节点的创建坐标相对于父容器;屏幕坐标转换见视口API。
示例中的SkyNoteEditor及EntityRefs等类型从@skynote/editor导入,函数以已有Editor为输入;首次创建实例见快速开始。
创建节点
| 接口 | 返回值 | 坐标与选区 |
|---|---|---|
createNode(request) | string | null | 默认左上角定位,可提供parentId;不改变选区 |
insertNodeAtViewportCenter(request) | string | null | 新节点中心对准当前视口中心,成功后选中新节点 |
insertNodeAt(request, point) | string | null | 新节点中心对准给定世界坐标,成功后选中新节点 |
CreateNodeRequest<T>的公共参数:
| 参数 | 默认 / 要求 |
|---|---|
nodeType | 必填,已注册的节点类型 |
x / y | createNode必填;两个insert方法负责定位 |
origin | top-left;可改为center |
parentId | 缺省为根层级,只在createNode请求中使用 |
id | 缺省自动生成 |
width / height | 缺省使用节点类型创建内容的尺寸 |
rotation | 可选旋转角 |
options | 按nodeType从NodeCreateOptionsMap推导 |
label | 可选的撤销记录名称 |
autoWrap | 创建可接收子节点的容器时,默认自动收纳完全落入其中的同层节点 |
提交被拒绝时检查返回的null。创建请求成功不表示它必定在当前视口内;指定较远坐标后可调用fitContent()。
export function addConnectedNotes(editor: SkyNoteEditor<HTMLElement>): string[] {
const ids: string[] = [];
editor.engine.documentStore.batch(() => {
const first = editor.createNode({ nodeType: 'sticky', x: 0, y: 0, options: { text: '问题' } });
const second = editor.createNode({ nodeType: 'shape', x: 280, y: 30, options: { label: '下一步' } });
if (!first || !second) throw new Error('无法创建示例内容');
ids.push(first, second);
editor.engine.documentStore.createConnector({
connectorType: 'curved',
from: { nodeId: first },
to: { nodeId: second }
});
}, '创建问题与下一步');
editor.select(ids);
return ids;
}连线通过公开文档语义命令创建。内置路由id为straight、orthogonal、curved,端点可绑定nodeId或使用自由世界坐标position。移动节点后绑定连线随路由更新,不需要宿主在每次拖动时手动重建。
查询与可见范围
| 接口 | 返回值 / 用途 |
|---|---|
getNode(id) / getConnector(id) | 只读实体或undefined |
getNodes() / getConnectors() | 当前实体数组;只适合低频全量查询 |
getChildIds(parentId?) | 直接子节点ID,缺省查询根层级 |
nodeCount | 节点总数,不等于当前可见数 |
isNodeVisible(id) / isConnectorVisible(id) | 当前展示可见性,包含布局折叠等影响 |
getNodeBounds(id) | 可见节点实际世界外框,不可见时可为undefined |
getEntitiesBounds(refs) | 节点和连线整体世界外框,全部不存在时为undefined |
nodeAt(point) / connectorAt(point) | 世界坐标处的命中实体 |
getNodeStyle(id) / getConnectorStyle(id) | 合并节点/路由默认值后的生效样式 |
折叠或隐藏的逻辑内容仍可能保留在文档查询中。工具栏定位应使用几何查询,不用x/y/width/height简单拼接旋转节点、分组或整张导图的世界范围。
选区
select(nodeIds, connectorIds = [])替换当前选区;select([], [])清空。不可见实体被过滤,多选时锁定节点也会被过滤。selectedNodeIds和selectedConnectorIds是只读集合。
selectSubtree(rootId)表达布局公开的整体选择意图,只有布局允许时生效;文档写入仍以根节点为入口。selectedSubtreeNodeIds区分整图和单个主题选择,不能通过“选中了中心主题”自行推断整图。
selectAll()选择根层级可操作内容,容器后代随容器处理,不要求宿主枚举所有后代。
export function duplicateSelection(editor: SkyNoteEditor<HTMLElement>): EntityRefs {
return editor.duplicateEntities({ nodeIds: editor.selectedNodeIds, connectorIds: editor.selectedConnectorIds });
}修改与几何
| 接口 | 参数与行为 |
|---|---|
updateNodes(ids, fields, options?) | 字段对象或逐节点函数;style/data默认合并,merge:false改为替换 |
updateNodeStyle(ids, style, options?) | 只改提供的样式项;透明色会拆为颜色与透明度字段 |
setNodeRadius(ids, radius, options?) | 四角统一,或通过corner只改某个角 |
setNodeSize(ids, {width?, height?}, options?) | 左上角保持,按节点比例锁定与缩放策略计算 |
setNodeRotation(ids, rotation, options?) | 各节点绕自身中心设置角度 |
rotateNodesBy(ids, degrees, options?) | 绕所选节点整体中心做增量旋转 |
fitNodesContent(ids) | 调整节点外框以适应内容,不支持或已适应者跳过 |
setLocked(refs, locked) | 一次事务修改节点与连线锁定 |
setAspectLocked(ids, locked) | 修改节点比例锁定 |
普通修改命令大多返回void,不把返回值当成功标记。只读、事务守卫、锁定或布局约束可能影响是否执行;UI先查询可用能力,再提交对应语义命令。
连续数值面板通过groupId合并历史;关闭/失焦调用endGeometryEdit(groupId),详见历史API。
组合、排列与删除
| 接口 | 返回值 / 条件 |
|---|---|
canGroupNodes(ids) / canUngroupNodes(ids) | 查询当前是否可执行 |
groupNodes(ids) | 新组合ID或null,成功后选中组合 |
ungroupNodes(ids) | 释放的子节点ID数组,并更新选区;也可解散有子节点的容器外壳 |
duplicateEntities(refs, offset?) | 顶层副本ID集合,默认偏移{x:20,y:20};含后代和内部连线 |
deleteEntities(refs, label?) | 级联删除节点后代及依附连线,一步撤销 |
alignNodes(ids, alignment) | 按世界外框对齐;受锁定或自动布局约束时可能不执行 |
distributeNodes(ids, axis) | 至少三个独立节点,固定两端,均分边缘间距 |
autoArrangeNodes(ids, options?) | 单次网格整理,不改变尺寸、朝向或父子关系 |
EntityRefs的nodeIds与connectorIds均为可选Iterable,缺省类别视为空。删除分组或容器会影响其内容,不能当作只删一个外框。