BaseGraph

BaseGraph

这类节点拥有图的结构。

图上的每个节点被抽象为一个个 node,图上的每条连边被抽象为一条条 link。

这是一个抽象类,不应该被实例化。

API 列表

type GraphMode = "direct" | "undirect";

class BaseGraph extends SD2DNode {
    // 与 node 有关的查询
    nodes(): Array<SDNode>;
    nodesId(): Array<string>;
    element(node: number | string | SDNode): SDNode | undefined;
    nodeId(node: number | string | SDNode): string | undefined;

    // 与 link 有关的查询
    links(): Array<SDNode>;
    element(source: number | string | SDNode, target: number | string | SDNode): SDNode | undefined;
    source(link: SDNode): SDNode | undefined;
    target(link: SDNode): SDNode | undefined;
    sourceId(link: SDNode): string | undefined;
    targetId(link: SDNode): string | undefined;
    toNode(link: SDNode, source: number | string | SDNode): string | undefined;
    toNodeId(link: SDNode, source: number | string | SDNode): string | undefined;

    // 筛查
    findNode(condition: (node: SDNode, id: string) => boolean): SDNode | undefined;
    findNodes(condition: (node: SDNode, id: string) => boolean): Array<SDNode>;
    findLink(condition: (link: SDNode, sourceId: string, targetId: string) => boolean): SDNode | undefined;
    findLinks(condition: (link: SDNode, sourceId: string, targetId: string) => boolean): Array<SDNode>;
    findNodeById(id: number | string): SDNode | undefined;
    findLinkById(sourceId: number | string, targetId: number | string): SDNode | undefined;

    // 基础信息查询
    inLinks(node: number | string | SDNode, mode: GraphMode): Array<SDNode>;
    outLinks(node: number | string | SDNode, mode: GraphMode): Array<SDNode>;
    inNodes(node: number | string | SDNode, mode: GraphMode): Array<SDNode>;
    inNodesId(node: number | string | SDNode, mode: GraphMode): Array<string>;
    outNodes(node: number | string | SDNode, mode: GraphMode): Array<SDNode>;
    outNodesId(node: number | string | SDNode, mode: GraphMode): Array<string>;
    forEachInNode(node: number | string | SDNode, mode: GraphMode, callback: (node: SDNode, id: string) => void): this;
    forEachInLink(node: number | string | SDNode, mode: GraphMode, callback: (link: SDNode, sourceId: string, targetId: string) => void): this;
    forEachOutNode(node: number | string | SDNode, mode: GraphMode, callback: (node: SDNode, id: string) => void): this;
    forEachOutLink(node: number | string | SDNode, mode: GraphMode, callback: (link: SDNode, sourceId: string, targetId: string) => void): this;
    forEachNode(callback: (node: SDNode, id: string) => void): this;
    forEachLink(callback: (link: SDNode, sourceId: string, targetId: string) => void): this;

    // 图的结构管理
    link(sourceId: number | string, targetId: number | string, value?: any): this;
    newNode(id: number | string, value?: any): this;
    newNodeFromExistValue(id: number | string, value: SDNode): this;
    newNodeFromExistElement(id: number | string, element: SDNode): this;
    newLink(sourceId: number | string, targetId: number | string, value?: any): this;
    newLinkFromExistValue(sourceId: number | string, targetId: number | string, value: SDNode): this;
    newLinkFromExistElement(sourceId: number | string, targetId: number | string, element: SDNode): this;
    cut(sourceId: number | string, targetId: number | string): this;

    // 元素属性管理
    opacity(node: number | string | SDNode): number;
    opacity(node: number | string | SDNode, opacity: number): this;
    nodeOpacity(node: number | string | SDNode): number;
    nodeOpacity(node: number | string | SDNode, opacity: number): this;
    opacity(source: number | string | SDNode, target: number | string | SDNode): number;
    opacity(source: number | string | SDNode, target: number | string | SDNode, opacity: number): this;
    linkOpacity(source: number | string | SDNode, target: number | string | SDNode): number;
    linkOpacity(source: number | string | SDNode, target: number | string | SDNode, opacity: number): this;
    color(color: SDColor): this;
    color(node: number | string | SDNode): PacketColor;
    color(node: number | string | SDNode, color: SDColor): this;
    color(source: number | string | SDNode, target: number | string | SDNode): PacketColor;
    color(source: number | string | SDNode, target: number | string | SDNode, color: SDColor): this;
    text(node: number | string | SDNode): string;
    text(node: number | string | SDNode, text: string): this;
    nodeText(node: number | string | SDNode): string;
    nodeText(node: number | string | SDNode, text: string): this;
    text(source: number | string | SDNode, target: number | string | SDNode): string;
    text(source: number | string | SDNode, target: number | string | SDNode, text: string): this;
    linkText(source: number | string | SDNode, target: number | string | SDNode): string;
    linkText(source: number | string | SDNode, target: number | string | SDNode, text: string): this;
    intValue(node: number | string | SDNode): number;
    intValue(source: number | string | SDNode, target: number | string | SDNode): number;
    value(node: number | string | SDNode): SDNode | undefined;
    value(node: number | string | SDNode, value: any): this;
    nodeValue(node: number | string | SDNode): SDNode | undefined;
    nodeValue(node: number | string | SDNode, value: any): this;
    value(source: number | string | SDNode, target: number | string | SDNode): SDNode | undefined;
    value(source: number | string | SDNode, target: number | string | SDNode, value: any): this;
    linkValue(source: number | string | SDNode, target: number | string | SDNode): SDNode | undefined;
    linkValue(source: number | string | SDNode, target: number | string | SDNode, value: any): this;
}

