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 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.