mkdocs-nodegraph 0.4.1__tar.gz → 0.5.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/PKG-INFO +28 -4
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/README.md +15 -2
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/generate_graph.py +43 -5
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/graph_opts.json +1 -1
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/mdparser.py +26 -9
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/templates/template.html +403 -196
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/plugin.py +1 -0
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph.egg-info/PKG-INFO +28 -4
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/setup.py +1 -1
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/__init__.py +0 -0
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/__init__.py +0 -0
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/mdfile.py +0 -0
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/pyvis_opts.js +0 -0
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/templates/__init__.py +0 -0
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph.egg-info/SOURCES.txt +0 -0
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph.egg-info/dependency_links.txt +0 -0
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph.egg-info/entry_points.txt +0 -0
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph.egg-info/requires.txt +0 -0
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph.egg-info/top_level.txt +0 -0
- {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: mkdocs-nodegraph
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Node Graph plugin for Mkdocs Material
|
|
5
5
|
Home-page: https://yonge123.github.io/mkdocs-nodegraph/nodegraph.html
|
|
6
6
|
Author: JeongYong Hwang
|
|
@@ -18,6 +18,17 @@ Requires-Dist: pyembed-markdown>=1.1.0
|
|
|
18
18
|
Requires-Dist: mkdocs-glightbox>=0.4.0
|
|
19
19
|
Requires-Dist: pyvis>=0.3.0
|
|
20
20
|
Requires-Dist: PyYAML>=6.0.2
|
|
21
|
+
Dynamic: author
|
|
22
|
+
Dynamic: author-email
|
|
23
|
+
Dynamic: description
|
|
24
|
+
Dynamic: description-content-type
|
|
25
|
+
Dynamic: home-page
|
|
26
|
+
Dynamic: keywords
|
|
27
|
+
Dynamic: license
|
|
28
|
+
Dynamic: project-url
|
|
29
|
+
Dynamic: requires-dist
|
|
30
|
+
Dynamic: requires-python
|
|
31
|
+
Dynamic: summary
|
|
21
32
|
|
|
22
33
|
# mkdocs-nodegraph
|
|
23
34
|
|
|
@@ -35,11 +46,11 @@ It allows you to create interactive visualizations of your documentation structu
|
|
|
35
46
|
|
|
36
47
|
<p align="center">
|
|
37
48
|
<a>
|
|
38
|
-
<img alt="
|
|
49
|
+
<img alt="example_image_002.png" src="https://github.com/yonge123/mkdocs-nodegraph/blob/master/sources/example_image_002.png?raw=true" data-hpc="true" class="Box-sc-g0xbh4-0 fzFXnm">
|
|
39
50
|
</a>
|
|
40
51
|
|
|
41
52
|
|
|
42
|
-
<!--  -->
|
|
43
54
|
|
|
44
55
|
|
|
45
56
|
<br>
|
|
@@ -106,6 +117,19 @@ mdfile_site -> A website URL that opens on click while holding the Alt key
|
|
|
106
117
|
|
|
107
118
|
<br>
|
|
108
119
|
|
|
120
|
+
## Click Node
|
|
121
|
+
|
|
122
|
+
`LMB` -> Open Node Page
|
|
123
|
+
|
|
124
|
+
`Ctrl + LMB` -> Open Node Page in a New Tab
|
|
125
|
+
|
|
126
|
+
`Alt + LMB` -> Open the mdfile_site Page from the metadata
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
<br>
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
109
133
|
## mkdocs.yml Configuration
|
|
110
134
|
|
|
111
135
|
|
|
@@ -14,11 +14,11 @@ It allows you to create interactive visualizations of your documentation structu
|
|
|
14
14
|
|
|
15
15
|
<p align="center">
|
|
16
16
|
<a>
|
|
17
|
-
<img alt="
|
|
17
|
+
<img alt="example_image_002.png" src="https://github.com/yonge123/mkdocs-nodegraph/blob/master/sources/example_image_002.png?raw=true" data-hpc="true" class="Box-sc-g0xbh4-0 fzFXnm">
|
|
18
18
|
</a>
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
<!--  -->
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
<br>
|
|
@@ -85,6 +85,19 @@ mdfile_site -> A website URL that opens on click while holding the Alt key
|
|
|
85
85
|
|
|
86
86
|
<br>
|
|
87
87
|
|
|
88
|
+
## Click Node
|
|
89
|
+
|
|
90
|
+
`LMB` -> Open Node Page
|
|
91
|
+
|
|
92
|
+
`Ctrl + LMB` -> Open Node Page in a New Tab
|
|
93
|
+
|
|
94
|
+
`Alt + LMB` -> Open the mdfile_site Page from the metadata
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
<br>
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
88
101
|
## mkdocs.yml Configuration
|
|
89
102
|
|
|
90
103
|
|
{mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/generate_graph.py
RENAMED
|
@@ -131,7 +131,7 @@ class GraphBuilder():
|
|
|
131
131
|
|
|
132
132
|
# self.net.show_buttons(filter_=['physics', 'nodes', 'links'])
|
|
133
133
|
# build graph from parsed markdown pages
|
|
134
|
-
def build(self, mdfiles):
|
|
134
|
+
def build(self, mdfiles, tags=None):
|
|
135
135
|
nx_graph = nx.Graph()
|
|
136
136
|
edget_info_dic = dict()
|
|
137
137
|
color_list = copy.deepcopy(beautifulcolors)
|
|
@@ -195,6 +195,7 @@ class GraphBuilder():
|
|
|
195
195
|
label=mdfile.title,
|
|
196
196
|
url=html,
|
|
197
197
|
url2=alt_click_url,
|
|
198
|
+
nodetype="filenode",
|
|
198
199
|
size=size,
|
|
199
200
|
shape=shape,
|
|
200
201
|
image=icon,
|
|
@@ -212,6 +213,40 @@ class GraphBuilder():
|
|
|
212
213
|
edge_len = max_link * 45 + ( idx * 35)
|
|
213
214
|
nx_graph.add_edge(mdfile.uid, link_uid, length=edge_len)
|
|
214
215
|
|
|
216
|
+
if tags:
|
|
217
|
+
for idx, tag in enumerate(tags):
|
|
218
|
+
tag_name = tag["name"]
|
|
219
|
+
tag_uid = tag["uid"]
|
|
220
|
+
link_uids = tag["link_uids"]
|
|
221
|
+
count_links = len(link_uids)
|
|
222
|
+
icon = ""
|
|
223
|
+
shape="dot"
|
|
224
|
+
alt_click_url = ""
|
|
225
|
+
tag_color = "#FFD415"
|
|
226
|
+
size = 50 + (count_links * 4)
|
|
227
|
+
if size > 120:
|
|
228
|
+
size = 120
|
|
229
|
+
nx_graph.add_node(tag_uid,
|
|
230
|
+
label=tag_name,
|
|
231
|
+
url="",
|
|
232
|
+
url2=alt_click_url,
|
|
233
|
+
nodetype="tagnode",
|
|
234
|
+
size=size,
|
|
235
|
+
shape=shape,
|
|
236
|
+
image=icon,
|
|
237
|
+
color=tag_color,
|
|
238
|
+
opacity=1,
|
|
239
|
+
borderWidth=2,
|
|
240
|
+
)
|
|
241
|
+
|
|
242
|
+
edge_len = count_links * 45 + ( idx * 35)
|
|
243
|
+
if link_uids:
|
|
244
|
+
for link_uid in link_uids:
|
|
245
|
+
nx_graph.add_edge(tag_uid,
|
|
246
|
+
link_uid,
|
|
247
|
+
length=edge_len
|
|
248
|
+
)
|
|
249
|
+
|
|
215
250
|
# self.net.from_nx(nx_graph)
|
|
216
251
|
self.net.from_nx(nx_graph,
|
|
217
252
|
default_node_size=50,
|
|
@@ -247,7 +282,8 @@ def load_pyvis_opts(file_path):
|
|
|
247
282
|
return fout.read()
|
|
248
283
|
|
|
249
284
|
|
|
250
|
-
def build_graph(docs_dir, site_dir, output_file, pyvis_opts_file,
|
|
285
|
+
def build_graph(docs_dir, site_dir, output_file, pyvis_opts_file,
|
|
286
|
+
graph_opts_file, config_graphfile):
|
|
251
287
|
if not os.path.isfile(pyvis_opts_file):
|
|
252
288
|
raise IOError(f'Failed to find file -> "{pyvis_opts_file}"')
|
|
253
289
|
|
|
@@ -258,14 +294,16 @@ def build_graph(docs_dir, site_dir, output_file, pyvis_opts_file, graph_opts_fil
|
|
|
258
294
|
os.makedirs(outputDir, exist_ok=True)
|
|
259
295
|
|
|
260
296
|
parser = MdParser(docs_dir)
|
|
261
|
-
|
|
262
|
-
|
|
297
|
+
parser.parse()
|
|
298
|
+
mdfiles = parser.mdfiles
|
|
299
|
+
tags = parser.tags
|
|
300
|
+
|
|
263
301
|
graph_config = read_config(graph_opts_file)
|
|
264
302
|
graph_opts = load_graph_opts(graph_config)
|
|
265
303
|
pyvis_opts = load_pyvis_opts(pyvis_opts_file)
|
|
266
304
|
|
|
267
305
|
builder = GraphBuilder(pyvis_opts, graph_opts, output_file, config_graphfile, docs_dir, site_dir)
|
|
268
|
-
builder.build(mdfiles)
|
|
306
|
+
builder.build(mdfiles, tags)
|
|
269
307
|
|
|
270
308
|
|
|
271
309
|
def rebuild_graph_html(index_path, graph_path, output_path=None):
|
|
@@ -52,6 +52,7 @@ class MdParser():
|
|
|
52
52
|
|
|
53
53
|
def __init__(self, target_dir):
|
|
54
54
|
self.mdfiles = []
|
|
55
|
+
self.tags = []
|
|
55
56
|
self.target_dir = target_dir
|
|
56
57
|
|
|
57
58
|
def parse_md(self, file_name):
|
|
@@ -61,8 +62,9 @@ class MdParser():
|
|
|
61
62
|
title = ""
|
|
62
63
|
metadata = ""
|
|
63
64
|
return MdFile(file_name, base_name, title, links, link_uids, metadata)
|
|
64
|
-
|
|
65
|
+
|
|
65
66
|
def parse(self):
|
|
67
|
+
tags_dic = dict()
|
|
66
68
|
uid = 1
|
|
67
69
|
for subdir, dirs, files in os.walk(self.target_dir):
|
|
68
70
|
for f in files:
|
|
@@ -71,14 +73,20 @@ class MdParser():
|
|
|
71
73
|
|
|
72
74
|
if not any(x for x in self.mdfiles if x.file_path == path):
|
|
73
75
|
md = self.parse_md(path)
|
|
76
|
+
md.uid = uid
|
|
77
|
+
self.mdfiles.append(md)
|
|
78
|
+
|
|
74
79
|
parseMedata = getMetadata(path)
|
|
75
80
|
if parseMedata:
|
|
76
81
|
metadata = yaml.safe_load(parseMedata)
|
|
77
82
|
md.metadata = metadata
|
|
78
83
|
|
|
79
|
-
|
|
84
|
+
if "tags" in metadata:
|
|
85
|
+
for tag in metadata["tags"]:
|
|
86
|
+
if tag not in tags_dic:
|
|
87
|
+
tags_dic[tag] = set()
|
|
88
|
+
tags_dic[tag].add(uid)
|
|
80
89
|
uid += 1
|
|
81
|
-
self.mdfiles.append(md)
|
|
82
90
|
|
|
83
91
|
for mdfile in self.mdfiles:
|
|
84
92
|
uids = set()
|
|
@@ -86,10 +94,19 @@ class MdParser():
|
|
|
86
94
|
for link in mdfile.mdlinks:
|
|
87
95
|
link_basename = os.path.basename(link)
|
|
88
96
|
link_new = link.replace("../", "/").replace("./", "").replace("/", "").replace(".", "")
|
|
89
|
-
|
|
90
|
-
if len(
|
|
91
|
-
uids.add(
|
|
92
|
-
|
|
97
|
+
getmdfiles = list(filter(lambda x: (x.file_path.replace("\\", "").replace("../", "/").replace("./", "").replace("/", "").replace(".", "").endswith(link_new) and os.path.basename(x.file_path) == link_basename), self.mdfiles))
|
|
98
|
+
if len(getmdfiles) > 0:
|
|
99
|
+
uids.add(getmdfiles[0].uid)
|
|
100
|
+
|
|
93
101
|
mdfile.link_uids = list(uids)
|
|
94
|
-
|
|
95
|
-
|
|
102
|
+
|
|
103
|
+
if tags_dic:
|
|
104
|
+
for tag, link_uids in tags_dic.items():
|
|
105
|
+
self.tags.append({
|
|
106
|
+
'name': tag,
|
|
107
|
+
'uid': uid,
|
|
108
|
+
'link_uids': link_uids
|
|
109
|
+
})
|
|
110
|
+
uid += 1
|
|
111
|
+
|
|
112
|
+
return self.mdfiles, self.tags
|
{mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/templates/template.html
RENAMED
|
@@ -3,27 +3,25 @@
|
|
|
3
3
|
<meta charset="utf-8">
|
|
4
4
|
{% if cdn_resources=="local" %}
|
|
5
5
|
|
|
6
|
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vis-network/
|
|
7
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis-network/
|
|
6
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vis-network/10.0.2/dist/dist/vis-network.min.css">
|
|
7
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis-network/10.0.2/dist/vis-network.min.js"></script>
|
|
8
8
|
{% if select_menu or filter_menu %}
|
|
9
9
|
<link href="lib/tom-select/tom-select.css" rel="stylesheet">
|
|
10
10
|
<script src="lib/tom-select/tom-select.complete.min.js"></script>
|
|
11
11
|
{% endif %}
|
|
12
12
|
{% elif cdn_resources=="in_line" %}
|
|
13
|
-
<style>{% include '
|
|
14
|
-
<script>{% include '
|
|
13
|
+
<style>{% include 'libs/vis-network/10.0.2/dist/dist/vis-network.min.css' %}</style>
|
|
14
|
+
<script>{% include 'libs/vis-network/10.0.2/dist/vis-network.min.js' %}</script>
|
|
15
15
|
{% if select_menu or filter_menu %}
|
|
16
16
|
<style>{% include 'lib/tom-select/tom-select.css' %}</style>
|
|
17
17
|
<script>{% include 'lib/tom-select/tom-select.complete.min.js' %}</script>
|
|
18
18
|
{% endif %}
|
|
19
19
|
{% elif cdn_resources=="remote" %}
|
|
20
|
-
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vis-network/
|
|
21
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis-network/
|
|
22
|
-
|
|
23
|
-
{# <
|
|
24
|
-
{#
|
|
25
|
-
{# crossorigin="anonymous"#}
|
|
26
|
-
{# referrerpolicy="no-referrer"></script>#}
|
|
20
|
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vis-network/10.0.2/dist/dist/vis-network.min.css">
|
|
21
|
+
<script src="https://cdnjs.cloudflare.com/ajax/libs/vis-network/10.0.2/dist/vis-network.min.js"></script>
|
|
22
|
+
|
|
23
|
+
{# <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vis-network/10.0.2/dist/dist/vis-network.min.css" />#}
|
|
24
|
+
{# <script src="https://cdnjs.cloudflare.com/ajax/libs/vis-network/10.0.2/dist/vis-network.min.js" />#}
|
|
27
25
|
{% if select_menu or filter_menu %}
|
|
28
26
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/tom-select/2.0.0-rc.4/css/tom-select.min.css" integrity="sha512-43fHB3GLgZfz8QXl1RPQ8O66oIgv3po9cJ5erMt1c4QISq9dYb195T3vr5ImnJPXuVroKcGBPXBFKETW8jrPNQ==" crossorigin="anonymous" referrerpolicy="no-referrer" />
|
|
29
27
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/tom-select/2.0.0-rc.4/js/tom-select.complete.js" integrity="sha512-jeF9CfnvzDiw9G9xiksVjxR2lib44Gnovvkv+3CgCG6NXCD4gqlA5nDAVW5WjpA+i+/zKsUWV5xNEbW1X/HH0Q==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
|
|
@@ -66,7 +64,7 @@
|
|
|
66
64
|
margin:auto auto auto auto;
|
|
67
65
|
border-radius:11px;
|
|
68
66
|
border:2px solid rgba(30,30,30,0.05);
|
|
69
|
-
background: rgb(0, 173, 246);
|
|
67
|
+
background: rgb(0, 173, 246);
|
|
70
68
|
box-shadow: 2px 0px 4px rgba(0,0,0,0.4);
|
|
71
69
|
}
|
|
72
70
|
|
|
@@ -121,7 +119,7 @@
|
|
|
121
119
|
{% endif %}
|
|
122
120
|
|
|
123
121
|
{% if tooltip_link %}
|
|
124
|
-
|
|
122
|
+
|
|
125
123
|
div.popup {
|
|
126
124
|
position:absolute;
|
|
127
125
|
top:0px;
|
|
@@ -135,7 +133,6 @@
|
|
|
135
133
|
box-shadow: 3px 3px 10px rgba(0, 0, 0, 0.2);
|
|
136
134
|
}
|
|
137
135
|
|
|
138
|
-
/* hide the original tooltip */
|
|
139
136
|
.vis-tooltip {
|
|
140
137
|
display:none;
|
|
141
138
|
}
|
|
@@ -152,9 +149,8 @@
|
|
|
152
149
|
min-height: 100vh;
|
|
153
150
|
}
|
|
154
151
|
|
|
155
|
-
|
|
156
152
|
.left-panel {
|
|
157
|
-
background: #
|
|
153
|
+
background: #4454704f;
|
|
158
154
|
width: 270px;
|
|
159
155
|
position: absolute;
|
|
160
156
|
z-index: 2;
|
|
@@ -198,154 +194,250 @@
|
|
|
198
194
|
}
|
|
199
195
|
|
|
200
196
|
.search-container {
|
|
201
|
-
margin-bottom:
|
|
197
|
+
margin-bottom: 8px;
|
|
202
198
|
display: flex;
|
|
203
199
|
align-items: center;
|
|
204
|
-
gap:
|
|
200
|
+
gap: 5px;
|
|
205
201
|
}
|
|
206
202
|
|
|
207
203
|
.search-input {
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
border
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
height: 30px;
|
|
220
|
-
display: flex;
|
|
221
|
-
background-color: hsl(0, 0%, 65%);
|
|
222
|
-
color: rgb(255, 255, 255);
|
|
223
|
-
border: 1px solid hsl(0, 0%, 65%);
|
|
224
|
-
border-radius: 4px;
|
|
225
|
-
font-size: 16px;
|
|
226
|
-
cursor: pointer;
|
|
227
|
-
display: inline-flex;
|
|
228
|
-
align-items: center;
|
|
229
|
-
justify-content: center;
|
|
230
|
-
}
|
|
231
|
-
.up-btn:hover {
|
|
232
|
-
background-color:hsl(0, 0%, 71%);
|
|
204
|
+
flex: 1;
|
|
205
|
+
min-width: 0;
|
|
206
|
+
padding: 7px 10px;
|
|
207
|
+
background: var(--surface);
|
|
208
|
+
color: var(--text);
|
|
209
|
+
border: 1px solid var(--border);
|
|
210
|
+
border-radius: 6px;
|
|
211
|
+
font-size: 13px;
|
|
212
|
+
font-family: inherit;
|
|
213
|
+
outline: none;
|
|
214
|
+
transition: border-color 0.2s, box-shadow 0.2s;
|
|
233
215
|
}
|
|
234
|
-
.
|
|
235
|
-
|
|
216
|
+
.search-input::placeholder { color: var(--muted); }
|
|
217
|
+
.search-input:focus {
|
|
218
|
+
border-color: var(--accent);
|
|
219
|
+
box-shadow: 0 0 0 2px rgba(0,229,255,0.15);
|
|
236
220
|
}
|
|
237
|
-
|
|
221
|
+
|
|
222
|
+
.up-btn,
|
|
238
223
|
.down-btn {
|
|
239
224
|
width: 30px;
|
|
240
225
|
height: 30px;
|
|
241
|
-
|
|
242
|
-
color: rgb(255, 255, 255);
|
|
243
|
-
border: 1px solid hsl(0, 0%, 65%);
|
|
244
|
-
border-radius: 4px;
|
|
245
|
-
font-size: 16px;
|
|
246
|
-
box-sizing: border-box;
|
|
247
|
-
cursor: pointer;
|
|
226
|
+
flex-shrink: 0;
|
|
248
227
|
display: inline-flex;
|
|
249
228
|
align-items: center;
|
|
250
229
|
justify-content: center;
|
|
230
|
+
background: var(--surface);
|
|
231
|
+
color: var(--text);
|
|
232
|
+
border: 1px solid var(--border);
|
|
233
|
+
border-radius: 6px;
|
|
234
|
+
cursor: pointer;
|
|
235
|
+
transition: border-color 0.2s, background 0.2s, box-shadow 0.2s;
|
|
251
236
|
}
|
|
237
|
+
.up-btn:hover,
|
|
252
238
|
.down-btn:hover {
|
|
253
|
-
|
|
239
|
+
border-color: var(--accent);
|
|
240
|
+
background: rgba(0,229,255,0.08);
|
|
241
|
+
box-shadow: 0 0 6px rgba(0,229,255,0.2);
|
|
254
242
|
}
|
|
243
|
+
.up-btn:active,
|
|
255
244
|
.down-btn:active {
|
|
256
|
-
background
|
|
245
|
+
background: rgba(0,229,255,0.18);
|
|
257
246
|
}
|
|
258
247
|
|
|
259
|
-
.
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
border-radius: 4px;
|
|
248
|
+
.save-btn,
|
|
249
|
+
.home-btn,
|
|
250
|
+
.reset-btn {
|
|
251
|
+
display: flex;
|
|
252
|
+
align-items: center;
|
|
253
|
+
justify-content: center;
|
|
254
|
+
gap: 6px;
|
|
267
255
|
width: 100%;
|
|
256
|
+
padding: 8px 10px;
|
|
257
|
+
margin-bottom: 5px;
|
|
258
|
+
font-size: 12px;
|
|
259
|
+
font-family: inherit;
|
|
260
|
+
font-weight: 600;
|
|
261
|
+
letter-spacing: 0.05em;
|
|
262
|
+
text-transform: uppercase;
|
|
263
|
+
border: 1px solid transparent;
|
|
264
|
+
border-radius: 6px;
|
|
268
265
|
cursor: pointer;
|
|
266
|
+
transition: background 0.2s, border-color 0.2s, box-shadow 0.2s, transform 0.1s;
|
|
269
267
|
}
|
|
270
|
-
|
|
271
|
-
.
|
|
272
|
-
|
|
273
|
-
}
|
|
268
|
+
.save-btn:active,
|
|
269
|
+
.home-btn:active,
|
|
270
|
+
.reset-btn:active { transform: scale(0.97); }
|
|
274
271
|
|
|
275
272
|
.save-btn {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
background-color: hsl(194, 42%, 45%);
|
|
280
|
-
color: white;
|
|
281
|
-
border: none;
|
|
282
|
-
border-radius: 4px;
|
|
283
|
-
width: 100%;
|
|
284
|
-
cursor: pointer;
|
|
273
|
+
background: rgba(0,229,255,0.12);
|
|
274
|
+
color: var(--accent);
|
|
275
|
+
border-color: rgba(0,229,255,0.35);
|
|
285
276
|
}
|
|
286
|
-
|
|
287
277
|
.save-btn:hover {
|
|
288
|
-
background
|
|
278
|
+
background: rgba(0,229,255,0.22);
|
|
279
|
+
border-color: var(--accent);
|
|
280
|
+
box-shadow: 0 0 10px rgba(0,229,255,0.25);
|
|
289
281
|
}
|
|
290
282
|
|
|
291
|
-
.
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
border:
|
|
298
|
-
|
|
299
|
-
border-radius: 4px;
|
|
300
|
-
cursor: pointer;
|
|
283
|
+
.home-btn {
|
|
284
|
+
background: var(--surface);
|
|
285
|
+
color: var(--text);
|
|
286
|
+
border-color: var(--border);
|
|
287
|
+
}
|
|
288
|
+
.home-btn:hover {
|
|
289
|
+
border-color: var(--accent);
|
|
290
|
+
background: rgba(0,229,255,0.06);
|
|
301
291
|
}
|
|
302
292
|
|
|
303
|
-
.reset-btn
|
|
304
|
-
background
|
|
293
|
+
.reset-btn {
|
|
294
|
+
background: rgba(255,77,109,0.08);
|
|
295
|
+
color: #ff7a94;
|
|
296
|
+
border-color: rgba(255,77,109,0.3);
|
|
305
297
|
}
|
|
306
|
-
.
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
background-color: hsl(0, 0%, 65%);
|
|
311
|
-
color: white;
|
|
312
|
-
border: none;
|
|
313
|
-
border-radius: 4px;
|
|
314
|
-
width: 100%;
|
|
315
|
-
cursor: pointer;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
.home-btn:hover {
|
|
319
|
-
background-color: hsl(0, 0%, 71%);
|
|
298
|
+
.reset-btn:hover {
|
|
299
|
+
background: rgba(255,77,109,0.18);
|
|
300
|
+
border-color: var(--accent2);
|
|
301
|
+
box-shadow: 0 0 10px rgba(255,77,109,0.2);
|
|
320
302
|
}
|
|
321
303
|
|
|
322
304
|
input {
|
|
323
|
-
accent-color:
|
|
305
|
+
accent-color: var(--accent);
|
|
324
306
|
}
|
|
325
307
|
|
|
326
308
|
.control-label {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
309
|
+
display: flex;
|
|
310
|
+
align-items: center;
|
|
311
|
+
font-size: 12px;
|
|
312
|
+
font-weight: 600;
|
|
313
|
+
letter-spacing: 0.06em;
|
|
314
|
+
color: var(--text);
|
|
315
|
+
margin-bottom: 0px;
|
|
316
|
+
margin-top: 16px;
|
|
317
|
+
width: 100%;
|
|
336
318
|
}
|
|
337
319
|
|
|
338
320
|
input[type="range"] {
|
|
339
|
-
|
|
340
|
-
|
|
321
|
+
-webkit-appearance: none;
|
|
322
|
+
appearance: none;
|
|
341
323
|
width: 100%;
|
|
342
|
-
height:
|
|
343
|
-
background:
|
|
324
|
+
height: 14px;
|
|
325
|
+
background: transparent;
|
|
326
|
+
border-radius: 4px;
|
|
344
327
|
outline: none;
|
|
345
|
-
|
|
346
|
-
|
|
328
|
+
cursor: pointer;
|
|
329
|
+
opacity: 0.85;
|
|
330
|
+
}
|
|
331
|
+
input[type="range"]:hover { opacity: 1; }
|
|
332
|
+
|
|
333
|
+
input[type="range"]::-webkit-slider-runnable-track {
|
|
334
|
+
background: linear-gradient(to right, rgba(0,229,255,0.4), var(--border));
|
|
335
|
+
border-radius: 4px;
|
|
336
|
+
height: 4px;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
input[type="range"]::-moz-range-track {
|
|
340
|
+
background: linear-gradient(to right, rgba(0,229,255,0.4), var(--border));
|
|
341
|
+
border-radius: 4px;
|
|
342
|
+
height: 4px;
|
|
343
|
+
}
|
|
344
|
+
input[type="range"]::-moz-range-thumb:hover {
|
|
345
|
+
transform: scale(1.25);
|
|
346
|
+
box-shadow: 0 0 10px rgba(0,229,255,0.75);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
input[type="range"]::-webkit-slider-thumb {
|
|
350
|
+
-webkit-appearance: none;
|
|
351
|
+
appearance: none;
|
|
352
|
+
width: 14px;
|
|
353
|
+
height: 14px;
|
|
354
|
+
border-radius: 50%;
|
|
355
|
+
background: var(--accent);
|
|
356
|
+
border: 0px solid var(--bg);
|
|
357
|
+
box-shadow: 0 0 6px rgba(0,229,255,0.5);
|
|
358
|
+
margin-top: -5px; /* Centers thumb on track in Webkit */
|
|
359
|
+
}
|
|
360
|
+
input[type="range"]::-webkit-slider-thumb:hover {
|
|
361
|
+
transform: scale(1.25);
|
|
362
|
+
box-shadow: 0 0 10px rgba(0,229,255,0.75);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
input[type="range"]::-moz-range-thumb {
|
|
366
|
+
width: 14px;
|
|
367
|
+
height: 14px;
|
|
368
|
+
border-radius: 50%;
|
|
369
|
+
background: var(--accent);
|
|
370
|
+
border: 0px solid var(--bg); /* Ensure border doesn't squash the circle */
|
|
371
|
+
box-shadow: 0 0 6px rgba(0,229,255,0.5);
|
|
372
|
+
box-sizing: border-box; /* Force border to stay inside the 14px */
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
:root {
|
|
376
|
+
--bg: #0d0f14;
|
|
377
|
+
--surface: #151820;
|
|
378
|
+
--border: #252a35;
|
|
379
|
+
--accent: #00e5ff;
|
|
380
|
+
--accent2: #ff4d6d;
|
|
381
|
+
--accent3: #b3ff5c;
|
|
382
|
+
--text: #c8d0e0;
|
|
383
|
+
--muted: #555f75;
|
|
384
|
+
}
|
|
385
|
+
.toggle-group {
|
|
386
|
+
display: flex;
|
|
387
|
+
flex-direction: column;
|
|
388
|
+
gap: 8px;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
.toggle-item {
|
|
392
|
+
display: flex;
|
|
393
|
+
align-items: center;
|
|
394
|
+
gap: 12px;
|
|
395
|
+
padding: 10px 12px;
|
|
396
|
+
border: 1px solid var(--border);
|
|
397
|
+
border-radius: 4px;
|
|
398
|
+
cursor: pointer;
|
|
399
|
+
transition: border-color 0.15s, background 0.15s;
|
|
400
|
+
user-select: none;
|
|
347
401
|
}
|
|
348
402
|
|
|
403
|
+
.toggle-item:hover { border-color: var(--accent); background: rgba(0,229,255,0.04); }
|
|
404
|
+
|
|
405
|
+
.toggle-item input[type="checkbox"] { display: none; }
|
|
406
|
+
|
|
407
|
+
.toggle-dot {
|
|
408
|
+
width: 32px;
|
|
409
|
+
height: 18px;
|
|
410
|
+
border-radius: 9px;
|
|
411
|
+
background: var(--border);
|
|
412
|
+
position: relative;
|
|
413
|
+
flex-shrink: 0;
|
|
414
|
+
transition: background 0.2s;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
.toggle-dot::after {
|
|
418
|
+
content: '';
|
|
419
|
+
position: absolute;
|
|
420
|
+
width: 12px;
|
|
421
|
+
height: 12px;
|
|
422
|
+
border-radius: 50%;
|
|
423
|
+
background: var(--muted);
|
|
424
|
+
top: 3px;
|
|
425
|
+
left: 3px;
|
|
426
|
+
transition: transform 0.2s, background 0.2s;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
input[type="checkbox"]:checked ~ .toggle-dot { background: rgba(0,229,255,0.2); }
|
|
430
|
+
input[type="checkbox"]:checked ~ .toggle-dot::after {
|
|
431
|
+
transform: translateX(14px);
|
|
432
|
+
background: var(--accent);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
.toggle-label {
|
|
436
|
+
font-size: 12px;
|
|
437
|
+
font-weight: 600;
|
|
438
|
+
color: var(--text);
|
|
439
|
+
}
|
|
440
|
+
|
|
349
441
|
</style>
|
|
350
442
|
</head>
|
|
351
443
|
|
|
@@ -446,11 +538,42 @@
|
|
|
446
538
|
</button>
|
|
447
539
|
|
|
448
540
|
</div>
|
|
449
|
-
|
|
541
|
+
|
|
450
542
|
<button class="save-btn" id="btn_save_node_positions" >Save</button>
|
|
451
543
|
<button class="home-btn" id="btn_home_location" >Home</button>
|
|
452
544
|
<button class="reset-btn" id="btn_reset_preferences" >Reset</button>
|
|
453
545
|
|
|
546
|
+
<div class="toggle-group">
|
|
547
|
+
|
|
548
|
+
<label class="toggle-item">
|
|
549
|
+
<input type="checkbox" id="togglePhysics" checked>
|
|
550
|
+
<div class="toggle-dot"></div>
|
|
551
|
+
<span class="toggle-label">Physics</span>
|
|
552
|
+
</label>
|
|
553
|
+
|
|
554
|
+
<label class="toggle-item">
|
|
555
|
+
<input type="checkbox" id="toggleTagNodes" unchecked>
|
|
556
|
+
<div class="toggle-dot"></div>
|
|
557
|
+
<span class="toggle-label">Tags</span>
|
|
558
|
+
</label>
|
|
559
|
+
|
|
560
|
+
<label class="toggle-item">
|
|
561
|
+
<input type="checkbox" id="toggleFileNodes" checked>
|
|
562
|
+
<div class="toggle-dot"></div>
|
|
563
|
+
<span class="toggle-label">Nodes</span>
|
|
564
|
+
</label>
|
|
565
|
+
|
|
566
|
+
<label class="toggle-item">
|
|
567
|
+
<input type="checkbox" id="toggleGrid" checked>
|
|
568
|
+
<div class="toggle-dot"></div>
|
|
569
|
+
<span class="toggle-label">Grid</span>
|
|
570
|
+
</label>
|
|
571
|
+
|
|
572
|
+
</div>
|
|
573
|
+
|
|
574
|
+
<span id="text_gridScale" class="control-label">Grid Scale</span>
|
|
575
|
+
<input id="slider_gridScale" type="range" min="10" max="300" value="100"></input>
|
|
576
|
+
|
|
454
577
|
<span id="text_gravitationalConstant" class="control-label">
|
|
455
578
|
Gravitational Constant
|
|
456
579
|
</span>
|
|
@@ -781,27 +904,35 @@
|
|
|
781
904
|
var viewState = {};
|
|
782
905
|
|
|
783
906
|
var default_preferences = {
|
|
907
|
+
"physics": true,
|
|
908
|
+
"showTags": false,
|
|
909
|
+
"showNodes": true,
|
|
910
|
+
"showGrid": true,
|
|
911
|
+
"gridScale": 120,
|
|
912
|
+
"gravitationalConstant": 437,
|
|
784
913
|
"centralGravity": 8,
|
|
914
|
+
"springConstant": 5,
|
|
785
915
|
"damping": 20,
|
|
786
|
-
"edgeLength": 4,
|
|
787
|
-
"edgeWidth": 6,
|
|
788
916
|
"fontSize": 43,
|
|
789
|
-
"gravitationalConstant": 437,
|
|
790
917
|
"nodeSize": 11,
|
|
791
|
-
"
|
|
792
|
-
"
|
|
918
|
+
"edgeLength": 4,
|
|
919
|
+
"edgeWidth": 6,
|
|
793
920
|
};
|
|
794
921
|
|
|
795
922
|
var preferences = {
|
|
923
|
+
"physics": true,
|
|
924
|
+
"showTags": false,
|
|
925
|
+
"showNodes": true,
|
|
926
|
+
"showGrid": true,
|
|
927
|
+
"gridScale": 120,
|
|
928
|
+
"gravitationalConstant": 437,
|
|
796
929
|
"centralGravity": 8,
|
|
930
|
+
"springConstant": 5,
|
|
797
931
|
"damping": 20,
|
|
798
|
-
"edgeLength": 4,
|
|
799
|
-
"edgeWidth": 6,
|
|
800
932
|
"fontSize": 43,
|
|
801
|
-
"gravitationalConstant": 437,
|
|
802
933
|
"nodeSize": 11,
|
|
803
|
-
"
|
|
804
|
-
"
|
|
934
|
+
"edgeLength": 4,
|
|
935
|
+
"edgeWidth": 6,
|
|
805
936
|
};
|
|
806
937
|
|
|
807
938
|
storedPreferences = localStorage.getItem('preferences');
|
|
@@ -830,6 +961,7 @@
|
|
|
830
961
|
}
|
|
831
962
|
toggleSaveNodePositions()
|
|
832
963
|
});
|
|
964
|
+
|
|
833
965
|
function loadViewState(){
|
|
834
966
|
var savedState = JSON.parse(localStorage.getItem('networkViewState'));
|
|
835
967
|
if (savedState) {
|
|
@@ -843,6 +975,7 @@
|
|
|
843
975
|
function saveViewState(){
|
|
844
976
|
var viewPosition = network.getViewPosition();
|
|
845
977
|
var scale = network.getScale();
|
|
978
|
+
|
|
846
979
|
var viewState = {
|
|
847
980
|
position: viewPosition,
|
|
848
981
|
scale: scale
|
|
@@ -854,35 +987,6 @@
|
|
|
854
987
|
localStorage.setItem('preferences', JSON.stringify(preferences));
|
|
855
988
|
}
|
|
856
989
|
|
|
857
|
-
function loadPhysics(){
|
|
858
|
-
var btn = document.getElementById('btn_physics');
|
|
859
|
-
if (preferences.physics == true) {
|
|
860
|
-
network.setOptions( { physics: true } );
|
|
861
|
-
btn.innerHTML = 'Physics: ON';
|
|
862
|
-
} else {
|
|
863
|
-
network.setOptions( { physics: false } );
|
|
864
|
-
btn.innerHTML = 'Physics: OFF';
|
|
865
|
-
}
|
|
866
|
-
}
|
|
867
|
-
|
|
868
|
-
// Add Button and Slider to Control the Physics
|
|
869
|
-
function togglePhysics() {
|
|
870
|
-
var btn = document.getElementById('btn_physics');
|
|
871
|
-
var physics = !network.physics.options.enabled;
|
|
872
|
-
network.physics.enabled = physics;
|
|
873
|
-
|
|
874
|
-
if (physics) {
|
|
875
|
-
preferences.physics = true;
|
|
876
|
-
network.setOptions( { physics: true } );
|
|
877
|
-
btn.innerHTML = 'Physics: ON';
|
|
878
|
-
} else {
|
|
879
|
-
preferences.physics = false;
|
|
880
|
-
network.setOptions( { physics: false } );
|
|
881
|
-
btn.innerHTML = 'Physics: OFF';
|
|
882
|
-
}
|
|
883
|
-
savePreferences();
|
|
884
|
-
}
|
|
885
|
-
|
|
886
990
|
// Reset all node highlights
|
|
887
991
|
function resetHighlight() {
|
|
888
992
|
nodes.forEach(node => {
|
|
@@ -1011,8 +1115,6 @@
|
|
|
1011
1115
|
|
|
1012
1116
|
}
|
|
1013
1117
|
|
|
1014
|
-
|
|
1015
|
-
// TODO New
|
|
1016
1118
|
// Get DOM elements
|
|
1017
1119
|
const searchInput = document.getElementById('searchInput');
|
|
1018
1120
|
searchInput.addEventListener('keyup', function(event) {
|
|
@@ -1026,10 +1128,6 @@
|
|
|
1026
1128
|
|
|
1027
1129
|
const downButton = document.getElementById("downButton");
|
|
1028
1130
|
downButton.addEventListener('click', () => navigateResults('down'));
|
|
1029
|
-
|
|
1030
|
-
// Physics
|
|
1031
|
-
const btn_physics = document.getElementById('btn_physics');
|
|
1032
|
-
btn_physics.onclick = togglePhysics;
|
|
1033
1131
|
|
|
1034
1132
|
// Save as Startup
|
|
1035
1133
|
const btn_save_node_positions = document.getElementById('btn_save_node_positions');
|
|
@@ -1050,6 +1148,124 @@
|
|
|
1050
1148
|
const btn_reset_preferences = document.getElementById('btn_reset_preferences');
|
|
1051
1149
|
btn_reset_preferences.onclick = resetPreferences;
|
|
1052
1150
|
|
|
1151
|
+
const chk_physics = document.getElementById('togglePhysics');
|
|
1152
|
+
chk_physics.addEventListener('change', e => {on_toggle_physics(e.target.checked);});
|
|
1153
|
+
|
|
1154
|
+
function load_physics(){
|
|
1155
|
+
const chk_physics = document.getElementById('togglePhysics');
|
|
1156
|
+
chk_physics.checked = preferences.physics;
|
|
1157
|
+
on_toggle_physics(preferences.physics)
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
// Add Button and Slider to Control the Physics
|
|
1161
|
+
function on_toggle_physics(physics) {
|
|
1162
|
+
network.physics.enabled = physics;
|
|
1163
|
+
network.setOptions( { physics: physics } );
|
|
1164
|
+
preferences.physics = physics;
|
|
1165
|
+
savePreferences();
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
const chk_show_tags = document.getElementById('toggleTagNodes');
|
|
1169
|
+
chk_show_tags.addEventListener('change', e => {
|
|
1170
|
+
on_node_vis_changed('tagnode', e.target.checked);
|
|
1171
|
+
});
|
|
1172
|
+
|
|
1173
|
+
function load_show_tags(){
|
|
1174
|
+
const chk_show_tags = document.getElementById('toggleTagNodes');
|
|
1175
|
+
chk_show_tags.checked = preferences.showTags;
|
|
1176
|
+
on_node_vis_changed('tagnode', preferences.showTags);
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
const chk_show_nodes = document.getElementById('toggleFileNodes');
|
|
1180
|
+
chk_show_nodes.addEventListener('change', e => {
|
|
1181
|
+
on_node_vis_changed('filenode', e.target.checked);
|
|
1182
|
+
});
|
|
1183
|
+
|
|
1184
|
+
function load_show_nodes(){
|
|
1185
|
+
const chk_show_nodes = document.getElementById('toggleFileNodes');
|
|
1186
|
+
chk_show_nodes.checked = preferences.showNodes;
|
|
1187
|
+
on_node_vis_changed('filenode', preferences.showNodes);
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
// Store removed edges per nodetype so they can be restored later
|
|
1191
|
+
var removedEdgesByType = {};
|
|
1192
|
+
|
|
1193
|
+
function on_node_vis_changed(nodetype, visible) {
|
|
1194
|
+
hidden = !visible;
|
|
1195
|
+
const matched = network.body.data.nodes.get({ filter: n => n.nodetype === nodetype });
|
|
1196
|
+
network.body.data.nodes.update(matched.map(n => ({ id: n.id, hidden })));
|
|
1197
|
+
|
|
1198
|
+
if (hidden) {
|
|
1199
|
+
// Collect all edges connected to the hidden nodes
|
|
1200
|
+
const connectedEdgeIds = new Set(matched.flatMap(n => network.getConnectedEdges(n.id)));
|
|
1201
|
+
const edgesToRemove = edges.get(Array.from(connectedEdgeIds));
|
|
1202
|
+
|
|
1203
|
+
// Save them keyed by nodetype so we can restore later
|
|
1204
|
+
if (!removedEdgesByType[nodetype]) removedEdgesByType[nodetype] = [];
|
|
1205
|
+
edgesToRemove.forEach(e => {
|
|
1206
|
+
// Avoid duplicates if multiple nodetypes share an edge
|
|
1207
|
+
if (!removedEdgesByType[nodetype].find(r => r.id === e.id)) {
|
|
1208
|
+
removedEdgesByType[nodetype].push(e);
|
|
1209
|
+
}
|
|
1210
|
+
});
|
|
1211
|
+
|
|
1212
|
+
edges.remove(Array.from(connectedEdgeIds));
|
|
1213
|
+
} else {
|
|
1214
|
+
// Restore edges that were removed for this nodetype,
|
|
1215
|
+
// but only if both endpoint nodes are currently visible
|
|
1216
|
+
const toRestore = removedEdgesByType[nodetype] || [];
|
|
1217
|
+
const validEdges = toRestore.filter(e => {
|
|
1218
|
+
const fromNode = network.body.data.nodes.get(e.from);
|
|
1219
|
+
const toNode = network.body.data.nodes.get(e.to);
|
|
1220
|
+
return fromNode && !fromNode.hidden && toNode && !toNode.hidden;
|
|
1221
|
+
});
|
|
1222
|
+
if (validEdges.length > 0) edges.add(validEdges);
|
|
1223
|
+
removedEdgesByType[nodetype] = [];
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
if (nodetype == "filenode"){
|
|
1227
|
+
preferences.showNodes = visible;
|
|
1228
|
+
}
|
|
1229
|
+
else if (nodetype == "tagnode"){
|
|
1230
|
+
preferences.showTags = visible;
|
|
1231
|
+
}
|
|
1232
|
+
savePreferences();
|
|
1233
|
+
}
|
|
1234
|
+
|
|
1235
|
+
const chk_show_grid = document.getElementById('toggleGrid');
|
|
1236
|
+
chk_show_grid.addEventListener('change', on_grid_changed);
|
|
1237
|
+
|
|
1238
|
+
const slider_grid_scale = document.getElementById('slider_gridScale')
|
|
1239
|
+
slider_grid_scale.addEventListener('input', on_grid_changed);
|
|
1240
|
+
|
|
1241
|
+
function load_grid(){
|
|
1242
|
+
const chk_show_grid = document.getElementById('toggleGrid');
|
|
1243
|
+
chk_show_grid.checked = preferences.showGrid;
|
|
1244
|
+
|
|
1245
|
+
const slider_grid_scale = document.getElementById('slider_gridScale')
|
|
1246
|
+
slider_grid_scale.value = preferences.gridScale;
|
|
1247
|
+
|
|
1248
|
+
on_grid_changed();
|
|
1249
|
+
}
|
|
1250
|
+
|
|
1251
|
+
function on_grid_changed() {
|
|
1252
|
+
const net = document.getElementById('mynetwork');
|
|
1253
|
+
const visible = document.getElementById('toggleGrid').checked;
|
|
1254
|
+
if (!visible) { net.style.backgroundImage = 'none'; return; }
|
|
1255
|
+
const scale = parseInt(document.getElementById('slider_gridScale').value);
|
|
1256
|
+
const minor = Math.max(2, Math.round(scale / 5));
|
|
1257
|
+
net.style.backgroundImage = `
|
|
1258
|
+
linear-gradient(rgba(255,255,255,0.04) 1px, transparent 1px),
|
|
1259
|
+
linear-gradient(90deg, rgba(255,255,255,0.04) 1px, transparent 1px),
|
|
1260
|
+
linear-gradient(rgba(255,255,255,0.015) 1px, transparent 1px),
|
|
1261
|
+
linear-gradient(90deg, rgba(255,255,255,0.015) 1px, transparent 1px)`;
|
|
1262
|
+
net.style.backgroundSize = `${scale}px ${scale}px, ${scale}px ${scale}px, ${minor}px ${minor}px, ${minor}px ${minor}px`;
|
|
1263
|
+
net.style.backgroundPosition = '-1px -1px, -1px -1px, -1px -1px, -1px -1px';
|
|
1264
|
+
preferences.showGrid = visible;
|
|
1265
|
+
preferences.gridScale = scale;
|
|
1266
|
+
savePreferences();
|
|
1267
|
+
}
|
|
1268
|
+
|
|
1053
1269
|
// gravitationalConstant
|
|
1054
1270
|
const slider_gravitationalConstant = document.getElementById('slider_gravitationalConstant');
|
|
1055
1271
|
slider_gravitationalConstant.value = preferences.gravitationalConstant;
|
|
@@ -1170,8 +1386,11 @@
|
|
|
1170
1386
|
on_slider_fontSize_input();
|
|
1171
1387
|
on_slider_nodeSize_input();
|
|
1172
1388
|
on_slider_edge_input();
|
|
1173
|
-
loadPhysics();
|
|
1174
1389
|
loadViewState();
|
|
1390
|
+
load_physics();
|
|
1391
|
+
load_show_nodes();
|
|
1392
|
+
load_show_tags();
|
|
1393
|
+
load_grid();
|
|
1175
1394
|
}
|
|
1176
1395
|
|
|
1177
1396
|
function homeLocation(){
|
|
@@ -1184,7 +1403,11 @@
|
|
|
1184
1403
|
}
|
|
1185
1404
|
|
|
1186
1405
|
function resetPreferences(){
|
|
1187
|
-
|
|
1406
|
+
|
|
1407
|
+
document.getElementById('toggleTagNodes').checked = default_preferences.showTags;
|
|
1408
|
+
document.getElementById('toggleFileNodes').checked = default_preferences.showNodes;
|
|
1409
|
+
document.getElementById('toggleGrid').checked = default_preferences.showGrid;
|
|
1410
|
+
document.getElementById('slider_gridScale').value = default_preferences.gridScale;
|
|
1188
1411
|
document.getElementById('slider_gravitationalConstant').value = default_preferences.gravitationalConstant;
|
|
1189
1412
|
document.getElementById('slider_centralGravity').value = default_preferences.centralGravity;
|
|
1190
1413
|
document.getElementById('slider_springConstant').value = default_preferences.springConstant;
|
|
@@ -1207,6 +1430,9 @@
|
|
|
1207
1430
|
if (node.url) {
|
|
1208
1431
|
if (params.event.srcEvent.ctrlKey) {
|
|
1209
1432
|
window.open(node.url, '_blank');
|
|
1433
|
+
}
|
|
1434
|
+
else if (params.event.srcEvent.altKey) {
|
|
1435
|
+
window.open(node.url2, '_blank');
|
|
1210
1436
|
}else {
|
|
1211
1437
|
window.location.href = node.url;
|
|
1212
1438
|
}
|
|
@@ -1222,21 +1448,23 @@
|
|
|
1222
1448
|
scale: viewState.scale
|
|
1223
1449
|
});
|
|
1224
1450
|
|
|
1225
|
-
// preferences.physics = true;
|
|
1226
|
-
|
|
1227
1451
|
node_positions = {};
|
|
1228
1452
|
saveNodePositions();
|
|
1229
1453
|
|
|
1230
1454
|
preferences = {
|
|
1455
|
+
"physics": true,
|
|
1456
|
+
"showTags": false,
|
|
1457
|
+
"showNodes": true,
|
|
1458
|
+
"showGrid": true,
|
|
1459
|
+
"gridScale": 120,
|
|
1460
|
+
"gravitationalConstant": 437,
|
|
1231
1461
|
"centralGravity": 8,
|
|
1462
|
+
"springConstant": 5,
|
|
1232
1463
|
"damping": 20,
|
|
1233
|
-
"edgeLength": 4,
|
|
1234
|
-
"edgeWidth": 6,
|
|
1235
1464
|
"fontSize": 43,
|
|
1236
|
-
"gravitationalConstant": 437,
|
|
1237
1465
|
"nodeSize": 11,
|
|
1238
|
-
"
|
|
1239
|
-
"
|
|
1466
|
+
"edgeLength": 4,
|
|
1467
|
+
"edgeWidth": 6,
|
|
1240
1468
|
};
|
|
1241
1469
|
savePreferences();
|
|
1242
1470
|
|
|
@@ -1245,27 +1473,6 @@
|
|
|
1245
1473
|
|
|
1246
1474
|
loadPreferences();
|
|
1247
1475
|
|
|
1248
|
-
// seet physic on / off by dragStart dragEnd
|
|
1249
|
-
// network.on("dragStart", function(params) {
|
|
1250
|
-
// if (params.nodes.length > 0) {
|
|
1251
|
-
// network.setOptions( { physics: true } );
|
|
1252
|
-
// }
|
|
1253
|
-
// });
|
|
1254
|
-
|
|
1255
|
-
// network.on("dragEnd", function(params) {
|
|
1256
|
-
// if (params.nodes.length > 0) {
|
|
1257
|
-
|
|
1258
|
-
// network.setOptions( { physics: false } );
|
|
1259
|
-
|
|
1260
|
-
// }
|
|
1261
|
-
// });
|
|
1262
|
-
|
|
1263
|
-
// setTimeout(function() {
|
|
1264
|
-
// network.setOptions( { physics: false } );
|
|
1265
|
-
// }, 12000);
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
1476
|
|
|
1270
1477
|
{% if neighborhood_highlight %}
|
|
1271
1478
|
network.on("click", neighbourhoodHighlight);
|
|
@@ -72,6 +72,7 @@ class GraphViewPlugin(mkdocs.plugins.BasePlugin):
|
|
|
72
72
|
def on_post_build(self, config, **kwargs):
|
|
73
73
|
docs_dir = config["docs_dir"]
|
|
74
74
|
site_dir = config['site_dir']
|
|
75
|
+
|
|
75
76
|
config_graphfile = self.get_config_graphfile()
|
|
76
77
|
if not config_graphfile.endswith(".html"):
|
|
77
78
|
config_graphfile = config_graphfile + ".html"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: mkdocs-nodegraph
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Node Graph plugin for Mkdocs Material
|
|
5
5
|
Home-page: https://yonge123.github.io/mkdocs-nodegraph/nodegraph.html
|
|
6
6
|
Author: JeongYong Hwang
|
|
@@ -18,6 +18,17 @@ Requires-Dist: pyembed-markdown>=1.1.0
|
|
|
18
18
|
Requires-Dist: mkdocs-glightbox>=0.4.0
|
|
19
19
|
Requires-Dist: pyvis>=0.3.0
|
|
20
20
|
Requires-Dist: PyYAML>=6.0.2
|
|
21
|
+
Dynamic: author
|
|
22
|
+
Dynamic: author-email
|
|
23
|
+
Dynamic: description
|
|
24
|
+
Dynamic: description-content-type
|
|
25
|
+
Dynamic: home-page
|
|
26
|
+
Dynamic: keywords
|
|
27
|
+
Dynamic: license
|
|
28
|
+
Dynamic: project-url
|
|
29
|
+
Dynamic: requires-dist
|
|
30
|
+
Dynamic: requires-python
|
|
31
|
+
Dynamic: summary
|
|
21
32
|
|
|
22
33
|
# mkdocs-nodegraph
|
|
23
34
|
|
|
@@ -35,11 +46,11 @@ It allows you to create interactive visualizations of your documentation structu
|
|
|
35
46
|
|
|
36
47
|
<p align="center">
|
|
37
48
|
<a>
|
|
38
|
-
<img alt="
|
|
49
|
+
<img alt="example_image_002.png" src="https://github.com/yonge123/mkdocs-nodegraph/blob/master/sources/example_image_002.png?raw=true" data-hpc="true" class="Box-sc-g0xbh4-0 fzFXnm">
|
|
39
50
|
</a>
|
|
40
51
|
|
|
41
52
|
|
|
42
|
-
<!--  -->
|
|
43
54
|
|
|
44
55
|
|
|
45
56
|
<br>
|
|
@@ -106,6 +117,19 @@ mdfile_site -> A website URL that opens on click while holding the Alt key
|
|
|
106
117
|
|
|
107
118
|
<br>
|
|
108
119
|
|
|
120
|
+
## Click Node
|
|
121
|
+
|
|
122
|
+
`LMB` -> Open Node Page
|
|
123
|
+
|
|
124
|
+
`Ctrl + LMB` -> Open Node Page in a New Tab
|
|
125
|
+
|
|
126
|
+
`Alt + LMB` -> Open the mdfile_site Page from the metadata
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
<br>
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
109
133
|
## mkdocs.yml Configuration
|
|
110
134
|
|
|
111
135
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/templates/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
{mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph.egg-info/entry_points.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|