jekyll-graph 0.0.1 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +21 -0
- data/Gemfile +2 -2
- data/README.md +41 -31
- data/bin/console +1 -1
- data/jekyll-graph.gemspec +4 -3
- data/lib/jekyll-graph/config.rb +32 -8
- data/lib/jekyll-graph/jekyll-graph.js +58 -24
- data/lib/jekyll-graph/tags.rb +1 -1
- data/lib/jekyll-graph/version.rb +1 -1
- data/lib/jekyll-graph.rb +66 -51
- metadata +9 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 16fc54d9f258c71e879a2b65b3d642e2c6ba0a30efaec85fb036941bffdf5c49
|
4
|
+
data.tar.gz: 052f0d8c7c64150116e7205f66f8d0052433713f0f012eac3ce229f9f48001fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a4e8ea1b69e907907d5d384f7352dc4bc7f9cc1511c0e3a731cea9f43138074aa24f17691bc740a09979c34605add2838334b1ddf6ce8d96066597386c4ea70
|
7
|
+
data.tar.gz: 7ca4c585d6f999fb4a4dbf24801b7165fee27b67f01334e9d3dc66eb06f638889fc0276feeef71a5d632424c51a23c62445f667be74abbb255902936c63f7b2c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,24 @@
|
|
1
|
+
## [0.0.5] - 2021-11-23
|
2
|
+
### Change
|
3
|
+
- 'relatives' -> 'lineage' for tree nodes.
|
4
|
+
|
5
|
+
## [0.0.4] 2021-11-22
|
6
|
+
### Fix
|
7
|
+
- Custom path config related fix in scripts.
|
8
|
+
|
9
|
+
## [0.0.3] 2021-11-22
|
10
|
+
### Change
|
11
|
+
- Fix javascript inheritance.
|
12
|
+
- Decrement missing node log messages from 'warn' to 'debug'.
|
13
|
+
- Update license.
|
14
|
+
### Fix
|
15
|
+
- Display log messages related to dependencies (see [#2](https://github.com/manunamz/jekyll-graph/issues/2)).
|
16
|
+
- Custom path configs.
|
17
|
+
|
18
|
+
## [0.0.2] - 2021-09-17
|
19
|
+
### Change
|
20
|
+
- Liquid tag `force-graph` -> `jekyll_graph`.
|
21
|
+
|
1
22
|
## [0.0.1] - 2021-09-17
|
2
23
|
- Initial release
|
3
24
|
### Added
|
data/Gemfile
CHANGED
@@ -6,8 +6,8 @@ source "https://rubygems.org"
|
|
6
6
|
gemspec
|
7
7
|
|
8
8
|
gem "jekyll", "~> 4.2.0"
|
9
|
-
gem "jekyll-namespaces", "~> 0.0.
|
10
|
-
gem "jekyll-wikilinks", "~> 0.0.
|
9
|
+
gem "jekyll-namespaces", "~> 0.0.3"
|
10
|
+
gem "jekyll-wikilinks", "~> 0.0.8"
|
11
11
|
|
12
12
|
gem "rake", "~> 13.0.3"
|
13
13
|
gem "rspec", "~> 3.10"
|
data/README.md
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
|
5
5
|
⚠️ Expect breaking changes and surprises until otherwise noted (likely by v0.1.0 or v1.0.0). ⚠️
|
6
6
|
|
7
|
-
Jekyll-Graph generates data and renders a graph that allows visitors to navigate a jekyll site by clicking nodes in the graph. Nodes are generated from the site's markdown files. Links for the tree graph are generated from `jekyll-namespaces` and links for the net-web graph from `jekyll-wikilinks
|
7
|
+
Jekyll-Graph generates data and renders a graph that allows visitors to navigate a jekyll site by clicking nodes in the graph. Nodes are generated from the site's markdown files. Links for the tree graph are generated from [`jekyll-namespaces`](https://github.com/manunamz/jekyll-namespaces) and links for the net-web graph from [`jekyll-wikilinks`](https://github.com/manunamz/jekyll-wikilinks).
|
8
8
|
|
9
9
|
This gem is part of the [jekyll-bonsai](https://manunamz.github.io/jekyll-bonsai/) project. 🎋
|
10
10
|
|
@@ -14,14 +14,14 @@ Follow the instructions for installing a [jekyll plugin](https://jekyllrb.com/do
|
|
14
14
|
|
15
15
|
## Usage
|
16
16
|
|
17
|
-
1. Add `{%
|
17
|
+
1. Add `{% jekyll_graph %}` to the site head:
|
18
18
|
|
19
19
|
```html
|
20
20
|
<head>
|
21
21
|
|
22
22
|
...
|
23
23
|
|
24
|
-
{%
|
24
|
+
{% jekyll_graph %}
|
25
25
|
|
26
26
|
</head>
|
27
27
|
```
|
@@ -37,41 +37,43 @@ Follow the instructions for installing a [jekyll plugin](https://jekyllrb.com/do
|
|
37
37
|
```javascript
|
38
38
|
import JekyllGraph from './jekyll-graph.js';
|
39
39
|
|
40
|
-
export default class JekyllGraphSubClass {
|
41
|
-
...
|
42
|
-
}
|
43
|
-
|
44
|
-
// subclass
|
45
|
-
// Hook up the instance properties
|
46
|
-
Object.setPrototypeOf(JekyllGraphSubClass.prototype, JekyllGraph.prototype);
|
47
|
-
|
48
|
-
// Hook up the static properties
|
49
|
-
Object.setPrototypeOf(JekyllGraphSubClass, JekyllGraph);
|
40
|
+
export default class JekyllGraphSubClass extends JekyllGraph {
|
50
41
|
|
42
|
+
constructor() {
|
43
|
+
super();
|
44
|
+
// access graph div with 'this.graphDiv'
|
45
|
+
}
|
46
|
+
|
47
|
+
// ...
|
48
|
+
}
|
51
49
|
```
|
52
50
|
Call `this.drawNetWeb()` and `this.drawTree()` to actually draw the graph. You could do this simply on initialization or on a button click, etc.
|
53
51
|
|
54
|
-
Unless otherwise defined, the `jekyll-graph.js` file will be generated into `_site/assets/
|
52
|
+
Unless otherwise defined, the `jekyll-graph.js` file will be generated into `_site/assets/js/`.
|
55
53
|
|
56
54
|
## Configuration
|
57
55
|
|
58
56
|
Default configs look like this:
|
59
57
|
|
60
|
-
```
|
58
|
+
```yaml
|
61
59
|
graph:
|
62
60
|
enabled: true
|
63
61
|
exclude: []
|
64
|
-
|
65
|
-
|
66
|
-
|
62
|
+
path:
|
63
|
+
assets: "/assets"
|
64
|
+
scripts: "/assets/js"
|
65
|
+
net_web:
|
67
66
|
enabled: true
|
67
|
+
exclude:
|
68
|
+
attrs: false
|
69
|
+
links: false
|
68
70
|
force:
|
69
71
|
charge:
|
70
72
|
strength_x:
|
71
73
|
x_val:
|
72
74
|
strength_y:
|
73
75
|
y_val:
|
74
|
-
|
76
|
+
tree:
|
75
77
|
enabled: true
|
76
78
|
force:
|
77
79
|
charge:
|
@@ -82,10 +84,17 @@ graph:
|
|
82
84
|
```
|
83
85
|
|
84
86
|
`enabled`: Turn off the plugin by setting to `false`.
|
87
|
+
|
85
88
|
`exclude`: Exclude specific jekyll document types (`posts`, `pages`, `collection_items`).
|
86
|
-
|
87
|
-
`
|
88
|
-
|
89
|
+
|
90
|
+
`path.assets`: An optional custom assets location for graph assets to generate into. Location is relative to the root of the generated `_site/` directory.
|
91
|
+
|
92
|
+
`path.scripts`: An optional custom scripts location for the graph scripts to generate into. Location is relative to the assets location in the `_site/` directory (If `assets_path` is set, but `scripts_path` is not, the location will default to `_site/<assets_path>/js/`).
|
93
|
+
|
94
|
+
`net_web.exclude.attrs` and `net_web.exclude.links`: Determines whether wikilink attributes and/or links are added to the net-web graph from the link index.
|
95
|
+
|
96
|
+
`tree.enabled` and `net_web.enabled`: Toggles on/off the `tree` and `net_web` graphs, respectively. Be sure to disable graphs that are not in use.
|
97
|
+
|
89
98
|
`tree.force` and `net_web.force`: These are force variables from d3's simulation forces. You can check out the [docs for details](https://github.com/d3/d3-force#simulation_force).
|
90
99
|
|
91
100
|
Force values will likely need to be played with depending on the div size and number of nodes. [jekyll-bonsai](https://manunamz.github.io/jekyll-bonsai/) currently uses these values:
|
@@ -93,7 +102,6 @@ Force values will likely need to be played with depending on the div size and nu
|
|
93
102
|
```yaml
|
94
103
|
graph:
|
95
104
|
tree:
|
96
|
-
# enabled: true
|
97
105
|
dag_lvl_dist: 100
|
98
106
|
force:
|
99
107
|
charge: -100
|
@@ -102,7 +110,6 @@ graph:
|
|
102
110
|
strength_y: 0.1
|
103
111
|
y_val: 0.9
|
104
112
|
net_web:
|
105
|
-
# enabled: true
|
106
113
|
force:
|
107
114
|
charge: -300
|
108
115
|
strength_x: 0.3
|
@@ -133,13 +140,13 @@ Graph colors are determined by css variables which may be defined like so -- any
|
|
133
140
|
--graph-particles-color: grey;
|
134
141
|
/* label text */
|
135
142
|
--graph-text-color: black;
|
136
|
-
/* */
|
137
143
|
```
|
138
144
|
|
139
145
|
## Data
|
140
146
|
Graph data is generated in the following format:
|
141
147
|
|
142
148
|
For the net-web graph, `graph-net-web.json`,`links` are built from `backlinks` and `attributed` metadata generated in `jekyll-wikilinks`:
|
149
|
+
|
143
150
|
```json
|
144
151
|
// graph-net-web.json
|
145
152
|
{
|
@@ -149,8 +156,8 @@ For the net-web graph, `graph-net-web.json`,`links` are built from `backlinks` a
|
|
149
156
|
"url": "<relative-url>", // site.baseurl is handled for you here
|
150
157
|
"label": "<note's-title>",
|
151
158
|
"neighbors": {
|
152
|
-
"nodes": [<neighbor-node>, ...],
|
153
|
-
"links": [<neighbor-link>, ...],
|
159
|
+
"nodes": [<neighbor-node-id>, ...],
|
160
|
+
"links": [<neighbor-link-id>, ...],
|
154
161
|
}
|
155
162
|
},
|
156
163
|
...
|
@@ -164,18 +171,20 @@ For the net-web graph, `graph-net-web.json`,`links` are built from `backlinks` a
|
|
164
171
|
]
|
165
172
|
}
|
166
173
|
```
|
174
|
+
|
167
175
|
For the tree graph, `graph-tree.json`, `links` are built from a tree data structure constructed in `jekyll-namespaces`:
|
176
|
+
|
168
177
|
```json
|
169
178
|
// graph-tree.json
|
170
179
|
{
|
171
180
|
"nodes": [
|
172
181
|
{
|
173
182
|
"id": "<some-id>",
|
174
|
-
"url": "<
|
183
|
+
"url": "<lineage-url>", // site.baseurl wil be handled for you here
|
175
184
|
"label": "<note's-title>",
|
176
|
-
"
|
177
|
-
"nodes": [<
|
178
|
-
"links": [<
|
185
|
+
"lineage": {
|
186
|
+
"nodes": [<lineage-node-id>, ...],
|
187
|
+
"links": [<lineage-link-id>, ...],
|
179
188
|
}
|
180
189
|
},
|
181
190
|
...
|
@@ -189,4 +198,5 @@ For the tree graph, `graph-tree.json`, `links` are built from a tree data struct
|
|
189
198
|
]
|
190
199
|
}
|
191
200
|
```
|
201
|
+
|
192
202
|
Unless otherwise defined, both json files are generated into `_site/assets/`.
|
data/bin/console
CHANGED
data/jekyll-graph.gemspec
CHANGED
@@ -12,7 +12,8 @@ Gem::Specification.new do |spec|
|
|
12
12
|
# spec.description = "TODO: Write a longer description or delete this line."
|
13
13
|
spec.homepage = "https://github.com/manunamz/jekyll-graph"
|
14
14
|
spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
|
15
|
-
|
15
|
+
spec.licenses = ["GPL3"]
|
16
|
+
|
16
17
|
# spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
17
18
|
|
18
19
|
spec.metadata["homepage_uri"] = spec.homepage
|
@@ -34,6 +35,6 @@ Gem::Specification.new do |spec|
|
|
34
35
|
# For more information and examples about making a new gem, checkout our
|
35
36
|
# guide at: https://bundler.io/guides/creating_gem.html
|
36
37
|
|
37
|
-
spec.add_runtime_dependency "jekyll-namespaces", "~> 0.0.
|
38
|
-
spec.add_runtime_dependency "jekyll-wikilinks", "~> 0.0.
|
38
|
+
spec.add_runtime_dependency "jekyll-namespaces", "~> 0.0.3"
|
39
|
+
spec.add_runtime_dependency "jekyll-wikilinks", "~> 0.0.8"
|
39
40
|
end
|
data/lib/jekyll-graph/config.rb
CHANGED
@@ -5,12 +5,16 @@ module Jekyll
|
|
5
5
|
module Graph
|
6
6
|
|
7
7
|
class PluginConfig
|
8
|
+
|
9
|
+
ASSETS_KEY = "assets"
|
10
|
+
ATTRS_KEY = "attrs"
|
8
11
|
CONFIG_KEY = "graph"
|
9
12
|
ENABLED_KEY = "enabled"
|
10
13
|
EXCLUDE_KEY = "exclude"
|
14
|
+
LINKS_KEY = "links"
|
11
15
|
NET_WEB_KEY = "net_web"
|
12
|
-
|
13
|
-
|
16
|
+
PATH_KEY = "path"
|
17
|
+
SCRIPTS_KEY = "scripts"
|
14
18
|
TREE_KEY = "tree"
|
15
19
|
TYPE_KEY = "type"
|
16
20
|
|
@@ -20,7 +24,7 @@ module Jekyll
|
|
20
24
|
Jekyll.logger.debug("Excluded jekyll types in graph: ", option(EXCLUDE_KEY)) unless disabled?
|
21
25
|
end
|
22
26
|
|
23
|
-
#
|
27
|
+
# descriptors
|
24
28
|
|
25
29
|
def disabled?
|
26
30
|
return option(ENABLED_KEY) == false
|
@@ -39,22 +43,42 @@ module Jekyll
|
|
39
43
|
return option(EXCLUDE_KEY).include?(type.to_s)
|
40
44
|
end
|
41
45
|
|
42
|
-
def
|
43
|
-
return
|
46
|
+
def has_custom_assets_path?
|
47
|
+
return option_path(ASSETS_KEY)
|
44
48
|
end
|
45
49
|
|
46
50
|
def has_custom_scripts_path?
|
47
|
-
return
|
51
|
+
return option_path(SCRIPTS_KEY)
|
52
|
+
end
|
53
|
+
|
54
|
+
def use_attrs?
|
55
|
+
return true if option_net_web_exclude(ATTRS_KEY).nil?
|
56
|
+
return !option_net_web_exclude(ATTRS_KEY)
|
57
|
+
end
|
58
|
+
|
59
|
+
def use_links?
|
60
|
+
return true if option_net_web_exclude(LINKS_KEY).nil?
|
61
|
+
return !option_net_web_exclude(LINKS_KEY)
|
48
62
|
end
|
49
63
|
|
64
|
+
# options
|
65
|
+
|
50
66
|
def option(key)
|
51
67
|
@config[CONFIG_KEY] && @config[CONFIG_KEY][key]
|
52
68
|
end
|
53
69
|
|
70
|
+
def option_path(key)
|
71
|
+
@config[CONFIG_KEY] && @config[CONFIG_KEY][PATH_KEY] && @config[CONFIG_KEY][PATH_KEY][key]
|
72
|
+
end
|
73
|
+
|
54
74
|
def option_net_web(key)
|
55
75
|
@config[CONFIG_KEY] && @config[CONFIG_KEY][NET_WEB_KEY] && @config[CONFIG_KEY][NET_WEB_KEY][key]
|
56
76
|
end
|
57
77
|
|
78
|
+
def option_net_web_exclude(key)
|
79
|
+
@config[CONFIG_KEY] && @config[CONFIG_KEY][NET_WEB_KEY] && @config[CONFIG_KEY][NET_WEB_KEY][EXCLUDE_KEY] && @config[CONFIG_KEY][NET_WEB_KEY][EXCLUDE_KEY][key]
|
80
|
+
end
|
81
|
+
|
58
82
|
def option_tree(key)
|
59
83
|
@config[CONFIG_KEY] && @config[CONFIG_KEY][TREE_KEY] && @config[CONFIG_KEY][TREE_KEY][key]
|
60
84
|
end
|
@@ -66,11 +90,11 @@ module Jekyll
|
|
66
90
|
end
|
67
91
|
|
68
92
|
def path_assets
|
69
|
-
return
|
93
|
+
return has_custom_assets_path? ? option_path(ASSETS_KEY) : "/assets"
|
70
94
|
end
|
71
95
|
|
72
96
|
def path_scripts
|
73
|
-
return has_custom_scripts_path? ?
|
97
|
+
return has_custom_scripts_path? ? File.join(path_assets, option_path(SCRIPTS_KEY)) : File.join(path_assets, "js")
|
74
98
|
end
|
75
99
|
|
76
100
|
def testing
|
@@ -1,4 +1,5 @@
|
|
1
1
|
// don't need frontmatter because liquid is handled internally...somehow...
|
2
|
+
|
2
3
|
export default class JekyllGraph {
|
3
4
|
|
4
5
|
constructor() {
|
@@ -7,7 +8,7 @@ export default class JekyllGraph {
|
|
7
8
|
|
8
9
|
// d3
|
9
10
|
drawNetWeb () {
|
10
|
-
let assetsPath = '{{ site.graph.
|
11
|
+
let assetsPath = '{{ site.graph.path.assets }}' !== '' ? '{{ site.graph.path.assets }}' : '/assets';
|
11
12
|
fetch(`{{ site.baseurl }}${assetsPath}/graph-net-web.json`).then(res => res.json()).then(data => {
|
12
13
|
|
13
14
|
// neighbors: replace ids with full object
|
@@ -29,9 +30,11 @@ export default class JekyllGraph {
|
|
29
30
|
let hoverNode = null;
|
30
31
|
let hoverLink = null;
|
31
32
|
|
32
|
-
|
33
|
+
if (this.graph) {
|
34
|
+
this.graph._destructor();
|
35
|
+
}
|
33
36
|
|
34
|
-
(this.graphDiv)
|
37
|
+
const Graph = ForceGraph()(this.graphDiv)
|
35
38
|
// container
|
36
39
|
.height(this.graphDiv.parentElement.clientHeight)
|
37
40
|
.width(this.graphDiv.parentElement.clientWidth)
|
@@ -101,35 +104,47 @@ export default class JekyllGraph {
|
|
101
104
|
Graph.height(el.offsetHeight);
|
102
105
|
}
|
103
106
|
);
|
107
|
+
|
108
|
+
this.graph = Graph;
|
104
109
|
});
|
105
110
|
}
|
106
111
|
|
107
112
|
drawTree () {
|
108
|
-
let assetsPath = '{{ site.graph.
|
113
|
+
let assetsPath = '{{ site.graph.path.assets }}' !== '' ? '{{ site.graph.path.assets }}' : '/assets';
|
109
114
|
fetch(`{{ site.baseurl }}${assetsPath}/graph-tree.json`).then(res => res.json()).then(data => {
|
115
|
+
|
116
|
+
if (this.graph) {
|
117
|
+
this.graph._destructor();
|
118
|
+
}
|
119
|
+
|
120
|
+
// node height vars
|
121
|
+
this.shifted = [];
|
122
|
+
this.numSiblingsLeft = [];
|
123
|
+
|
124
|
+
// hover vars
|
125
|
+
const highlightNodes = new Set();
|
126
|
+
const highlightLinks = new Set();
|
127
|
+
let hoverNode = null;
|
128
|
+
let hoverLink = null;
|
110
129
|
|
111
|
-
//
|
130
|
+
// lineage: replace ids with full objects
|
112
131
|
data.nodes.forEach(node => {
|
132
|
+
// lineage
|
113
133
|
let relativeNodes = [];
|
114
|
-
node.
|
134
|
+
node.lineage.nodes.forEach(nNodeId => {
|
115
135
|
relativeNodes.push(data.nodes.find(node => node.id === nNodeId));
|
116
136
|
});
|
117
137
|
let relativeLinks = [];
|
118
|
-
node.
|
138
|
+
node.lineage.links.forEach(nLink => {
|
119
139
|
relativeLinks.push(data.links.find(link => link.source === nLink.source && link.target === nLink.target));
|
120
140
|
});
|
121
|
-
node.
|
122
|
-
node.
|
141
|
+
node.lineage.nodes = relativeNodes;
|
142
|
+
node.lineage.links = relativeLinks;
|
143
|
+
// siblings
|
144
|
+
this.numSiblingsLeft[node.parent] = node.siblings.length;
|
123
145
|
});
|
124
146
|
|
125
|
-
const
|
126
|
-
const highlightLinks = new Set();
|
127
|
-
let hoverNode = null;
|
128
|
-
let hoverLink = null;
|
129
|
-
|
130
|
-
const Graph = ForceGraph()
|
131
|
-
|
132
|
-
(this.graphDiv)
|
147
|
+
const Graph = ForceGraph()(this.graphDiv)
|
133
148
|
// dag-mode (tree)
|
134
149
|
.dagMode('td')
|
135
150
|
.dagLevelDistance(Number('{{ site.graph.tree.dag_lvl_dist }}'))
|
@@ -141,6 +156,8 @@ export default class JekyllGraph {
|
|
141
156
|
// .nodePointerAreaPaint((node, color, ctx, scale) => nodePaint(node, nodeTypeInNetWeb(node), ctx))
|
142
157
|
.nodeId('id')
|
143
158
|
.nodeLabel('label')
|
159
|
+
// todo-shift: this shiftNodeHeight() always renders, but animatation is choppy
|
160
|
+
// .nodeVal(node => this.shiftNodeHeight(node))
|
144
161
|
.onNodeClick((node, event) => this.goToPage(node, event))
|
145
162
|
// link
|
146
163
|
.linkSource('source')
|
@@ -171,8 +188,8 @@ export default class JekyllGraph {
|
|
171
188
|
highlightLinks.clear();
|
172
189
|
if (node) {
|
173
190
|
highlightNodes.add(node);
|
174
|
-
node.
|
175
|
-
node.
|
191
|
+
node.lineage.nodes.forEach(node => highlightNodes.add(node));
|
192
|
+
node.lineage.links.forEach(link => highlightLinks.add(link));
|
176
193
|
}
|
177
194
|
hoverNode = node || null;
|
178
195
|
})
|
@@ -202,12 +219,29 @@ export default class JekyllGraph {
|
|
202
219
|
Graph.height(el.offsetHeight);
|
203
220
|
}
|
204
221
|
);
|
222
|
+
|
223
|
+
this.graph = Graph;
|
205
224
|
});
|
206
225
|
}
|
207
226
|
|
208
227
|
// draw helpers
|
209
228
|
|
229
|
+
shiftNodeHeight(node) {
|
230
|
+
if (node.namespace !== 'root' && !this.shifted.includes(node)) {
|
231
|
+
const padding = 5;
|
232
|
+
let areSiblingsLeftEven = (this.numSiblingsLeft[node.parent] % 2) === 1;
|
233
|
+
let altrntr = areSiblingsLeftEven ? 1 : -1;
|
234
|
+
node.fy = node.fy + (altrntr * (this.numSiblingsLeft[node.parent] * padding));
|
235
|
+
this.numSiblingsLeft[node.parent] -= 1;
|
236
|
+
this.shifted.push(node);
|
237
|
+
}
|
238
|
+
}
|
239
|
+
|
210
240
|
nodePaint(node, ctx, hoverNode, hoverLink, gType) {
|
241
|
+
// todo-shift: this shiftNodeHeight() animates more smoothly, but suffers from a race condition
|
242
|
+
// if (gType === "tree") {
|
243
|
+
// this.shiftNodeHeight(node);
|
244
|
+
// }
|
211
245
|
let fillText = true;
|
212
246
|
let radius = 6;
|
213
247
|
//
|
@@ -216,7 +250,7 @@ export default class JekyllGraph {
|
|
216
250
|
if (this.isVisitedPage(node)) {
|
217
251
|
ctx.fillStyle = getComputedStyle(document.documentElement).getPropertyValue('--graph-node-visited-color');
|
218
252
|
} else if (this.isMissingPage(node)) {
|
219
|
-
ctx.fillStyle = getComputedStyle(document.documentElement).getPropertyValue('--graph-node-missing-color')
|
253
|
+
ctx.fillStyle = getComputedStyle(document.documentElement).getPropertyValue('--graph-node-missing-color');
|
220
254
|
} else if (!this.isVisitedPage(node) && !this.isMissingPage(node)) {
|
221
255
|
ctx.fillStyle = getComputedStyle(document.documentElement).getPropertyValue('--graph-node-unvisited-color');
|
222
256
|
} else {
|
@@ -235,9 +269,9 @@ export default class JekyllGraph {
|
|
235
269
|
} else if (hoverNode !== null && gType === "net-web" && !hoverNode.neighbors.nodes.includes(node)) {
|
236
270
|
// non-neighbor to hoverNode
|
237
271
|
fillText = false;
|
238
|
-
} else if (hoverNode !== null && gType === "tree" && hoverNode.
|
272
|
+
} else if (hoverNode !== null && gType === "tree" && hoverNode.lineage.nodes.includes(node)) {
|
239
273
|
// neighbor to hoverNode
|
240
|
-
} else if (hoverNode !== null && gType === "tree" && !hoverNode.
|
274
|
+
} else if (hoverNode !== null && gType === "tree" && !hoverNode.lineage.nodes.includes(node)) {
|
241
275
|
// non-neighbor to hoverNode
|
242
276
|
fillText = false;
|
243
277
|
} else if ((hoverNode === null && hoverLink !== null) && (hoverLink.source === node || hoverLink.target === node)) {
|
@@ -255,11 +289,11 @@ export default class JekyllGraph {
|
|
255
289
|
//
|
256
290
|
if (this.isCurrentPage(node)) {
|
257
291
|
// turn glow on
|
258
|
-
ctx.shadowBlur =
|
292
|
+
ctx.shadowBlur = 40;
|
259
293
|
ctx.shadowColor = getComputedStyle(document.documentElement).getPropertyValue('--graph-node-current-glow');
|
260
294
|
} else if (this.isTag(node)) {
|
261
295
|
// turn glow on
|
262
|
-
ctx.shadowBlur =
|
296
|
+
ctx.shadowBlur = 40;
|
263
297
|
ctx.shadowColor = getComputedStyle(document.documentElement).getPropertyValue('--graph-node-tagged-glow');
|
264
298
|
} else if (this.isVisitedPage(node)) {
|
265
299
|
// turn glow on
|
data/lib/jekyll-graph/tags.rb
CHANGED
data/lib/jekyll-graph/version.rb
CHANGED
data/lib/jekyll-graph.rb
CHANGED
@@ -15,7 +15,7 @@ Jekyll::Hooks.register :site, :after_init do |site|
|
|
15
15
|
end
|
16
16
|
|
17
17
|
require_relative "jekyll-graph/tags"
|
18
|
-
Liquid::Template.register_tag "
|
18
|
+
Liquid::Template.register_tag "jekyll_graph", Jekyll::Graph::HeadTag
|
19
19
|
Liquid::Template.register_tag "graph_scripts", Jekyll::Graph::GraphScriptTag
|
20
20
|
|
21
21
|
module Jekyll
|
@@ -30,13 +30,14 @@ module Jekyll
|
|
30
30
|
CONVERTER_CLASS = Jekyll::Converters::Markdown
|
31
31
|
|
32
32
|
def generate(site)
|
33
|
+
# check what's enabled
|
33
34
|
return if $graph_conf.disabled?
|
34
|
-
if !$graph_conf.disabled_net_web? && site.link_index
|
35
|
-
Jekyll.logger.error("To generate the net-web graph, please add and enable the 'jekyll-wikilinks' plugin")
|
35
|
+
if !$graph_conf.disabled_net_web? && !site.respond_to?(:link_index)
|
36
|
+
Jekyll.logger.error("Jekyll-Graph: To generate the net-web graph, please either add and enable the 'jekyll-wikilinks' plugin or disable the net-web in the jekyll-graph config")
|
36
37
|
return
|
37
38
|
end
|
38
|
-
if !$graph_conf.disabled_tree? && site.tree
|
39
|
-
Jekyll.logger.error("To generate the tree graph, please add and enable the 'jekyll-namespaces' plugin")
|
39
|
+
if !$graph_conf.disabled_tree? && !site.respond_to?(:tree)
|
40
|
+
Jekyll.logger.error("Jekyll-Graph: To generate the tree graph, please either add and enable the 'jekyll-namespaces' plugin or disable the tree in the jekyll-graph config")
|
40
41
|
return
|
41
42
|
end
|
42
43
|
|
@@ -50,7 +51,7 @@ module Jekyll
|
|
50
51
|
docs += @site.docs_to_write.filter { |d| !$graph_conf.excluded?(d.type) }
|
51
52
|
@md_docs = docs.filter { |doc| markdown_extension?(doc.extname) }
|
52
53
|
if @md_docs.empty?
|
53
|
-
Jekyll.logger.
|
54
|
+
Jekyll.logger.warn("Jekyll-Graph: No documents to process.")
|
54
55
|
end
|
55
56
|
|
56
57
|
# write graph
|
@@ -64,25 +65,23 @@ module Jekyll
|
|
64
65
|
)
|
65
66
|
# create json file
|
66
67
|
json_net_web_graph_file = self.new_page($graph_conf.path_assets, "graph-net-web.json", net_web_graph_content)
|
67
|
-
self.register_static_file(json_net_web_graph_file)
|
68
68
|
end
|
69
69
|
if !$graph_conf.disabled_tree?
|
70
70
|
# generate json data
|
71
71
|
json_tree_nodes, json_tree_links = self.generate_json_tree(@site.tree.root)
|
72
|
-
self.
|
72
|
+
self.set_lineage(json_tree_nodes, json_tree_links)
|
73
73
|
tree_graph_content = JSON.dump(
|
74
74
|
nodes: json_tree_nodes,
|
75
75
|
links: json_tree_links,
|
76
76
|
)
|
77
77
|
# create json file
|
78
78
|
json_tree_graph_file = self.new_page($graph_conf.path_assets, "graph-tree.json", tree_graph_content)
|
79
|
-
self.register_static_file(json_tree_graph_file)
|
80
79
|
end
|
81
80
|
# add graph drawing scripts
|
82
81
|
script_filename = "jekyll-graph.js"
|
83
82
|
graph_script_content = File.read(source_path(script_filename))
|
83
|
+
# create js file
|
84
84
|
static_file = self.new_page($graph_conf.path_scripts, script_filename, graph_script_content)
|
85
|
-
self.register_static_file(static_file)
|
86
85
|
end
|
87
86
|
|
88
87
|
# helpers
|
@@ -116,13 +115,12 @@ module Jekyll
|
|
116
115
|
return new_file
|
117
116
|
end
|
118
117
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
end
|
118
|
+
# keeping this around in case it's needed again
|
119
|
+
# # tests fail without manually adding the static file, but actual site builds seem to do ok
|
120
|
+
# # ...although there does seem to be a race condition which causes a rebuild to be necessary in order to detect the graph data file
|
121
|
+
# def register_static_file(static_file)
|
122
|
+
# @site.static_files << static_file if !@site.static_files.include?(static_file)
|
123
|
+
# end
|
126
124
|
|
127
125
|
# json population helpers
|
128
126
|
# set ids here, full javascript objects are populated in client-side javascript.
|
@@ -140,18 +138,24 @@ module Jekyll
|
|
140
138
|
end
|
141
139
|
end
|
142
140
|
|
143
|
-
def
|
141
|
+
def set_lineage(json_nodes, json_links)
|
144
142
|
# TODO: json nodes have relative_url, but node.id's/urls are doc urls.
|
145
143
|
json_nodes.each do |json_node|
|
146
|
-
|
147
|
-
|
148
|
-
json_node[:
|
144
|
+
# set lineage
|
145
|
+
|
146
|
+
ancestor_node_ids, descendent_node_ids = @site.tree.get_all_lineage_ids(json_node[:id])
|
147
|
+
lineage_node_ids = ancestor_node_ids.concat(descendent_node_ids)
|
148
|
+
json_node[:lineage][:nodes] = lineage_node_ids if !lineage_node_ids.nil?
|
149
149
|
|
150
150
|
# include current node when filtering for links along entire relative lineage
|
151
|
-
lineage_ids =
|
151
|
+
lineage_ids = lineage_node_ids.concat([json_node[:id]])
|
152
|
+
|
153
|
+
json_lineage_links = json_links.select { |l| lineage_ids.include?(l[:source]) && lineage_ids.include?(l[:target]) }
|
154
|
+
json_node[:lineage][:links] = json_lineage_links if !json_lineage_links.nil?
|
155
|
+
|
156
|
+
# set siblings
|
152
157
|
|
153
|
-
|
154
|
-
json_node[:relatives][:links] = json_relative_links if !json_relative_links.nil?
|
158
|
+
json_node[:siblings] = @site.tree.get_sibling_ids(json_node[:id])
|
155
159
|
end
|
156
160
|
end
|
157
161
|
|
@@ -163,14 +167,13 @@ module Jekyll
|
|
163
167
|
@md_docs.each do |doc|
|
164
168
|
if !$graph_conf.excluded?(doc.type)
|
165
169
|
|
166
|
-
Jekyll.logger.debug
|
170
|
+
Jekyll.logger.debug("Jekyll-Graph: Processing graph nodes for doc: ", doc.data['title'])
|
167
171
|
#
|
168
172
|
# missing nodes
|
169
173
|
#
|
170
174
|
@site.link_index.index[doc.url].missing.each do |missing_link_name|
|
171
175
|
if net_web_nodes.none? { |node| node[:id] == missing_link_name }
|
172
|
-
Jekyll.logger.warn
|
173
|
-
Jekyll.logger.warn " in: ", doc.data['title']
|
176
|
+
Jekyll.logger.warn("Jekyll-Graph: Net-Web node missing: #{missing_link_name}, in: #{doc.data['title']}")
|
174
177
|
net_web_nodes << {
|
175
178
|
id: missing_link_name, # an id is necessary for link targets
|
176
179
|
url: '',
|
@@ -200,10 +203,27 @@ module Jekyll
|
|
200
203
|
},
|
201
204
|
}
|
202
205
|
# TODO: this link calculation ends up with duplicates -- re-visit this later.
|
203
|
-
|
204
|
-
#
|
205
|
-
|
206
|
-
|
206
|
+
if $graph_conf.use_attrs?
|
207
|
+
@site.link_index.index[doc.url].attributes.each do |link| # link = { 'type' => str, 'urls' => [str, str, ...] }
|
208
|
+
# TODO: Header + Block-level wikilinks
|
209
|
+
link['urls'].each do |lu|
|
210
|
+
link_no_anchor = lu.match(/([^#]+)/i)[0]
|
211
|
+
link_no_baseurl = @site.baseurl.nil? ? link_no_anchor : link_no_anchor.gsub(@site.baseurl, "")
|
212
|
+
linked_doc = @md_docs.select{ |d| d.url == link_no_baseurl }
|
213
|
+
if !linked_doc.nil? && linked_doc.size == 1 && !$graph_conf.excluded?(linked_doc.first.type)
|
214
|
+
# TODO: add link['type'] to d3 graph
|
215
|
+
net_web_links << {
|
216
|
+
source: doc.url,
|
217
|
+
target: linked_doc.first.url,
|
218
|
+
}
|
219
|
+
end
|
220
|
+
end
|
221
|
+
end
|
222
|
+
end
|
223
|
+
if $graph_conf.use_links?
|
224
|
+
@site.link_index.index[doc.url].forelinks.each do |link| # link = { 'type' => str, 'url' => str }
|
225
|
+
# TODO: Header + Block-level wikilinks
|
226
|
+
link_no_anchor = link['url'].match(/([^#]+)/i)[0]
|
207
227
|
link_no_baseurl = @site.baseurl.nil? ? link_no_anchor : link_no_anchor.gsub(@site.baseurl, "")
|
208
228
|
linked_doc = @md_docs.select{ |d| d.url == link_no_baseurl }
|
209
229
|
if !linked_doc.nil? && linked_doc.size == 1 && !$graph_conf.excluded?(linked_doc.first.type)
|
@@ -215,19 +235,6 @@ module Jekyll
|
|
215
235
|
end
|
216
236
|
end
|
217
237
|
end
|
218
|
-
@site.link_index.index[doc.url].forelinks.each do |link| # link = { 'type' => str, 'url' => str }
|
219
|
-
# TODO: Header + Block-level wikilinks
|
220
|
-
link_no_anchor = link['url'].match(/([^#]+)/i)[0]
|
221
|
-
link_no_baseurl = @site.baseurl.nil? ? link_no_anchor : link_no_anchor.gsub(@site.baseurl, "")
|
222
|
-
linked_doc = @md_docs.select{ |d| d.url == link_no_baseurl }
|
223
|
-
if !linked_doc.nil? && linked_doc.size == 1 && !$graph_conf.excluded?(linked_doc.first.type)
|
224
|
-
# TODO: add link['type'] to d3 graph
|
225
|
-
net_web_links << {
|
226
|
-
source: doc.url,
|
227
|
-
target: linked_doc.first.url,
|
228
|
-
}
|
229
|
-
end
|
230
|
-
end
|
231
238
|
|
232
239
|
end
|
233
240
|
end
|
@@ -235,12 +242,12 @@ module Jekyll
|
|
235
242
|
return net_web_nodes, net_web_links
|
236
243
|
end
|
237
244
|
|
238
|
-
def generate_json_tree(node, json_parent="", tree_nodes=[], tree_links=[])
|
245
|
+
def generate_json_tree(node, json_parent="", tree_nodes=[], tree_links=[], level=0)
|
239
246
|
#
|
240
247
|
# missing nodes
|
241
248
|
#
|
242
249
|
if node.missing
|
243
|
-
Jekyll.logger.warn("Document for tree node missing: ", node.namespace)
|
250
|
+
Jekyll.logger.warn("Jekyll-Graph: Document for tree node missing: ", node.namespace)
|
244
251
|
|
245
252
|
leaf = node.namespace.split('.').pop()
|
246
253
|
missing_node = {
|
@@ -248,18 +255,22 @@ module Jekyll
|
|
248
255
|
label: leaf.gsub('-', ' '),
|
249
256
|
namespace: node.namespace,
|
250
257
|
url: "",
|
251
|
-
|
258
|
+
level: level,
|
259
|
+
lineage: {
|
252
260
|
nodes: [],
|
253
261
|
links: [],
|
254
262
|
},
|
263
|
+
siblings: [],
|
255
264
|
}
|
256
|
-
|
265
|
+
# non-root handling
|
257
266
|
if !json_parent.empty?
|
267
|
+
missing_node[:parent] = json_parent[:id]
|
258
268
|
tree_links << {
|
259
269
|
source: json_parent[:id],
|
260
270
|
target: node.namespace,
|
261
271
|
}
|
262
272
|
end
|
273
|
+
tree_nodes << missing_node
|
263
274
|
json_parent = missing_node
|
264
275
|
#
|
265
276
|
# existing nodes
|
@@ -270,22 +281,26 @@ module Jekyll
|
|
270
281
|
label: node.title,
|
271
282
|
namespace: node.namespace,
|
272
283
|
url: relative_url(node.url),
|
273
|
-
|
284
|
+
level: level,
|
285
|
+
lineage: {
|
274
286
|
nodes: [],
|
275
287
|
links: [],
|
276
288
|
},
|
289
|
+
siblings: [],
|
277
290
|
}
|
278
|
-
|
291
|
+
# non-root handling
|
279
292
|
if !json_parent.empty?
|
293
|
+
existing_node[:parent] = json_parent[:id]
|
280
294
|
tree_links << {
|
281
295
|
source: json_parent[:id],
|
282
296
|
target: node.url,
|
283
297
|
}
|
284
298
|
end
|
299
|
+
tree_nodes << existing_node
|
285
300
|
json_parent = existing_node
|
286
301
|
end
|
287
302
|
node.children.each do |child|
|
288
|
-
self.generate_json_tree(child, json_parent, tree_nodes, tree_links)
|
303
|
+
self.generate_json_tree(child, json_parent, tree_nodes, tree_links, (level + 1))
|
289
304
|
end
|
290
305
|
return tree_nodes, tree_links
|
291
306
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jekyll-graph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- manunamz
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: jekyll-namespaces
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.0.
|
19
|
+
version: 0.0.3
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.0.
|
26
|
+
version: 0.0.3
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: jekyll-wikilinks
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.0.
|
33
|
+
version: 0.0.8
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.0.
|
40
|
+
version: 0.0.8
|
41
41
|
description:
|
42
42
|
email:
|
43
43
|
- manunamz@pm.me
|
@@ -65,7 +65,8 @@ files:
|
|
65
65
|
- lib/jekyll-graph/tags.rb
|
66
66
|
- lib/jekyll-graph/version.rb
|
67
67
|
homepage: https://github.com/manunamz/jekyll-graph
|
68
|
-
licenses:
|
68
|
+
licenses:
|
69
|
+
- GPL3
|
69
70
|
metadata:
|
70
71
|
homepage_uri: https://github.com/manunamz/jekyll-graph
|
71
72
|
source_code_uri: https://github.com/manunamz/jekyll-graph
|
@@ -85,7 +86,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
86
|
- !ruby/object:Gem::Version
|
86
87
|
version: '0'
|
87
88
|
requirements: []
|
88
|
-
rubygems_version: 3.2.
|
89
|
+
rubygems_version: 3.2.27
|
89
90
|
signing_key:
|
90
91
|
specification_version: 4
|
91
92
|
summary: Add d3 graph generation to jekyll.
|