rubrowser 2.4.0 → 2.5.0

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: 1b96b57265b40b9d6be08133f053972d10052ba5f1e977a24d6c0ffb14aa0e5c
4
- data.tar.gz: 47438b460b1f3276bc21c9f80ec3b95b34771a498c0601c8c85a4ceb5acc7912
3
+ metadata.gz: e67fd969c9155da49e88d2cc1fd703ac364064841a3800ad03c70bc7c922bfc7
4
+ data.tar.gz: 478c3f44d920a685109f24630e17658f3854adc3db675596baa285e4ec8e4538
5
5
  SHA512:
6
- metadata.gz: c6260b25527525ec6d2a67c8c691b681f24ba03cbff1630bfb631ded4f09ea73f129c3727d4501343b2d18f38318903f1ae99900c342b51a9cfcbd0842d676e9
7
- data.tar.gz: 887c3e30156229cfac868468020ca48a47fc1d72358b44554341a4f19f732c92317fe5df02e6056bd765ae3c41306e3ebc19b51588915046f87b1073371e5018
6
+ metadata.gz: 454bcb581e7fa255cce469d2b82f4321aa0d9f2cf127d2439a99ab437836028587d05a75214b224e1930c971c8b93739aa85838f1a3588658c3909c9d7c84d50
7
+ data.tar.gz: 5281d603a1ab859d8609fb05a04ecb63b923beb65977e89ce628a8e6716d17c817eae2ec43e53496f377d348aced37f923374022cf9b5540191157a332bc0f25
@@ -0,0 +1 @@
1
+ [{"id":"Rubrowser::Data","x":905.0088057752334,"y":437.04147016200284},{"id":"Rubrowser","x":712.6220053486966,"y":770.3251873644217},{"id":"Rubrowser::Formatter::JSON","x":1114.4368770370438,"y":560.0312580369882},{"id":"Rubrowser::Formatter","x":1113.6584254066838,"y":601.6487084046246},{"id":"Graph","x":1115.7752854976002,"y":436.6211350242928},{"id":"Rubrowser::Parser::Definition::Base","x":-8.218934126737395,"y":322.74585638398685},{"id":"Rubrowser::Parser::Definition","x":-191.1839782278871,"y":318.6377197576412},{"id":"Rubrowser::Parser","x":713.688310910547,"y":660.9646559993857},{"id":"Rubrowser::Parser::Definition::Class","x":186.15033111747857,"y":246.30753307276427},{"id":"Rubrowser::Parser::Definition::Module","x":188.36911863082037,"y":324.35744429623855},{"id":"Rubrowser::Parser::Directory","x":786.9998045114313,"y":239.74214301898786},{"id":"Rubrowser::Parser::Factory","x":788.0050388528484,"y":325.70343641742613},{"id":"Rubrowser::Parser::File::Builder","x":506.8969046429671,"y":189.48025894394402},{"id":"Rubrowser::Parser::File","x":505.82216034587793,"y":322.6733725221146},{"id":"Rubrowser::Parser::Relation::Base","x":185.12905462589924,"y":402.5519743127113},{"id":"Rubrowser::Parser::Relation","x":187.0097719718301,"y":461.8654698954514},{"id":"Rubrowser::Renderer","x":905.2158605930458,"y":560.8807631671766}]
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rubrowser (2.4.0)
4
+ rubrowser (2.5.0)
5
5
  parser (~> 2.3, >= 2.3.0)
6
6
 
7
7
  GEM
@@ -1,3 +1,3 @@
1
1
  module Rubrowser
2
- VERSION = '2.4.0'.freeze
2
+ VERSION = '2.5.0'.freeze
3
3
  end
@@ -40,15 +40,21 @@ text.type{
40
40
  opacity: 0.1;
41
41
  }
42
42
 
