Graphlib JS 学习笔记

Graphlib是一个用于直接或间接地制作或修改图画的javascript库

一、基本概念

(1)、Graphlib只有一个图形类型,我们需要先创建它的实例

var g = new graphlib.Graph();

默认情况下,将创建一个不允许多边或复合节点的有向图,构造提供了三个参数:
1. directed 该值为true时图为有向图,default:true
2. multigraph 该值为true时允许一个图在同一对节点之间有多个边,default:false
3. compound 该值为true时允许图具有复合节点-节点可以是其他节点的父节点, default:false
创建有向多边复合图:

var g = new Graph({ directed: true, compound: true, multigraph: true });

(2)、节点和边的表示

1.设置节点的id

var g = new graphlib.Graph();
g.setNode('a-id', 'a-text');
console.log('a-id'); // 'a-text'
//所有与节点相关的函数都使用此id作为唯一标识。

2.边是通过连接的节点来识别的

var g = new graphlib.Graph();
g.setEdge('source', 'target', 'text');
console.log(g.edge('source', 'target'));

3.边对象 edgeObjs 用来唯一地识别单个对象中的边缘,用于各种边缘查询

(3)、多图

(4)、复合图

(5)、默认标签

二、API

(1)、graph.isDirected() 是否为有向图

(2)、graph.isMultigraph() 是否为多图

(3)、graph.isCompound() 是否为复合图

(4)、graph.graph() 返回当前分配的图形标签,若未定义则返回 undefined

var g = new graphlib.Graph();
g.graph(); // undefined
g.setGraph('aaa');
g.graph(); // aaa

(5)、graph.setGraph(label) 设置图像标签

(6)、graph.nodeCount() 返回图中的节点个数

(7)、graph.edgeCount() 返回图中的边数

(8)、graph.setDefaultNodeLabel(val)

(9)、graph.setDefaultEdgeLabel(val)

(10)、graph.nodes() 返回图中节点的 id 数组

(11)、graph.edges() 返回图中所有的边

(12)、graph.sources() 返回图中没有内边的节点 id (源)

(13)、graph.sinks() 返回图中没有外边的节点 id (目标)

(14)、graph.hasNode(v) 根据id判断节点在图中是否存在

(15)、graph.node(v) 根据id获取节点的标签,若无标签则返回 undefined

(16)、graph.setNode(v, [label]) 设置节点的标签,若不设置则使用默认的

(17)、graph.removeNode(v) 移除节点

(18)、graph.predecessors(v) 返回指定节点的所有前续节点

(19)、graph.successors(v) 返回指定节点的所有后继节点

(20)、graph.neighbors(v) 返回指定节点的所有前续节点和后继节点

(21)、graph.inEdges(v, [u]) 返回指向节点v的所有边

(22)、graph.outEdges(v, [w]) 返回由节点v指向的所有边

(23)、graph.nodeEdges(v, [w]) 不论方向如何,返回节点v的所有边

(24)、graph.parent(v) 返回节点v的父节点,如果节点v没有父节点或不是图的成员,则返回未定义的节点。对于非复合图总是返回 undefined

(25)、graph.children(v) 返回节点v的所有子节点,若节点v不在图中则返回 undefined,对于非复合图,始终返回[]

(26)、graph.setParent(v, parent) 如果定义了父函数,则将父函数设置为父函数,如果父函数未定义,则将父对象移除。如果图不是复合图,则抛出一个错误

(27)、graph.hasEdge(v, w, [name]) or graph.hasEdge(edgeObj) 判断边是否存在

(28)、graph.edge(v, w, [name]) or graph.edge(edgeObj) 获取边

(29)、graph.setEdge(v, w, [label], [name]) or graph.setEdge(edgeObj, [label]) 创建或更新边

(30)、graph.removeEdge(v, w) 移除边

三、图形与 json 数据格式的转换

(1)、json.write(g) 将图形对象转换为 json 对象

var g = new graphlib.Graph();
g.setNode('a', { lable: 'node a' });
g.setNode('b', { lable: 'node b' });
g.setEdge('a', 'b', { lable: 'edge a->b' });
var data = graphlib.json.write(g);
console.log(JSON.stringify(data));

(2)、json.read(json) 将json对象读取成图形对象

var g2 = graphlib.json.read(JSON.parse(str));
// or, in order to copy the graph
var g3 = graphlib.json.read(graphlib.json.write(g));
g2.nodes();
// ['a', 'b']
g2.edges();
// [ { v: 'a', w: 'b' } ]

四、关于实现的一些算法函数

(1)、alg.components(graph) 查找图表中的所有连接组件并返回这些组件的数组
算法示意图

var g = new graphlib.Graph();

g.setNode('a', { label: 'node a' });
g.setNode('b', { label: 'node b' });
g.setNode('c', { label: 'node c' });
g.setNode('d', { label: 'node d' });
g.setNode('e', { label: 'node e' });
g.setNode('f', { label: 'node f' });
g.setNode('g', { label: 'node g' });
g.setNode('h', { label: 'node h' });
g.setNode('i', { label: 'node i' });

g.setEdge('e', 'f');
g.setEdge('e', 'g');

g.setEdge('a', 'b');
g.setEdge('b', 'c');
g.setEdge('c', 'd');
g.setEdge('d', 'a');

g.setEdge('h', 'i');

console.log(graphlib.alg.components(g));
/*
返回:
[
    ['a', 'b', 'c', 'd'],
    ['e', 'f', 'g'],
    ['h', 'i']
]
*/

(2)、alg.dijkstra(graph, source, weightFn, edgeFn) 返回其他节点到指定节点的最短路径,第三个参数是计算边的权重函数,默认为1。第四个参数默认采用 g.outEdges(source)
算法示意图

function weight(e) {
    return g.edge(e);
}

graphlib.alg.dijkstra(g, "A", weight);
// 返回: { A: { distance: 0 },
//         B: { distance: 6, predecessor: 'C' },
//         C: { distance: 4, predecessor: 'A' },
//         D: { distance: 2, predecessor: 'A' },
//         E: { distance: 8, predecessor: 'F' },
//         F: { distance: 4, predecessor: 'D' } }

(3)、alg.dijkstraAll(graph, weightFn, edgeFn)

(4)、alg.findCycles(graph)

(5)、alg.floydWarshall(graph, weightFn, edgeFn)

(6)、alg.isAcyclic(graph) 判断图中是否存在循环路径,无循环路径返回 true,否则返回 false

var g = new graphlib.Graph();

g.setNode(1);
g.setNode(2);
g.setNode(3);
g.setEdge(1, 2);
g.setEdge(2, 3);

graphlib.alg.isAcyclic(g); // true

g.setEdge(3, 1);
graphlib.alg.isAcyclic(g); // false

注意:对于有向复合多边图,该方法只会根据方向路径去判断是否存在循环路径。对于无向复合多边图,该方法总是返回 false

(7)、alg.postorder(graph, vs)

(8)、alg.preorder(graph, vs)

(9)、alg.prim(graph, weightFn)

(10)、alg.tarjan(graph)

(11)、alg.topsort(graph)

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值