与 node 相关的查询

class BaseGraph {
    nodes(): Array<SDNode>; // 获取所有的节点
    nodesId(): Array<string>; // 获取所有的节点索引
    element(node: number | string | SDNode): SDNode | undefined; // 获取目标节点
    nodeId(node: number | string | SDNode): string | undefined; // 获取目标节点对应的索引
}

这类方法可以用来查询一些 node 信息。

与 link 相关的查询

class BaseGraph {
    links(): Array<SDNode>; // 获取所有的连边
    element(source: number | string | SDNode, target: number | string | SDNode): SDNode | undefined; // 获取目标连边
    source(link: SDNode): SDNode | undefined; // 获取目标连边的起点
    target(link: SDNode): SDNode | undefined; // 获取目标连边的终点
    sourceId(link: SDNode): string | undefined; // 获取目标连边的起点索引
    targetId(link: SDNode): string | undefined; // 获取目标连边的终点索引
    toNode(link: SDNode, source: number | string | SDNode): string | undefined; // 给定连边和其中一个端点,获取另一个端点
    toNodeId(link: SDNode, source: number | string | SDNode): string | undefined; // 给定连边和其中一个端点,获取另一个端点索引
}

这类方法可以用来查询一些 link 信息。

筛查

class BaseGraph {
    findNode(condition: (node: SDNode, id: string) => boolean): SDNode | undefined; // 查找第一个符合条件的节点
    findNodes(condition: (node: SDNode, id: string) => boolean): Array<SDNode>; // 查找所有符合条件的节点
    findLink(condition: (link: SDNode, sourceId: string, targetId: string) => boolean): SDNode | undefined; // 查找第一条符合条件的连边
    findLinks(condition: (link: SDNode, sourceId: string, targetId: string) => boolean): Array<SDNode>; // 查找所有符合条件的连边
    findNodeById(id: number | string): SDNode | undefined; // 根据节点索引查找节点
    findLinkById(sourceId: number | string, targetId: number | string): SDNode | undefined; // 根据连边索引查找连边
}

各种各样的筛选 node 和 link 的方法。

基础信息查询

class BaseGraph {
    inLinks(node: number | string | SDNode, mode: GraphMode): Array<SDNode>; // 获取目标节点的所有入边
    outLinks(node: number | string | SDNode, mode: GraphMode): Array<SDNode>; // 获取目标节点的所有出边
    inNodes(node: number | string | SDNode, mode: GraphMode): Array<SDNode>; // 获取目标节点的所有入边的另一端点
    inNodesId(node: number | string | SDNode, mode: GraphMode): Array<string>; // 获取目标节点的所有入边的另一端点索引
    outNodes(node: number | string | SDNode, mode: GraphMode): Array<SDNode>; // 获取目标节点的所有出边的另一端点
    outNodesId(node: number | string | SDNode, mode: GraphMode): Array<string>; // 获取目标节点的所有出边的另一端点索引
    forEachInNode(node: number | string | SDNode, mode: GraphMode, callback: (node: SDNode, id: string) => void): this; // 遍历目标节点的所有入边的另一端点
    forEachInLink(node: number | string | SDNode, mode: GraphMode, callback: (link: SDNode, sourceId: string, targetId: string) => void): this; // 遍历目标节点的所有入边
    forEachOutNode(node: number | string | SDNode, mode: GraphMode, callback: (node: SDNode, id: string) => void): this; // 遍历目标节点的所有出边的另一端点
    forEachOutLink(node: number | string | SDNode, mode: GraphMode, callback: (link: SDNode, sourceId: string, targetId: string) => void): this; // 遍历目标节点的所有出边
    forEachNode(callback: (node: SDNode, id: string) => void): this; // 遍历所有节点
    forEachLink(callback: (link: SDNode, sourceId: string, targetId: string) => void): this; // 遍历所有连边
}

各种邻接点信息。

图的结构管理