43
- .type_ignored, .name_ignored{
43
+ .ignored{
44
44
  display: none;
45
45
  }
46
46
 
47
- .highlighted, .name_highlighted, .type_highlighted{
47
+ .highlighted,
48
+ .highlighted_by_namespace,
49
+ .highlighted_by_path,
50
+ .highlighted_by_type{
48
51
  fill: #008ef3;
49
52
  }
50
53
 
51
- .highlighted circle, .name_highlighted circle, .type_highlighted circle{
54
+ .highlighted circle,
55
+ .highlighted_by_namespace circle,
56
+ .highlighted_by_path circle,
57
+ .highlighted_by_type circle{
52
58
  stroke: #008ef3;
53
59
  }
54
60
 
@@ -10,13 +10,22 @@ var svg = d3.select(".dependency_graph svg"),
10
10
  .on("start", dragstarted)
11
11
  .on("drag", dragged)
12
12
  .on("end", dragended),
13
- dup_definitions = data.definitions.map(function(d){ return {id: d.namespace, type: d.type, lines: d.lines, circular: d.circular }; }),
13
+ dup_definitions = data.definitions.map(function(d){
14
+ return {
15
+ id: d.namespace,
16
+ file: d.file,
17
+ type: d.type,
18
+ lines: d.lines,
19
+ circular: d.circular
20
+ };
21
+ }),
14
22
  definitions = _(dup_definitions).groupBy('id').map(function(group) {
15
23
  return {
16
24
  id: group[0].id,
17
25
  type: group[0].type,
18
26
  lines: _(group).sumBy('lines'),
19
- circular: group[0].circular
27
+ circular: group[0].circular,
28
+ files: group.map(function(d){ return d.file; })
20
29
  };
21
30
  }).value(),
22
31
  namespaces = definitions.map(function(d){ return d.id; }),
@@ -51,11 +51,25 @@ rubrowser.node.on('click', function(d){
51
51
  // --------------------------------
52
52
  $(document).on('change', '#highlight_by_namespace', function(){
53
53
  var highlights_entries = $(this).val().trim();
54
- var highlights = highlights_entries.split("\n");
54
+ var highlights = _(highlights_entries.split("\n"));
55
55
 
56
- rubrowser.node.classed('name_highlighted', function(d){
56
+ rubrowser.node.classed('highlighted_by_namespace', function(d){
57
57
  if(highlights_entries.length == 0){ return false; }
58
- return highlights.filter(function(i){ return d.id.indexOf(i) > -1; }).length > 0;
58
+ return highlights.some(function(i){ return d.id.indexOf(i) > -1; });
59
+ });
60
+ });
61
+
62
+ $(document).on('change', '#highlight_by_file_path', function(){
63
+ var highlights_entries = $(this).val().trim();
64
+ var highlights = _(highlights_entries.split("\n"));
65
+
66
+ rubrowser.node.classed('highlighted_by_path', function(d){
67
+ if(highlights_entries.length == 0){ return false; }
68
+ return highlights.some(function(i){
69
+ return _(d.files).some(function(f) {
70
+ return f.indexOf(i) > -1;
71
+ });
72
+ });
59
73
  });
60
74
  });
61
75
 
@@ -63,7 +77,7 @@ $(document).on('change', '#highlight_modules, #highlight_classes', function(){
63
77
  var modules_highlighted = $('#highlight_modules').is(':checked'),
64
78
  classes_highlighted = $('#highlight_classes').is(':checked');
65
79
 
66
- rubrowser.node.classed('type_highlighted', function(d){
80
+ rubrowser.node.classed('highlighted_by_type', function(d){
67
81
  return (d.type == 'Module' && modules_highlighted) || (d.type == 'Class' && classes_highlighted);
68
82
  });
69
83
  });
@@ -71,51 +85,91 @@ $(document).on('change', '#highlight_modules, #highlight_classes', function(){
71
85
  // --------------------------------
72
86
  // Ignore Panel
73
87
  // --------------------------------
88
+ var ignoring_functions = {};
89
+
90
+ function updateNodes() {
91
+
92
+ function ignoreNode(d) {
93
+ return _(ignoring_functions).some(function(ignoring_function) {
94
+ return ignoring_function(d);
95
+ });
96
+ }
97
+
98
+ function notIgnoreNode(d){
99
+ return !ignoreNode(d);
100
+ }
101
+ function ignoreRelation(r){
102
+ return ignoreNode(r.source) || ignoreNode(r.target);
103
+ }
104
+
105
+ function notIgnoreRelation(r){
106
+ return !ignoreRelation(r);
107
+ }
108
+
109
+ var filtered_definitions = rubrowser.definitions.filter(notIgnoreNode);
110
+ rubrowser.simulation.nodes(filtered_definitions);
111
+ rubrowser.node.classed('ignored', ignoreNode);
112
+
113
+ var filtered_relations = rubrowser.relations.filter(notIgnoreRelation);
114
+ rubrowser.simulation.force("link").links(filtered_relations);
115
+ rubrowser.link.classed('ignored', ignoreRelation);
116
+ }
117
+
74
118
  $(document).on('change', '#ignore_by_namespace', function(){
75
119
  var ignores_entries = $(this).val().trim();
76
120
  var ignores = ignores_entries.split("\n");
77
121
 
78
- // filtering definitions
79
- var filtered_definitions = rubrowser.definitions.filter(function(d){
80
- if(ignores_entries.length == 0){ return true; }
81
- return ignores.filter(function(i){ return d.id.indexOf(i) > -1; }).length == 0;
82
- })
83
-
84
- rubrowser.simulation
85
- .nodes(filtered_definitions)
122
+ if(ignores_entries.length == 0){
123
+ delete ignoring_functions["ignore_by_name"];
124
+ }else{
125
+ ignoring_functions["ignore_by_name"] = function(d){
126
+ return ignores.some(function(i){ return d.id.indexOf(i) > -1; });
127
+ }
128
+ }
86
129
 
87
- rubrowser.node.classed('name_ignored', function(d){
88
- if(ignores_entries.length == 0){ return false; }
89
- return ignores.filter(function(i){ return d.id.indexOf(i) > -1; }).length > 0;
90
- });
130
+ updateNodes();
131
+ });
91
132
 
92
- // filtering relations
93
- var filtered_relations = rubrowser.relations.filter(function(d){
94
- if(ignores_entries.length == 0){ return true; }
95
- return ignores.filter(function(i){ return d.source.id.indexOf(i) > -1 || d.target.id.indexOf(i) > -1; }).length == 0;
96
- })
133
+ $(document).on('change', '#ignore_by_file_path', function(){
134
+ var ignores_entries = $(this).val().trim();
135
+ var ignores = ignores_entries.split("\n");
97
136
 
98
- rubrowser.simulation
99
- .force("link")
100
- .links(filtered_relations);
137
+ if(ignores_entries.length == 0){
138
+ delete ignoring_functions["ignore_by_file_path"];
139
+ }else{
140
+ ignoring_functions["ignore_by_file_path"] = function(d){
141
+ return ignores.some(function(i){
142
+ return _(d.files).every(function(f){
143
+ return f.indexOf(i) > -1;
144
+ });
145
+ });
146
+ }
147
+ }
101
148
 
102
- rubrowser.link.classed('name_ignored', function(d){
103
- if(ignores_entries.length == 0){ return false; }
104
- return ignores.filter(function(i){ return d.source.id.indexOf(i) > -1 || d.target.id.indexOf(i) > -1; }).length > 0;
105
- });
149
+ updateNodes();
106
150
  });
107
151
 
108
152
  $(document).on('change', '#ignore_modules, #ignore_classes', function(){
109
153
  var modules_ignored = $('#ignore_modules').is(':checked'),
110
154
  classes_ignored = $('#ignore_classes').is(':checked');
111
155
 
112
- rubrowser.node.classed('type_ignored', function(d){
113
- return (d.type == 'Module' && modules_ignored) || (d.type == 'Class' && classes_ignored);
114
- });
115
- rubrowser.link.classed('type_ignored', function(d){
116
- return ((d.source.type == 'Module' && modules_ignored) || (d.source.type == 'Class' && classes_ignored)) ||
117
- ((d.target.type == 'Module' && modules_ignored) || (d.target.type == 'Class' && classes_ignored));
118
- });
156
+ if( modules_ignored ){
157
+ ignoring_functions["ignore_modules"] = function(d) {
158
+ return d.type == 'Module';
159
+ }
160
+ }else{
161
+ delete ignoring_functions["ignore_modules"];
162
+ }
163
+
164
+ if( classes_ignored ){
165
+ ignoring_functions["ignore_classes"] = function(d) {
166
+ return d.type == 'Class';
167
+ }
168
+ }else{
169
+ delete ignoring_functions["ignore_classes"];
170
+ }
171
+
172
+ updateNodes();
119
173
  });
120
174
 
121
175
  // --------------------------------
@@ -140,6 +194,22 @@ $(document).on('click', "#pause_simulation", function(){
140
194
  rubrowser.simulation.stop();
141
195
  });
142
196
 
197
+ $(document).on('click', "#fix_all", function(){
198
+ rubrowser.node.classed("fixed", true);
199
+ rubrowser.node.each(function(d){
200
+ d.fx = d.x;
201
+ d.fy = d.y;
202
+ });
203
+ });
204
+
205
+ $(document).on('click', "#release_all", function(){
206
+ rubrowser.node.classed("fixed", false);
207
+ rubrowser.node.each(function(d){
208
+ delete d["fx"];
209
+ delete d["fy"];
210
+ });
211
+ });
212
+
143
213
  $(document).on('click', "#download_layout", function(){
144
214
  var json = JSON.stringify(rubrowser.state.get());
145
215
  var element = document.createElement('a');
data/readme.md CHANGED
@@ -17,7 +17,7 @@ documentation
17
17
 
18
18
  this project is so small that the visualization looks like so
19
19
 
20
- ![rubrowser visualization](http://i.imgur.com/5mbshee.png)
20
+ ![rubrowser visualization](https://i.imgur.com/2tWrl2s.png)
21
21
 
22
22
  the idea is that the project opens every `.rb` file and parse it with `parser`
23
23
  gem then list all modules and classes definitions, and all constants that are
@@ -63,12 +63,37 @@ if you run it without any options
63
63
  ```
64
64
  rubrowser
65
65
  ```
66
- it'll analyze the current directory and print out an HTML file, so you can write it to a file, and open it in your browser
66
+
67
+ it'll analyze the current directory and print out an HTML file, so you can write
68
+ it to a file, and open it in your browser
67
69
 
68
70
  ```
69
71
  rubrowser > output.html
70
72
  ```
71
73
 
74
+ ## Using a saved layout
75
+
76
+ When you move classes/modules in the graph to fix them in one place, then you
77
+ refresh the page, you'll reset the graph again.
78
+
79
+ for that reason there is a button to download the current graph state as json file (fixed
80
+ nodes positions), when you generate the graph again you can pass that file to
81
+ rubrowser to embed it inside the output HTML file.
82
+
83
+ ```
84
+ rubrowser -l layout.json
85
+ ```
86
+
87
+ I recommend putting that file in your project and name it `.rubrowser` in that
88
+ case it'll be easy to use it whenever you generate the graph.
89
+
90
+ ```
91
+ rubrowser -l .rubrowser
92
+ ```
93
+
94
+ So that in the future probably rubrowser can pick the file automatically, if you
95
+ follow that naming, your project will be ready in that case.
96
+
72
97
  ## Features
73
98
 
74
99
  * interactive graph, you can pull any node to fix it to some position
@@ -76,16 +101,21 @@ rubrowser > output.html
76
101
  * zoom and pan with mouse or touch pad
77
102
  * highlight node and all related nodes, it'll make it easier for you to see what
78
103
  depends and dependencies of certain class
79
- * ignore node by name
104
+ * highlight nodes by names or file path
105
+ * ignore node by name, or file path
80
106
  * ignore nodes of certain type (modules/classes)
81
107
  * hide namespaces
82
108
  * hide relations
83
109
  * change graph appearance (collision radius)
84
110
  * stop animation immediately
111
+ * fix all nodes in position or release all fixed nodes
85
112
  * Module/class circle size on the graph will be relative to module number of
86
113
  lines in your code
87
114
  * cyclical dependencies are marked in red
88
- * after you move nodes around, you can download the layout as a file, then provide it when generating the graph file again with `-l file.json` it will embed the layout in the file and the graph will have the same layout by default.
115
+ * after you move nodes around, you can download the layout as a file, then
116
+ provide it when generating the graph file again with `-l file.json` it will
117
+ embed the layout in the file and the graph will have the same layout by
118
+ default.
89
119
 
90
120
  ## Why?
91
121
 
@@ -1,16 +1,20 @@
1
1
  <div class="toolbox">
2
- <div class="card mt-2">
2
+ <div class="card ml-2 mt-2">
3
3
  <div class="card-header">Node Details</div>
4
4
  <div class="card-body" id="information_panel">
5
5
  Please click on any node.
6
6
  </div>
7
7
  </div>
8
- <div class="card mt-2">
8
+ <div class="card ml-2 mt-2">
9
9
  <div class="card-header">Search</div>
10
10
  <div class="card-body">
11
11
  <label class="form-label">Namespace</label>
12
12
  <textarea id="highlight_by_namespace" class="form-control" rows="5"></textarea>
13
13
  </div>
14
+ <div class="card-body">
15
+ <label class="form-label">File Path</label>
16
+ <textarea id="highlight_by_file_path" class="form-control" rows="5"></textarea>
17
+ </div>
14
18
  <div class="card-body">
15
19
  <div class="form-check">
16
20
  <input type="checkbox" class="form-check-input" id="highlight_modules"/>
@@ -22,12 +26,16 @@
22
26
  </div>
23
27
  </div>
24
28
  </div>
25
- <div class="card mt-2">
29
+ <div class="card ml-2 mt-2">
26
30
  <div class="card-header">Ignore</div>
27
31
  <div class="card-body">
28
32
  <label>Namespace</label>
29
33
  <textarea id="ignore_by_namespace" class="form-control" rows="5"></textarea>
30
34
  </div>
35
+ <div class="card-body">
36
+ <label>File Path</label>
37
+ <textarea id="ignore_by_file_path" class="form-control" rows="5"></textarea>
38
+ </div>
31
39
  <div class="card-body">
32
40
  <div class="form-check">
33
41
  <input type="checkbox" class="form-check-input" id="ignore_modules"/>
@@ -39,11 +47,13 @@
39
47
  </div>
40
48
  </div>
41
49
  </div>
42
- <div class="card mt-2">
50
+ <div class="card ml-2 mt-2">
43
51
  <div class="card-header">Display</div>
44
52
  <div class="card-body">
45
53
  <button type="button" id="download_layout" class="btn btn-secondary btn-block">Download layout</button>
46
54
  <button type="button" id="pause_simulation" class="btn btn-secondary btn-block">Pause animation</button>
55
+ <button type="button" id="fix_all" class="btn btn-secondary btn-block">Fix all</button>
56
+ <button type="button" id="release_all" class="btn btn-secondary btn-block">Release all</button>
47
57
  </div>
48
58
  <div class="card-body">
49
59
  <label class="form-label">Force Collide</label>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rubrowser
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.0
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emad Elsaid
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-02-03 00:00:00.000000000 Z
11
+ date: 2018-02-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -112,6 +112,7 @@ files:
112
112
  - ".hound.yml"
113
113
  - ".rspec"
114
114
  - ".rubocop.yml"
115
+ - ".rubrowser"
115
116
  - Gemfile
116
117
  - Gemfile.lock
117
118
  - MIT-LICENSE