Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
tianyazhichiC
algorithm-visualizer
提交
c1656493
A
algorithm-visualizer
项目概览
tianyazhichiC
/
algorithm-visualizer
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
A
algorithm-visualizer
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
c1656493
编写于
2月 28, 2017
作者:
J
Jason Park
提交者:
GitHub
2月 28, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #221 from rajraku/master
Tracer to depict addition of nodes in binary search tree
上级
20abd870
2a36705f
变更
2
显示空白变更内容
内联
并排
Showing
2 changed file
with
481 addition
and
0 deletion
+481
-0
js/module/tracer/directed_graph_construct.js
js/module/tracer/directed_graph_construct.js
+479
-0
js/module/tracer/index.js
js/module/tracer/index.js
+2
-0
未找到文件。
js/module/tracer/directed_graph_construct.js
0 → 100644
浏览文件 @
c1656493
'
use strict
'
;
const
Tracer
=
require
(
'
./tracer
'
);
const
{
refineByType
}
=
require
(
'
../../tracer_manager/util/index
'
);
class
DirectedGraphConstructTracer
extends
Tracer
{
static
getClassName
()
{
return
'
DirectedGraphConstructTracer
'
;
}
constructor
(
name
,
nodePlacement
=
null
)
{
super
(
name
);
this
.
nodePlacement
=
nodePlacement
;
this
.
nodeCollection
=
[];
if
(
this
.
isNew
)
initView
(
this
);
}
_addRoot
(
root
)
{
this
.
manager
.
pushStep
(
this
.
capsule
,
{
type
:
'
addRoot
'
,
arguments
:
arguments
});
return
this
;
}
_addNode
(
element
,
parentElement
=
null
)
{
this
.
manager
.
pushStep
(
this
.
capsule
,
{
type
:
'
addNode
'
,
arguments
:
arguments
});
return
this
;
}
_findNode
(
val
)
{
var
idToFind
=
this
.
n
(
val
);
var
G
=
this
.
nodeCollection
;
var
result
=
null
;
for
(
let
i
=
0
;
i
<
G
.
length
;
i
++
)
{
if
(
G
[
i
].
id
===
idToFind
)
{
result
=
G
[
i
];
break
;
}
}
return
result
;
}
_visit
(
target
,
source
)
{
this
.
manager
.
pushStep
(
this
.
capsule
,
{
type
:
'
visit
'
,
target
:
target
,
source
:
source
});
return
this
;
}
_leave
(
target
,
source
)
{
this
.
manager
.
pushStep
(
this
.
capsule
,
{
type
:
'
leave
'
,
target
:
target
,
source
:
source
});
return
this
;
}
_setNodePositions
(
positions
)
{
this
.
manager
.
pushStep
(
this
.
capsule
,
{
type
:
'
setNodePositions
'
,
positions
:
positions
});
return
this
;
}
_clearTraversal
()
{
this
.
manager
.
pushStep
(
this
.
capsule
,
{
type
:
'
clear
'
});
return
this
;
}
processStep
(
step
,
options
)
{
switch
(
step
.
type
)
{
case
'
clear
'
:
this
.
clear
.
apply
(
this
);
break
;
case
'
setNodePositions
'
:
$
.
each
(
this
.
graph
.
nodes
(),
(
i
,
node
)
=>
{
if
(
i
>=
step
.
positions
.
length
)
return
false
;
const
position
=
step
.
positions
[
i
];
node
.
x
=
position
.
x
;
node
.
y
=
position
.
y
;
});
break
;
case
'
addRoot
'
:
this
.
addRoot
.
apply
(
this
,
step
.
arguments
);
break
;
case
'
addNode
'
:
this
.
addNode
.
apply
(
this
,
step
.
arguments
);
break
;
case
'
visit
'
:
case
'
leave
'
:
var
visit
=
step
.
type
==
'
visit
'
;
var
nodeObject
=
this
.
_findNode
(
step
.
target
);
nodeObject
.
visited
=
visit
;
nodeObject
.
isNew
=
false
;
var
targetNode
=
this
.
graph
.
nodes
(
this
.
n
(
step
.
target
));
var
color
=
visit
?
this
.
color
.
visited
:
this
.
color
.
left
;
if
(
targetNode
)
{
targetNode
.
color
=
color
;
if
(
step
.
source
!==
undefined
)
{
var
edgeId
=
this
.
e
(
step
.
source
,
step
.
target
);
var
edge
=
this
.
graph
.
edges
(
edgeId
);
edge
.
color
=
color
;
this
.
graph
.
dropEdge
(
edgeId
).
addEdge
(
edge
);
}
}
if
(
this
.
logTracer
)
{
var
source
=
step
.
source
;
if
(
source
===
undefined
)
source
=
''
;
this
.
logTracer
.
print
(
visit
?
source
+
'
->
'
+
step
.
target
:
source
+
'
<-
'
+
step
.
target
);
}
break
;
default
:
super
.
processStep
(
step
,
options
);
}
}
addRoot
(
root
)
{
if
(
this
.
rootObject
)
throw
'
Root for this graph is already added
'
;
this
.
rootObject
=
this
.
createGraphNode
(
root
);
this
.
drawGraph
(
this
.
rootObject
.
level
);
}
addNode
(
node
,
parent
)
{
var
nodeObject
=
this
.
createGraphNode
(
node
,
parent
)
this
.
drawGraph
(
nodeObject
.
level
);
}
createGraphNode
(
node
,
parent
)
{
var
nodeObject
=
this
.
nodeConstruct
(
node
);
var
parentObject
=
this
.
_findNode
(
parent
);
if
(
parentObject
)
{
nodeObject
.
parent
=
parentObject
;
nodeObject
.
level
=
parentObject
.
level
+
1
;
if
(
this
.
nodePlacement
===
null
)
{
parentObject
.
children
.
push
(
nodeObject
);
}
else
if
(
this
.
nodePlacement
===
0
)
{
var
isSpliced
=
false
;
var
insertIndex
=
0
;
if
(
parentObject
.
children
.
length
>
0
)
{
for
(
let
i
=
0
;
i
<
parentObject
.
children
.
length
;
i
++
)
{
var
child
=
parentObject
.
children
[
i
];
if
(
child
.
originalVal
>
node
)
{
isSpliced
=
true
;
break
;
}
insertIndex
++
;
}
}
if
(
isSpliced
)
{
parentObject
.
children
.
splice
(
insertIndex
,
0
,
nodeObject
);
}
else
{
parentObject
.
children
.
push
(
nodeObject
);
}
}
}
this
.
nodeCollection
.
push
(
nodeObject
);
return
nodeObject
;
}
nodeConstruct
(
val
)
{
var
nodeObject
=
{
id
:
this
.
n
(
val
),
originalVal
:
val
,
isNew
:
true
,
visited
:
false
,
children
:
[],
level
:
1
,
parent
:
null
}
return
nodeObject
;
}
drawGraph
(
nodeLevel
)
{
const
nodes
=
[];
const
edges
=
[];
var
tracer
=
this
;
var
arrangeChildNodes
=
function
(
node
,
offsetWidth
)
{
if
(
node
.
children
.
length
>
1
){
var
midPoint
=
Math
.
floor
(
node
.
children
.
length
/
2
);
for
(
let
i
=
0
;
i
<
node
.
children
.
length
;
i
++
)
{
if
(
i
===
midPoint
)
{
offsetWidth
+=
(
node
.
children
.
length
%
2
===
0
?
1
:
0
);
addGraphNode
(
node
,
offsetWidth
);
}
offsetWidth
=
arrangeChildNodes
(
node
.
children
[
i
],
offsetWidth
);
addEdge
(
node
,
node
.
children
[
i
]);
}
}
else
{
if
(
node
.
children
.
length
===
0
)
{
offsetWidth
+=
1
;
}
else
{
offsetWidth
=
arrangeChildNodes
(
node
.
children
[
0
],
offsetWidth
);
addEdge
(
node
,
node
.
children
[
0
]);
}
addGraphNode
(
node
,
offsetWidth
);
}
return
offsetWidth
;
};
var
addGraphNode
=
function
(
node
,
calculatedX
)
{
var
color
=
getColor
(
node
.
isNew
,
node
.
visited
,
tracer
.
color
);
nodes
.
push
({
id
:
node
.
id
,
label
:
''
+
node
.
originalVal
,
x
:
calculatedX
,
y
:
node
.
level
-
1
,
size
:
1
,
color
:
color
,
weight
:
0
});
};
var
addEdge
=
function
(
node
,
childNode
)
{
var
color
=
getColor
(
node
.
visited
&&
childNode
.
isNew
,
node
.
visited
&&
childNode
.
visited
,
tracer
.
color
);
edges
.
push
({
id
:
tracer
.
e
(
node
.
originalVal
,
childNode
.
originalVal
),
source
:
node
.
id
,
target
:
childNode
.
id
,
color
:
color
,
size
:
1
,
weight
:
refineByType
(
childNode
.
originalVal
)
});
};
var
getColor
=
function
(
isNew
,
isVisited
,
colorPalete
)
{
return
isNew
?
colorPalete
.
selected
:
(
isVisited
?
colorPalete
.
visited
:
colorPalete
.
default
);
};
arrangeChildNodes
(
this
.
rootObject
,
0
);
this
.
graph
.
clear
();
this
.
graph
.
read
({
nodes
:
nodes
,
edges
:
edges
});
this
.
s
.
camera
.
goTo
({
x
:
0
,
y
:
nodeLevel
,
angle
:
0
,
ratio
:
1
});
this
.
refresh
();
return
false
;
}
resize
()
{
super
.
resize
();
this
.
s
.
renderers
[
0
].
resize
();
this
.
refresh
();
}
refresh
()
{
super
.
refresh
();
this
.
s
.
refresh
();
}
clear
()
{
super
.
clear
();
this
.
clearGraphColor
();
this
.
refresh
();
}
clearGraphColor
()
{
var
tracer
=
this
;
this
.
nodeCollection
.
forEach
(
function
(
node
){
node
.
visited
=
node
.
isNew
=
false
;
});
this
.
graph
.
nodes
().
forEach
(
function
(
node
)
{
node
.
color
=
tracer
.
color
.
default
;
});
this
.
graph
.
edges
().
forEach
(
function
(
edge
)
{
edge
.
color
=
tracer
.
color
.
default
;
});
}
n
(
v
)
{
return
'
n
'
+
v
;
}
e
(
v1
,
v2
)
{
return
'
e
'
+
v1
+
'
_
'
+
v2
;
}
getColor
(
edge
,
source
,
target
,
settings
)
{
var
color
=
edge
.
color
,
edgeColor
=
settings
(
'
edgeColor
'
),
defaultNodeColor
=
settings
(
'
defaultNodeColor
'
),
defaultEdgeColor
=
settings
(
'
defaultEdgeColor
'
);
if
(
!
color
)
switch
(
edgeColor
)
{
case
'
source
'
:
color
=
source
.
color
||
defaultNodeColor
;
break
;
case
'
target
'
:
color
=
target
.
color
||
defaultNodeColor
;
break
;
default
:
color
=
defaultEdgeColor
;
break
;
}
return
color
;
}
drawLabel
(
node
,
context
,
settings
)
{
var
fontSize
,
prefix
=
settings
(
'
prefix
'
)
||
''
,
size
=
node
[
prefix
+
'
size
'
];
if
(
size
<
settings
(
'
labelThreshold
'
))
return
;
if
(
!
node
.
label
||
typeof
node
.
label
!==
'
string
'
)
return
;
fontSize
=
(
settings
(
'
labelSize
'
)
===
'
fixed
'
)
?
settings
(
'
defaultLabelSize
'
)
:
settings
(
'
labelSizeRatio
'
)
*
size
;
context
.
font
=
(
settings
(
'
fontStyle
'
)
?
settings
(
'
fontStyle
'
)
+
'
'
:
''
)
+
fontSize
+
'
px
'
+
settings
(
'
font
'
);
context
.
fillStyle
=
(
settings
(
'
labelColor
'
)
===
'
node
'
)
?
(
node
.
color
||
settings
(
'
defaultNodeColor
'
))
:
settings
(
'
defaultLabelColor
'
);
context
.
textAlign
=
'
center
'
;
context
.
fillText
(
node
.
label
,
Math
.
round
(
node
[
prefix
+
'
x
'
]),
Math
.
round
(
node
[
prefix
+
'
y
'
]
+
fontSize
/
3
)
);
}
drawArrow
(
edge
,
source
,
target
,
color
,
context
,
settings
)
{
var
prefix
=
settings
(
'
prefix
'
)
||
''
,
size
=
edge
[
prefix
+
'
size
'
]
||
1
,
tSize
=
target
[
prefix
+
'
size
'
],
sX
=
source
[
prefix
+
'
x
'
],
sY
=
source
[
prefix
+
'
y
'
],
tX
=
target
[
prefix
+
'
x
'
],
tY
=
target
[
prefix
+
'
y
'
],
angle
=
Math
.
atan2
(
tY
-
sY
,
tX
-
sX
),
dist
=
3
;
sX
+=
Math
.
sin
(
angle
)
*
dist
;
tX
+=
Math
.
sin
(
angle
)
*
dist
;
sY
+=
-
Math
.
cos
(
angle
)
*
dist
;
tY
+=
-
Math
.
cos
(
angle
)
*
dist
;
var
aSize
=
Math
.
max
(
size
*
2.5
,
settings
(
'
minArrowSize
'
)),
d
=
Math
.
sqrt
(
Math
.
pow
(
tX
-
sX
,
2
)
+
Math
.
pow
(
tY
-
sY
,
2
)),
aX
=
sX
+
(
tX
-
sX
)
*
(
d
-
aSize
-
tSize
)
/
d
,
aY
=
sY
+
(
tY
-
sY
)
*
(
d
-
aSize
-
tSize
)
/
d
,
vX
=
(
tX
-
sX
)
*
aSize
/
d
,
vY
=
(
tY
-
sY
)
*
aSize
/
d
;
context
.
strokeStyle
=
color
;
context
.
lineWidth
=
size
;
context
.
beginPath
();
context
.
moveTo
(
sX
,
sY
);
context
.
lineTo
(
aX
,
aY
);
context
.
stroke
();
context
.
fillStyle
=
color
;
context
.
beginPath
();
context
.
moveTo
(
aX
+
vX
,
aY
+
vY
);
context
.
lineTo
(
aX
+
vY
*
0.6
,
aY
-
vX
*
0.6
);
context
.
lineTo
(
aX
-
vY
*
0.6
,
aY
+
vX
*
0.6
);
context
.
lineTo
(
aX
+
vX
,
aY
+
vY
);
context
.
closePath
();
context
.
fill
();
}
drawOnHover
(
node
,
context
,
settings
,
next
)
{
var
tracer
=
this
;
context
.
setLineDash
([
5
,
5
]);
var
nodeIdx
=
node
.
id
.
substring
(
1
);
this
.
graph
.
edges
().
forEach
(
function
(
edge
)
{
var
ends
=
edge
.
id
.
substring
(
1
).
split
(
"
_
"
);
if
(
ends
[
0
]
==
nodeIdx
)
{
var
color
=
'
#0ff
'
;
var
source
=
node
;
var
target
=
tracer
.
graph
.
nodes
(
'
n
'
+
ends
[
1
]);
tracer
.
drawArrow
(
edge
,
source
,
target
,
color
,
context
,
settings
);
if
(
next
)
next
(
edge
,
source
,
target
,
color
,
context
,
settings
);
}
else
if
(
ends
[
1
]
==
nodeIdx
)
{
var
color
=
'
#ff0
'
;
var
source
=
tracer
.
graph
.
nodes
(
'
n
'
+
ends
[
0
]);
var
target
=
node
;
tracer
.
drawArrow
(
edge
,
source
,
target
,
color
,
context
,
settings
);
if
(
next
)
next
(
edge
,
source
,
target
,
color
,
context
,
settings
);
}
});
}
}
const
initView
=
(
tracer
)
=>
{
tracer
.
s
=
tracer
.
capsule
.
s
=
new
sigma
({
renderer
:
{
container
:
tracer
.
$container
[
0
],
type
:
'
canvas
'
},
settings
:
{
minArrowSize
:
8
,
defaultEdgeType
:
'
arrow
'
,
maxEdgeSize
:
2.5
,
labelThreshold
:
4
,
font
:
'
Roboto
'
,
defaultLabelColor
:
'
#fff
'
,
zoomMin
:
0.6
,
zoomMax
:
1.2
,
skipErrors
:
true
,
minNodeSize
:
.
5
,
maxNodeSize
:
12
,
labelSize
:
'
proportional
'
,
labelSizeRatio
:
1.3
,
funcLabelsDef
(
node
,
context
,
settings
)
{
tracer
.
drawLabel
(
node
,
context
,
settings
);
},
funcHoversDef
(
node
,
context
,
settings
,
next
)
{
tracer
.
drawOnHover
(
node
,
context
,
settings
,
next
);
},
funcEdgesArrow
(
edge
,
source
,
target
,
context
,
settings
)
{
var
color
=
tracer
.
getColor
(
edge
,
source
,
target
,
settings
);
tracer
.
drawArrow
(
edge
,
source
,
target
,
color
,
context
,
settings
);
}
}
});
sigma
.
plugins
.
dragNodes
(
tracer
.
s
,
tracer
.
s
.
renderers
[
0
]);
tracer
.
graph
=
tracer
.
capsule
.
graph
=
tracer
.
s
.
graph
;
};
sigma
.
canvas
.
labels
.
def
=
function
(
node
,
context
,
settings
)
{
var
func
=
settings
(
'
funcLabelsDef
'
);
if
(
func
)
{
func
(
node
,
context
,
settings
);
}
};
sigma
.
canvas
.
hovers
.
def
=
function
(
node
,
context
,
settings
)
{
var
func
=
settings
(
'
funcHoversDef
'
);
if
(
func
)
{
func
(
node
,
context
,
settings
);
}
};
sigma
.
canvas
.
edges
.
def
=
function
(
edge
,
source
,
target
,
context
,
settings
)
{
var
func
=
settings
(
'
funcEdgesDef
'
);
if
(
func
)
{
func
(
edge
,
source
,
target
,
context
,
settings
);
}
};
sigma
.
canvas
.
edges
.
arrow
=
function
(
edge
,
source
,
target
,
context
,
settings
)
{
var
func
=
settings
(
'
funcEdgesArrow
'
);
if
(
func
)
{
func
(
edge
,
source
,
target
,
context
,
settings
);
}
};
module
.
exports
=
DirectedGraphConstructTracer
;
js/module/tracer/index.js
浏览文件 @
c1656493
...
...
@@ -7,6 +7,7 @@ const Array2DTracer = require('./array2d');
const
ChartTracer
=
require
(
'
./chart
'
);
const
CoordinateSystemTracer
=
require
(
'
./coordinate_system
'
);
const
DirectedGraphTracer
=
require
(
'
./directed_graph
'
);
const
DirectedGraphConstructTracer
=
require
(
'
./directed_graph_construct
'
);
const
UndirectedGraphTracer
=
require
(
'
./undirected_graph
'
);
const
WeightedDirectedGraphTracer
=
require
(
'
./weighted_directed_graph
'
);
const
WeightedUndirectedGraphTracer
=
require
(
'
./weighted_undirected_graph
'
);
...
...
@@ -19,6 +20,7 @@ module.exports = {
ChartTracer
,
CoordinateSystemTracer
,
DirectedGraphTracer
,
DirectedGraphConstructTracer
,
UndirectedGraphTracer
,
WeightedDirectedGraphTracer
,
WeightedUndirectedGraphTracer
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录