rubrowser 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +1 -1
- data/lib/rubrowser.rb +1 -1
- data/public/css/application.css +77 -0
- data/public/javascript/application.js +22 -18
- data/public/javascript/toolbox.js +77 -0
- data/readme.md +3 -1
- data/views/index.erb +32 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c73af6e853cf9a9ccbfecd66f87167be4f6437a2
|
4
|
+
data.tar.gz: 644e9a8d84252da3aeb417c52cdc37ac5c598d1f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3fee22947295cf8a8aa168c63edf91f6c19d91ed967fac419d5371ab5a6970694a9f9ec039a3f3244218f8a15a2d05c5ad8ea6d1bd6e6c04bff4ece7f3089e9
|
7
|
+
data.tar.gz: f1a827ac8faf66d3609ac2f52cf54508d856b053c1950fb427c9ff4b3ef3886ab319b8f74d114d425aad18b66f9c599b722658e67f9a3ac3a067ffd4bb377b55
|
data/Gemfile.lock
CHANGED
data/lib/rubrowser.rb
CHANGED
data/public/css/application.css
CHANGED
@@ -39,4 +39,81 @@ text {
|
|
39
39
|
|
40
40
|
text.type{
|
41
41
|
font: 7px sans-serif;
|
42
|
+
}
|
43
|
+
|
44
|
+
.downlighted, .name_ignored, .type_ignored{
|
45
|
+
opacity: 0.1;
|
46
|
+
}
|
47
|
+
|
48
|
+
.highlighted, .name_highlighted, .type_highlighted{
|
49
|
+
fill: #008ef3;
|
50
|
+
}
|
51
|
+
|
52
|
+
.highlighted circle, .name_highlighted circle, .type_highlighted circle{
|
53
|
+
stroke: #008ef3;
|
54
|
+
}
|
55
|
+
|
56
|
+
.hide_namespace .namespace, .link.hide_relation{
|
57
|
+
display: none;
|
58
|
+
}
|
59
|
+
|
60
|
+
/* ============================ */
|
61
|
+
/* Toolbox style */
|
62
|
+
/* ============================ */
|
63
|
+
|
64
|
+
.toolbox{
|
65
|
+
position: fixed;
|
66
|
+
top: 0px;
|
67
|
+
left: 0px;
|
68
|
+
max-height: 100%;
|
69
|
+
width: 200px;
|
70
|
+
background: white;
|
71
|
+
border-right: 1px solid #ddd;
|
72
|
+
display: none;
|
73
|
+
overflow: auto;
|
74
|
+
}
|
75
|
+
|
76
|
+
.panel .title{
|
77
|
+
padding: 20px 10px;
|
78
|
+
font-weight: bold;
|
79
|
+
text-transform: uppercase;
|
80
|
+
cursor: pointer;
|
81
|
+
border-bottom: 1px solid #ddd;
|
82
|
+
-moz-user-select: none;
|
83
|
+
-khtml-user-select: none;
|
84
|
+
-webkit-user-select: none;
|
85
|
+
-ms-user-select: none;
|
86
|
+
user-select: none;
|
87
|
+
}
|
88
|
+
|
89
|
+
.panel .title:hover{
|
90
|
+
background: #eee;
|
91
|
+
}
|
92
|
+
|
93
|
+
.panel .content{
|
94
|
+
border-bottom: 1px solid #ddd;
|
95
|
+
padding: 5px;
|
96
|
+
}
|
97
|
+
|
98
|
+
.panel label{
|
99
|
+
display: block;
|
100
|
+
margin-top: 10px;
|
101
|
+
margin-bottom: 5px;
|
102
|
+
}
|
103
|
+
|
104
|
+
.panel textarea{
|
105
|
+
display: block;
|
106
|
+
width: 100%;
|
107
|
+
max-width: 100%;
|
108
|
+
height: 100px;
|
109
|
+
padding: 0px;
|
110
|
+
border: 1px solid #ddd
|
111
|
+
}
|
112
|
+
|
113
|
+
.panel input[type=button],
|
114
|
+
.panel input[type=range],
|
115
|
+
.panel button{
|
116
|
+
width: 100%;
|
117
|
+
max-width: 100%;
|
118
|
+
display: block;
|
42
119
|
}
|
@@ -1,6 +1,7 @@
|
|
1
1
|
d3.json("/data.json", function(error, data) {
|
2
2
|
parseGraph(data);
|
3
3
|
$('.loading').hide();
|
4
|
+
$('.toolbox').show();
|
4
5
|
});
|
5
6
|
|
6
7
|
var parseGraph = function(data){
|
@@ -12,8 +13,8 @@ var parseGraph = function(data){
|
|
12
13
|
.on("start", dragstarted)
|
13
14
|
.on("drag", dragged)
|
14
15
|
.on("end", dragended),
|
15
|
-
|
16
|
-
namespaces =
|
16
|
+
definitions = _.uniqWith(data.definitions.map(function(d){ return {id: d.namespace, type: d.type }; }), _.isEqual),
|
17
|
+
namespaces = definitions.map(function(d){ return d.id; }),
|
17
18
|
relations = data.relations.map(function(d){ return {source: d.caller, target: d.resolved_namespace }; });
|
18
19
|
|
19
20
|
relations = relations.filter(function(d){
|
@@ -34,10 +35,10 @@ var parseGraph = function(data){
|
|
34
35
|
.force("link", d3.forceLink().id(function(d) { return d.id; }))
|
35
36
|
.force("charge", d3.forceManyBody())
|
36
37
|
.force("center", d3.forceCenter(width / 2, height / 2))
|
37
|
-
.force("forceCollide", d3.forceCollide(
|
38
|
+
.force("forceCollide", d3.forceCollide(80));
|
38
39
|
|
39
40
|
simulation
|
40
|
-
.nodes(
|
41
|
+
.nodes(definitions)
|
41
42
|
.on("tick", ticked);
|
42
43
|
|
43
44
|
simulation.force("link")
|
@@ -53,7 +54,7 @@ var parseGraph = function(data){
|
|
53
54
|
node = container.append("g")
|
54
55
|
.attr("class", "nodes")
|
55
56
|
.selectAll("g")
|
56
|
-
.data(
|
57
|
+
.data(definitions)
|
57
58
|
.enter().append("g")
|
58
59
|
.call(drag)
|
59
60
|
.on("dblclick", dblclick),
|
@@ -68,6 +69,7 @@ var parseGraph = function(data){
|
|
68
69
|
.text(function(d) { return d.type[0]; }),
|
69
70
|
text = node
|
70
71
|
.append("text")
|
72
|
+
.attr("class", "namespace")
|
71
73
|
.attr("x", 8)
|
72
74
|
.attr("y", ".31em")
|
73
75
|
.text(function(d) { return d.id; });
|
@@ -126,29 +128,31 @@ var parseGraph = function(data){
|
|
126
128
|
|
127
129
|
node.on('mouseover', function(d) {
|
128
130
|
var relatives = [];
|
129
|
-
link.
|
131
|
+
link.classed('downlighted', function(l) {
|
130
132
|
if (d === l.source || d === l.target){
|
131
133
|
relatives.push(l.source);
|
132
134
|
relatives.push(l.target);
|
133
|
-
return
|
135
|
+
return false;
|
134
136
|
}else{
|
135
|
-
return
|
137
|
+
return true;
|
136
138
|
}
|
137
139
|
});
|
138
|
-
node.
|
139
|
-
|
140
|
-
return 1;
|
141
|
-
}else{
|
142
|
-
return 0.1;
|
143
|
-
}
|
140
|
+
node.classed('downlighted', function(n) {
|
141
|
+
return !(n == d || relatives.indexOf(n) > -1);
|
144
142
|
});
|
145
143
|
});
|
146
144
|
|
147
145
|
node.on('mouseout', function() {
|
148
|
-
link.
|
149
|
-
node.
|
146
|
+
link.classed('downlighted', false);
|
147
|
+
node.classed('downlighted', false);
|
150
148
|
});
|
151
149
|
|
152
|
-
|
153
|
-
|
150
|
+
window.rubrowser = {
|
151
|
+
data: data,
|
152
|
+
definitions: definitions,
|
153
|
+
relations: relations,
|
154
|
+
simulation: simulation,
|
155
|
+
node: node,
|
156
|
+
link: link
|
157
|
+
};
|
154
158
|
};
|
@@ -0,0 +1,77 @@
|
|
1
|
+
$(document).on('click', '.panel .title', function(){
|
2
|
+
$(this).siblings().toggle();
|
3
|
+
});
|
4
|
+
|
5
|
+
// --------------------------------
|
6
|
+
// Search Panel
|
7
|
+
// --------------------------------
|
8
|
+
$(document).on('change', '#highlight_by_namespace', function(){
|
9
|
+
var highlights_entries = $(this).val().trim();
|
10
|
+
var highlights = highlights_entries.split("\n");
|
11
|
+
|
12
|
+
rubrowser.node.classed('name_highlighted', function(d){
|
13
|
+
if(highlights_entries.length == 0){ return false; }
|
14
|
+
return highlights.filter(function(i){ return d.id.indexOf(i) > -1; }).length > 0;
|
15
|
+
});
|
16
|
+
});
|
17
|
+
|
18
|
+
$(document).on('change', '#highlight_modules, #highlight_classes', function(){
|
19
|
+
var modules_highlighted = $('#highlight_modules').is(':checked'),
|
20
|
+
classes_highlighted = $('#highlight_classes').is(':checked');
|
21
|
+
|
22
|
+
rubrowser.node.classed('type_highlighted', function(d){
|
23
|
+
return (d.type == 'Module' && modules_highlighted) || (d.type == 'Class' && classes_highlighted);
|
24
|
+
});
|
25
|
+
});
|
26
|
+
|
27
|
+
// --------------------------------
|
28
|
+
// Ignore Panel
|
29
|
+
// --------------------------------
|
30
|
+
$(document).on('change', '#ignore_by_namespace', function(){
|
31
|
+
var ignores_entries = $(this).val().trim();
|
32
|
+
var ignores = ignores_entries.split("\n");
|
33
|
+
|
34
|
+
rubrowser.node.classed('name_ignored', function(d){
|
35
|
+
if(ignores_entries.length == 0){ return false; }
|
36
|
+
return ignores.filter(function(i){ return d.id.indexOf(i) > -1; }).length > 0;
|
37
|
+
});
|
38
|
+
rubrowser.link.classed('name_ignored', function(d){
|
39
|
+
if(ignores_entries.length == 0){ return false; }
|
40
|
+
return ignores.filter(function(i){ return d.source.id.indexOf(i) > -1 || d.target.id.indexOf(i) > -1; }).length > 0;
|
41
|
+
});
|
42
|
+
});
|
43
|
+
|
44
|
+
$(document).on('change', '#ignore_modules, #ignore_classes', function(){
|
45
|
+
var modules_ignored = $('#ignore_modules').is(':checked'),
|
46
|
+
classes_ignored = $('#ignore_classes').is(':checked');
|
47
|
+
|
48
|
+
rubrowser.node.classed('type_ignored', function(d){
|
49
|
+
return (d.type == 'Module' && modules_ignored) || (d.type == 'Class' && classes_ignored);
|
50
|
+
});
|
51
|
+
rubrowser.link.classed('type_ignored', function(d){
|
52
|
+
return ((d.source.type == 'Module' && modules_ignored) || (d.source.type == 'Class' && classes_ignored)) ||
|
53
|
+
((d.target.type == 'Module' && modules_ignored) || (d.target.type == 'Class' && classes_ignored));
|
54
|
+
});
|
55
|
+
});
|
56
|
+
|
57
|
+
// --------------------------------
|
58
|
+
// Display Panel
|
59
|
+
// --------------------------------
|
60
|
+
$(document).on('change', "#force_collide", function(){
|
61
|
+
var new_value = $(this).val();
|
62
|
+
rubrowser.simulation.force("forceCollide", d3.forceCollide(new_value));
|
63
|
+
});
|
64
|
+
|
65
|
+
$(document).on('change', "#hide_relations", function(){
|
66
|
+
var hide_relations = $('#hide_relations').is(':checked');
|
67
|
+
rubrowser.link.classed("hide_relation", hide_relations);
|
68
|
+
});
|
69
|
+
|
70
|
+
$(document).on('change', "#hide_namespaces", function(){
|
71
|
+
var hide_namespaces = $('#hide_namespaces').is(':checked');
|
72
|
+
rubrowser.node.classed("hide_namespace", hide_namespaces);
|
73
|
+
});
|
74
|
+
|
75
|
+
$(document).on('click', "#pause_simulation", function(){
|
76
|
+
rubrowser.simulation.stop();
|
77
|
+
});
|
data/readme.md
CHANGED
@@ -6,7 +6,7 @@ a visualizer for ruby code (rails or otherwise), it analyze your code and extrac
|
|
6
6
|
|
7
7
|
this project is so small that the visualization looks like so
|
8
8
|
|
9
|
-
![rubrowser visualization](http://i.imgur.com/
|
9
|
+
![rubrowser visualization](http://i.imgur.com/5mbshee.png)
|
10
10
|
|
11
11
|
the idea is that the project opens every `.rb` file and parse it with `parser` gem then list all modules and classes definitions, and all constants that are listed inside this module/class and link them together.
|
12
12
|
|
@@ -54,6 +54,8 @@ it'll analyze the current directory and open port 9000, so you can access the gr
|
|
54
54
|
* to release node double click on it
|
55
55
|
* zoom and pan with mouse or touch pad
|
56
56
|
* highlight node and all related nodes, it'll make it easier for you to see what depends and dependencies of certain class
|
57
|
+
* ignore node by name
|
58
|
+
* ignore nodes of certain type (modules/classes)
|
57
59
|
|
58
60
|
|
59
61
|
## Tests?
|
data/views/index.erb
CHANGED
@@ -12,9 +12,41 @@
|
|
12
12
|
Parsing files...
|
13
13
|
</div>
|
14
14
|
</div>
|
15
|
+
<div class="toolbox">
|
16
|
+
<div class="panel">
|
17
|
+
<div class="title"> Search </div>
|
18
|
+
<div class="content">
|
19
|
+
<label>Namespace</label>
|
20
|
+
<textarea id="highlight_by_namespace"></textarea>
|
21
|
+
<label><input type="checkbox" id="highlight_modules"/> Modules</label>
|
22
|
+
<label><input type="checkbox" id="highlight_classes"/> Classes</label>
|
23
|
+
</div>
|
24
|
+
</div>
|
25
|
+
<div class="panel">
|
26
|
+
<div class="title"> Ignore </div>
|
27
|
+
<div class="content">
|
28
|
+
<label>Namespace</label>
|
29
|
+
<textarea id="ignore_by_namespace"></textarea>
|
30
|
+
<label><input type="checkbox" id="ignore_modules"/> Modules</label>
|
31
|
+
<label><input type="checkbox" id="ignore_classes"/> Classes</label>
|
32
|
+
</div>
|
33
|
+
</div>
|
34
|
+
<div class="panel">
|
35
|
+
<div class="title"> Display </div>
|
36
|
+
<div class="content">
|
37
|
+
<input type="button" id="pause_simulation" value="Pause animation"/>
|
38
|
+
<label>Force Collide</label>
|
39
|
+
<input id="force_collide" type="range" value="80" min="0" max="500"/>
|
40
|
+
<label><input type="checkbox" id="hide_namespaces"/> Hide namespaces</label>
|
41
|
+
<label><input type="checkbox" id="hide_relations"/> Hide relations</label>
|
42
|
+
</div>
|
43
|
+
</div>
|
44
|
+
</div>
|
45
|
+
|
15
46
|
<script src='/javascript/lodash.js' type='text/javascript'></script>
|
16
47
|
<script src='/javascript/d3.js' type='text/javascript'></script>
|
17
48
|
<script src='/javascript/jquery.js' type='text/javascript'></script>
|
18
49
|
<script src='/javascript/application.js' type='text/javascript'></script>
|
50
|
+
<script src='/javascript/toolbox.js' type='text/javascript'></script>
|
19
51
|
</body>
|
20
52
|
</html>
|
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: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Emad Elsaid
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-09-
|
11
|
+
date: 2016-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: parser
|
@@ -60,6 +60,7 @@ files:
|
|
60
60
|
- public/javascript/d3.js
|
61
61
|
- public/javascript/jquery.js
|
62
62
|
- public/javascript/lodash.js
|
63
|
+
- public/javascript/toolbox.js
|
63
64
|
- readme.md
|
64
65
|
- rubrowser.gemspec
|
65
66
|
- views/index.erb
|