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.
Files changed (20) hide show
  1. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/PKG-INFO +28 -4
  2. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/README.md +15 -2
  3. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/generate_graph.py +43 -5
  4. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/graph_opts.json +1 -1
  5. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/mdparser.py +26 -9
  6. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/templates/template.html +403 -196
  7. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/plugin.py +1 -0
  8. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph.egg-info/PKG-INFO +28 -4
  9. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/setup.py +1 -1
  10. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/__init__.py +0 -0
  11. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/__init__.py +0 -0
  12. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/mdfile.py +0 -0
  13. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/pyvis_opts.js +0 -0
  14. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph/nodegraph/templates/__init__.py +0 -0
  15. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph.egg-info/SOURCES.txt +0 -0
  16. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph.egg-info/dependency_links.txt +0 -0
  17. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph.egg-info/entry_points.txt +0 -0
  18. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph.egg-info/requires.txt +0 -0
  19. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/mkdocs_nodegraph.egg-info/top_level.txt +0 -0
  20. {mkdocs_nodegraph-0.4.1 → mkdocs_nodegraph-0.5.0}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: mkdocs-nodegraph
3
- Version: 0.4.1
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="example_image_001.png" src="https://github.com/yonge123/mkdocs-nodegraph/blob/master/sources/example_image_001.png?raw=true" data-hpc="true" class="Box-sc-g0xbh4-0 fzFXnm">
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
- <!-- ![Example Network Graph Visualization](./sources/example_image_001.png) -->
53
+ <!-- ![Example Network Graph Visualization](./sources/example_image_002.png) -->
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="example_image_001.png" src="https://github.com/yonge123/mkdocs-nodegraph/blob/master/sources/example_image_001.png?raw=true" data-hpc="true" class="Box-sc-g0xbh4-0 fzFXnm">
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
- <!-- ![Example Network Graph Visualization](./sources/example_image_001.png) -->
21
+ <!-- ![Example Network Graph Visualization](./sources/example_image_002.png) -->
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
 
@@ -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, graph_opts_file, config_graphfile):
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
- mdfiles = parser.parse()
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):
@@ -2,6 +2,6 @@
2
2
  "width": "100%",
3
3
  "height": "90vh",
4
4
  "heading": "",
5
- "bgcolor": "#222222",
5
+ "bgcolor": "191B20",
6
6
  "font_color": "#94A3B8"
7
7
  }
