jekyll-graph 0.0.1 → 0.0.5

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80f4df6c36b93f7bd1b6b30a351683ada9d0773e5399c8dca002e5ab7a952dbf
4
- data.tar.gz: 97a36f2a8c500da04f6d74ddc97249f79ea37bb0c61590f8f05dc4b1b662b4ff
3
+ metadata.gz: 16fc54d9f258c71e879a2b65b3d642e2c6ba0a30efaec85fb036941bffdf5c49
4
+ data.tar.gz: 052f0d8c7c64150116e7205f66f8d0052433713f0f012eac3ce229f9f48001fd
5
5
  SHA512:
6
- metadata.gz: 69b15e75ead4762b34f116f88221414961db6a18d504d574545d959b913431cf4738dd44eecabd6a35cf2eb47b5b50939920bf27c66b8ed553cbe211b58e1ec2
7
- data.tar.gz: 9caf1f36d76d631cc4b16310fd70fafceb6665dfd4ae33fd1ef28d2792ab15cb9d6ed4bbdba75ecc06ebd9e3cc66f34b5378b3a5836a72cd4ec878251316d21d
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.2"
10
- gem "jekyll-wikilinks", "~> 0.0.6"
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 `{% force_graph %}` to the site head:
17
+ 1. Add `{% jekyll_graph %}` to the site head:
18
18
 
19
19
  ```html
20
20
  <head>
21
21
 
22
22
  ...
23
23
 
24
- {% force_graph %}
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/scripts/`.
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
- ```yml
58
+ ```yaml
61
59
  graph:
62
60
  enabled: true
63
61
  exclude: []
64
- assets_path: "/assets"
65
- scripts_path: "/assets/js"
66
- tree:
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
- net_web:
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
- `assets_path`: Custom graph file location from the root of the generated `_site/` directory.
87
- `scripts_path`: Custom graph scripts location from the assets location of the generated `_site/` directory (If `assets_path` is set, but `scripts_path` is not, the location will default to `_site/<assets_path>/js/`).
88
- `tree.enabled` and `net_web.enabled`: Toggles on/off the `tree` and `net_web` graphs, respectively.
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": "<relative-url>", // site.baseurl wil be handled for you here
183
+ "url": "<lineage-url>", // site.baseurl wil be handled for you here
175
184
  "label": "<note's-title>",
176
- "relatives": {
177
- "nodes": [<relative-node>, ...],
178
- "links": [<relative-link>, ...],
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
@@ -2,7 +2,7 @@
2
2
  # frozen_string_literal: true
3
3
 
4
4
  require "bundler/setup"
5
- require "jekyll/graph"
5
+ require "jekyll-graph"
6
6
 
7
7
  # You can add fixtures and/or initialization code here to make experimenting
8
8
  # with your gem easier. You can also use a different console, if you like.
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.2"
38
- spec.add_runtime_dependency "jekyll-wikilinks", "~> 0.0.6"
38
+ spec.add_runtime_dependency "jekyll-namespaces", "~> 0.0.3"
39
+ spec.add_runtime_dependency "jekyll-wikilinks", "~> 0.0.8"
39
40
  end
@@ -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
- PATH_ASSETS_KEY = "assets_path"
13
- PATH_SCRIPTS_KEY = "scripts_path"
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
- # options
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 has_custom_write_path?
43
- return !!option(PATH_ASSETS_KEY)
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 !!option(PATH_SCRIPTS_KEY)
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 has_custom_write_path? ? option(PATH_ASSETS_KEY) : "/assets"
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? ? option(PATH_SCRIPTS_KEY) : File.join(path_assets, "js")
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.assets_path }}' !== '' ? '{{ site.graph.assets_path }}' : '/assets';
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
- const Graph = ForceGraph()
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.assets_path }}' !== '' ? '{{ site.graph.assets_path }}' : '/assets';
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
- // relatives: replace ids with full object
130
+ // lineage: replace ids with full objects
112
131
  data.nodes.forEach(node => {
132
+ // lineage
113
133
  let relativeNodes = [];
114
- node.relatives.nodes.forEach(nNodeId => {
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.relatives.links.forEach(nLink => {
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.relatives.nodes = relativeNodes;
122
- node.relatives.links = relativeLinks;
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 highlightNodes = new Set();
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.relatives.nodes.forEach(node => highlightNodes.add(node));
175
- node.relatives.links.forEach(link => highlightLinks.add(link));
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.relatives.nodes.includes(node)) {
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.relatives.nodes.includes(node)) {
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 = 30;
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 = 30;
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
@@ -3,7 +3,7 @@
3
3
  module Jekyll
4
4
  module Graph
5
5
 
6
- class ForceGraphTag < Liquid::Tag
6
+ class HeadTag < Liquid::Tag
7
7
  def render(context)
8
8
  [
9
9
  "<script src=\"//unpkg.com/element-resize-detector/dist/element-resize-detector.min.js\"></script>",
@@ -3,7 +3,7 @@
3
3
  module Jekyll
4
4
  module Graph
5
5
 
6
- VERSION = "0.0.1"
6
+ VERSION = "0.0.5"
7
7
 
8
8
  end
9
9
  end
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 "force_graph", Jekyll::Graph::ForceGraphTag
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.nil?
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.nil?
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.debug("No documents to process.")
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.set_relatives(json_tree_nodes, json_tree_links)
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
- def register_static_file(static_file)
120
- # tests fail without manually adding the static file, but actual site builds seem to do ok
121
- # ...although there does seem to be a race condition which causes a rebuild to be necessary in order to detect the graph data file
122
- if $graph_conf.testing
123
- @site.static_files << static_file if !@site.static_files.include?(static_file)
124
- end
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 set_relatives(json_nodes, json_links)
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
- ancestor_node_ids, descendent_node_ids = @site.tree.get_all_relative_ids(json_node[:id])
147
- relative_node_ids = ancestor_node_ids.concat(descendent_node_ids)
148
- json_node[:relatives][:nodes] = relative_node_ids if !relative_node_ids.nil?
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 = relative_node_ids.concat([json_node[:id]])
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
- json_relative_links = json_links.select { |l| lineage_ids.include?(l[:source]) && lineage_ids.include?(l[:target]) }
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 "Processing graph nodes for doc: ", doc.data['title']
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 "Net-Web node missing: ", missing_link_name
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
- @site.link_index.index[doc.url].attributes.each do |link| # link = { 'type' => str, 'urls' => [str, str, ...] }
204
- # TODO: Header + Block-level wikilinks
205
- link['urls'].each do |lu|
206
- link_no_anchor = lu.match(/([^#]+)/i)[0]
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
- relatives: {
258
+ level: level,
259
+ lineage: {
252
260
  nodes: [],
253
261
  links: [],
254
262
  },
263
+ siblings: [],
255
264
  }
256
- tree_nodes << missing_node
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
- relatives: {
284
+ level: level,
285
+ lineage: {
274
286
  nodes: [],
275
287
  links: [],
276
288
  },
289
+ siblings: [],
277
290
  }
278
- tree_nodes << existing_node
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.1
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-09-17 00:00:00.000000000 Z
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.2
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.2
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.6
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.6
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.17
89
+ rubygems_version: 3.2.27
89
90
  signing_key:
90
91
  specification_version: 4
91
92
  summary: Add d3 graph generation to jekyll.