Sub-DAG (Node Group)
Sub DAG means a node render can be a DAG view which is generated by Nice-DAG as well. Here is to give a sample which can explain how to generate a sub DAG. To simply the illustratation, the example extends Read-Only DAG.
Step 1: Adapt Node List
Sub-DAG can be regarded as a group of nodes. Before the render adaption, you need to know how a data structure can be represented a node group. There are two ways to define a node group. modelType
of useNiceDag is used to indicated which structure should be used.
Hierarchical Structure
const NodeData = [
{
id: "start",
},
{
id: "task",
dependencies: ["start"],
children: [
//children is an array of nodes which can represent a node group
{
id: "sub-task-1",
},
{
id: "sub-task-2",
dependencies: ["sub-task-1"],
},
],
},
{
id: "end",
dependencies: ["task"],
},
];
In this example, the task is a node which contains a sub DAG view because the node has a children definition with an array.
If you use the hierarchical structure, you don't need any change of useNiceDag parameters because modelType
is HIERARCHY
in default.
Flatten Structure
const NodeData = [
{
id: "start",
},
{
id: "task",
dependencies: ["start"],
},
{
id: "sub-task1",
parentId: "task",
},
{
id: "sub-task2",
parentId: "task",
dependencies: ["sub-task1"],
},
{
id: "end",
dependencies: ["task"],
},
];
In this example, the task is a node which contains a sub DAG view. The difference between flatten structure and hierarchical structure is that the flatten one uses parentId
to grouping nodes. In this sample, sub-task1
and sub-task2
have the same parentId task
so that they are in the same group.
Notes:
Whether to use hierarchical structure or flatten structure, the node id
MUST be unique. This is due to the NiceDagNodes
is unaware of the node layers. It is called by a Teleport component which is associated to a DOM node by the unique id.
If you use the flatten structure, you don't need any change of useNiceDag parameters but set modelType
to FLATTEN
.
<script>
export default() {
setup() {
//call useNiceDag
const { niceDagEl, niceDagReactive } = useNiceDag(
{
initNodes: NodeData,
modelType: 'FLATTEN'
},
false
);
return {
niceDagEl,
niceDagReactive,
};
},
...
}
</script>
Step 2: Adapt the node render
The size of a node group isn't controlled by getNodeSize
because it is determined by the content (children) of the node. Usually, you can call useNiceDag with a parameter subViewPadding
object for a node group
Nice-DAG gives a default sub DAG padding object.
{
top: 40,
bottom: 20,
left: 20,
right: 20,
}
For this example, we can leave the default value. Once the node group has the paddings, you can leverage the padding to add some DOM nodes (e.g. button
, <a/>
) to control the group.
const GroupControl = {
props: ["node", "niceDag"],
emits: ["update:node", "update:niceDag"],
components: [ShrinkSvg, MyButton],
render() {
return (
<div className="my-first-dag-node-group-content">
<div>
{this.node.data?.label || this.node.id}
<button onClick={() => this.node.shrink()}>-</button>
</div>
</div>
);
},
};
const NodeControl = {
props: ["node", "niceDag"],
emits: ["update:node", "update:niceDag"],
render() {
return (
<div className="readonly-sample-node-content">
<span>{this.node.data?.label || this.node.id}</span>
{this.node.children?.length > 0 && (
<button onClick={()=>this.node.expand()}>-<button>
)}
</div>
);
},
};
export const SampleNode = {
props: ["node","niceDagReactive"],
emits: ["update:node","update:niceDagReactive"],
render() {
return (
<div className="my-first-dag-node">
{this.node.children?.length > 0 && !this.node.collapse ? (
<GroupControl node={this.node} niceDag={niceDagReactive.use()} />
) : (
<NodeControl node={this.node} niceDag={niceDagReactive.use()} />
)}
</div>
);
},
};
Notes
Whether to use hierarchical structure of flatten structure, it should use children
to indicate if it is a node group. This is due to Node objects is converted or IViewNode objects once it sets to the useNiceDag.