@@ -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
- md.uid = uid
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
- uid = 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))
90
- if len(uid) > 0:
91
- uids.add(uid[0].uid)
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
- return self.mdfiles
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
@@ -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/9.1.2/dist/dist/vis-network.min.css" integrity="sha512-WgxfT5LWjfszlPHXRmBWHkV2eceiWTOBvrKCNbdgDYTHrT2AeLCGbF4sZlZw3UMN3WtL0tGUoIAKsu8mllg/XA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
7
- <script src="https://cdnjs.cloudflare.com/ajax/libs/vis-network/9.1.2/dist/vis-network.min.js" integrity="sha512-LnvoEWDFrqGHlHmDD2101OrLcbsfkrzoSpvtSQtxK3RMnRV0eOkhhBN2dXHKRrUU8p2DGRTk35n4O8nWSVe1mQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
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 'lib/vis-9.1.2/vis-network.css' %}</style>
14
- <script>{% include 'lib/vis-9.1.2/vis-network.min.js' %}</script>
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/9.1.2/dist/dist/vis-network.min.css" integrity="sha512-WgxfT5LWjfszlPHXRmBWHkV2eceiWTOBvrKCNbdgDYTHrT2AeLCGbF4sZlZw3UMN3WtL0tGUoIAKsu8mllg/XA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
21
- <script src="https://cdnjs.cloudflare.com/ajax/libs/vis-network/9.1.2/dist/vis-network.min.js" integrity="sha512-LnvoEWDFrqGHlHmDD2101OrLcbsfkrzoSpvtSQtxK3RMnRV0eOkhhBN2dXHKRrUU8p2DGRTk35n4O8nWSVe1mQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
22
- {# <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/vis-network/9.0.4/dist/dist/vis-network.min.css" integrity="sha512-+5tJeVsSE2tSnmKB5SWOD0GsYA5dOP0B/FSv7I2GYhdOcyjJq81Q1St3qgJgInwreAdNuw0KGJ0FOaxOJ0E4yw==" crossorigin="anonymous" referrerpolicy="no-referrer" />#}
23
- {# <script src="https://cdnjs.cloudflare.com/ajax/libs/vis-network/9.0.4/dist/vis-network.js"#}
24
- {# integrity="sha512-CEbUhbSq35hCqBH8ckfAkH1Tcua5NEywtEzwiJ+BUC4EIZkC7vyta3ivZu/WqJhK1qHTurO3hwHsErU3HHjwIA=="#}
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); /* Old browsers */
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
- /* position absolute is important and the container has to be relative or absolute as well. */
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: #222222a6;
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: 3px;
197
+ margin-bottom: 8px;
202
198
  display: flex;
203
199
  align-items: center;
204
- gap: 3px;
200
+ gap: 5px;
205
201
  }
206
202
 
207
203
  .search-input {
208
- width: 300px;
209
- padding: 5px;
210
- background-color: white;
211
- color: rgb(27, 27, 27);
212
- border: 1px solid #ddd;
213
- border-radius: 4px;
214
- font-size: 16px;
215
- }
216
-
217
- .up-btn {
218
- width: 30px;
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
- .up-btn:active {
235
- background-color:hsl(0, 0%, 65%);
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
- background-color: hsl(0, 0%, 65%);
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
- background-color:hsl(0, 0%, 71%);
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-color:hsl(0, 0%, 65%);
245
+ background: rgba(0,229,255,0.18);
257
246
  }
258
247
 
259
- .physics-btn {
260
- font-size: 13px;
261
- padding: 9px 9px;
262
- margin-bottom: 3px;
263
- background-color: hsl(122, 39%, 49%);
264
- color: white;
265
- border: none;
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
- .physics-btn:hover {
272
- background-color:hsl(121, 47%, 57%);
273
- }
268
+ .save-btn:active,
269
+ .home-btn:active,
270
+ .reset-btn:active { transform: scale(0.97); }
274
271
 
275
272
  .save-btn {
276
- font-size: 13px;
277
- padding: 9px 9px;
278
- margin-bottom: 3px;
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-color: hsl(194, 41%, 53%);
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
- .reset-btn {
292
- font-size: 14px;
293
- padding: 9px 9px;
294
- margin-bottom: 3px;
295
- background-color: hsl(0, 0%, 40%);
296
- color: white;
297
- border: none;
298
- width: 100%;
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:hover {
304
- background-color: hsl(0, 0%, 50%);
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
- .home-btn {
307
- font-size: 13px;
308
- padding: 9px 9px;
309
- margin-bottom: 3px;
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: gray;
305
+ accent-color: var(--accent);
324
306
  }
325
307
 
326
308
  .control-label {
327
- opacity: 0.9;
328
- top: 0px;
329
- left: 0px;
330
- font-size: 16px;
331
- font-weight: bold;
332
- color: #4CAF50;
333
- display: block;
334
- margin-bottom: 5px;
335
- width: 100%;
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
- color: gray;
340
- opacity: 0.5;
321
+ -webkit-appearance: none;
322
+ appearance: none;
341
323
  width: 100%;
342
- height: 10px;
343
- background: #d3d3d3;
324
+ height: 14px;
325
+ background: transparent;
326
+ border-radius: 4px;
344
327
  outline: none;
345
- border-radius: 8px;
346
- margin-bottom: 6px;
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
- <button class="physics-btn" id="btn_physics" >Physics: ON</button>
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
- "physics": true,
792
- "springConstant": 5,
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
- "physics": true,
804
- "springConstant": 5,
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
- document.getElementById('btn_physics').value = default_preferences.physics;
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
- "physics": true,
1239
- "springConstant": 5,
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
1
+ Metadata-Version: 2.4
2
2
  Name: mkdocs-nodegraph
3
- Version: 0.4.1
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="example_image_001.png" src="https://github.com/yonge123/mkdocs-nodegraph/blob/master/sources/example_image_001.png?raw=true" data-hpc="true" class="Box-sc-g0xbh4-0 fzFXnm">
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
- <!-- ![Example Network Graph Visualization](./sources/example_image_001.png) -->
53
+ <!-- ![Example Network Graph Visualization](./sources/example_image_002.png) -->
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
 
@@ -5,7 +5,7 @@ with open('README.md', 'r') as fin:
5
5
 
6
6
  setup(
7
7
  name="mkdocs-nodegraph",
8
- version="0.4.1",
8
+ version="0.5.0",
9
9
  description="Node Graph plugin for Mkdocs Material",
10
10
  long_description=long_description,
11
11
  long_description_content_type="text/markdown",