class BaseGraph {
    link(sourceId: number | string, targetId: number | string, value?: any): this; // 连接两个节点
    newNode(id: number | string, value?: any): this; // 新建一个节点
    newNodeFromExistValue(id: number | string, value: SDNode): this; // 新建一个节点
    newNodeFromExistElement(id: number | string, element: SDNode): this; // 新建一个节点
    newLink(sourceId: number | string, targetId: number | string, value?: any): this; // 新建一条连边
    newLinkFromExistValue(sourceId: number | string, targetId: number | string, value: SDNode): this; // 新建一条连边
    newLinkFromExistElement(sourceId: number | string, targetId: number | string, element: SDNode): this; // 新建一条连边
    cut(sourceId: number | string, targetId: number | string): this; // 删除一条连边
}

让我们试着构建一张图:

const svg = sd.svg();
const dag1 = new sd.DAG(svg).link(1, 2).link(1, 3).link(2, 3).width(100).height(100);
const dag2 = new sd.DAG(svg).newNode(1).newNode(2).newNode(3).newLink(1, 2).newLink(1, 3).newLink(2, 3).dx(300).width(100).height(100);

试一试,两张图的构建都是正确的。link 和 newLink 的区别在于,对 link 而言,它会检查连边两端的节点是否存在,如果不存在则会自动创建,而 newLink 只完成连边的创建这一个任务。link 相比于 newLink 更加智能。

如果我们希望在创建节点的时候,每个节点上显示的不是其索引,而是别的什么东西,则可以这样做:

const svg = sd.svg();
const C = sd.color();
const dag = new sd.DAG(svg).width(100).height(100);
dag.newNode(1, new sd.Rect(svg).color(C.orange));
dag.newNode(2, new sd.Circle(svg).color(C.blue));
dag.newNode(3, new sd.Image(svg).href("/img/gift.png"));
dag.link(1, 2).link(1, 3).link(2, 3);

同样,我们可以指定连边上显示一些额外信息:

const svg = sd.svg();
const C = sd.color();
const dag = new sd.DAG(svg).width(100).height(100);
dag.link(1, 2, new sd.Image(svg).href("/img/gift.png").scale(0.5));
dag.newNode(3).newLink(1, 3, new sd.Image(svg).href("/img/snowflake.png").scale(0.5));
dag.newLink(2, 3, new sd.Rect(svg).color(C.blue).scale(0.5));

元素属性管理

这里提供了一些方法,对节点和连边的各项属性进行快捷操作。

opacity

class BaseGraph {
    opacity(node: number | string | SDNode): number;
    opacity(node: number | string | SDNode, opacity: number): this;
    nodeOpacity(node: number | string | SDNode): number;
    nodeOpacity(node: number | string | SDNode, opacity: number): this;
    opacity(source: number | string | SDNode, target: number | string | SDNode): number;
    opacity(source: number | string | SDNode, target: number | string | SDNode, opacity: number): this;
    linkOpacity(source: number | string | SDNode, target: number | string | SDNode): number;
    linkOpacity(source: number | string | SDNode, target: number | string | SDNode, opacity: number): this;
}

color

class BaseGraph {
    color(color: SDColor): this;
    color(node: number | string | SDNode): PacketColor;
    color(node: number | string | SDNode, color: SDColor): this;
    color(source: number | string | SDNode, target: number | string | SDNode): PacketColor;
    color(source: number | string | SDNode, target: number | string | SDNode, color: SDColor): this;
}

text

class BaseGraph {
    text(node: number | string | SDNode): string;
    text(node: number | string | SDNode, text: string): this;
    nodeText(node: number | string | SDNode): string;
    nodeText(node: number | string | SDNode, text: string): this;
    text(source: number | string | SDNode, target: number | string | SDNode): string;
    text(source: number | string | SDNode, target: number | string | SDNode, text: string): this;
    linkText(source: number | string | SDNode, target: number | string | SDNode): string;
    linkText(source: number | string | SDNode, target: number | string | SDNode, text: string): this;
}

intValue

class BaseGraph {
    intValue(node: number | string | SDNode): number;
    intValue(source: number | string | SDNode, target: number | string | SDNode): number;
}

value

class BaseGraph {
    value(node: number | string | SDNode): SDNode | undefined;
    value(node: number | string | SDNode, value: any): this;
    nodeValue(node: number | string | SDNode): SDNode | undefined;
    nodeValue(node: number | string | SDNode, value: any): this;
    value(source: number | string | SDNode, target: number | string | SDNode): SDNode | undefined;
    value(source: number | string | SDNode, target: number | string | SDNode, value: any): this;
    linkValue(source: number | string | SDNode, target: number | string | SDNode): SDNode | undefined;
    linkValue(source: number | string | SDNode, target: number | string | SDNode, value: any): this;
}