rubrowser 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile.lock +2 -2
- data/bin/rubrowser +7 -1
- data/lib/rubrowser/renderer.rb +6 -0
- data/lib/rubrowser/version.rb +1 -1
- data/public/javascript/application.js +157 -162
- data/public/javascript/toolbox.js +35 -37
- data/readme.md +1 -0
- data/views/index.erb +5 -38
- data/views/toolbox.erb +36 -0
- metadata +3 -5
- data/public/javascript/d3.js +0 -16231
- data/public/javascript/jquery.js +0 -10074
- data/public/javascript/lodash.js +0 -17084
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a3f34361f8481fafacdbb4bda6020e92cc031e9e934e934935e36970164dd9f7
|
4
|
+
data.tar.gz: 5e8899befc1456be7326215551b081a061bd9156f754d409c64484bf6797113e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2df8b115f261a7bc09bfa296aeeb3b2db77f7f6e6e0bbd00673de377bb473c29e7c95458e42d02b4406a41262c114d3591e21fad96f5103676001989ef09551c
|
7
|
+
data.tar.gz: 752c00be5fb7b1b079895946de617967b2232d6a7f2ea830e118a2076b52d624f545bd6ddc91ebe93e884c536e30e8d1381b4e213fe0dc4b0f7b3e0bcb73d352
|
data/Gemfile.lock
CHANGED
data/bin/rubrowser
CHANGED
@@ -6,12 +6,16 @@ require 'rubrowser'
|
|
6
6
|
require 'rubrowser/renderer'
|
7
7
|
|
8
8
|
options = {
|
9
|
-
|
9
|
+
toolbox: true
|
10
10
|
}
|
11
11
|
|
12
12
|
OptionParser.new do |opts|
|
13
13
|
opts.banner = "Usage: #{__FILE__} [options] [file] ..."
|
14
14
|
|
15
|
+
opts.on('-T', '--no-toolbox', 'Don\'t display toolbox on the page') do
|
16
|
+
options[:toolbox] = false
|
17
|
+
end
|
18
|
+
|
15
19
|
opts.on('-v', '--version', 'Print Rubrowser version') do
|
16
20
|
puts "Rubrowser #{Rubrowser::VERSION}"
|
17
21
|
exit
|
@@ -23,4 +27,6 @@ OptionParser.new do |opts|
|
|
23
27
|
end
|
24
28
|
end.parse!
|
25
29
|
|
30
|
+
options[:files] = ARGV.empty? ? ['.'] : ARGV
|
31
|
+
|
26
32
|
puts Rubrowser::Renderer.call(options)
|
data/lib/rubrowser/renderer.rb
CHANGED
@@ -6,6 +6,7 @@ module Rubrowser
|
|
6
6
|
class Renderer
|
7
7
|
# Accepted options are:
|
8
8
|
# files: list of file paths to parse
|
9
|
+
# toolbox: bool, show/hide toolbox
|
9
10
|
def self.call(options = {})
|
10
11
|
new(options).call
|
11
12
|
end
|
@@ -22,6 +23,11 @@ module Rubrowser
|
|
22
23
|
|
23
24
|
def initialize(options)
|
24
25
|
@files = options[:files]
|
26
|
+
@toolbox = options[:toolbox]
|
27
|
+
end
|
28
|
+
|
29
|
+
def toolbox?
|
30
|
+
@toolbox
|
25
31
|
end
|
26
32
|
|
27
33
|
def data
|
data/lib/rubrowser/version.rb
CHANGED
@@ -2,169 +2,164 @@ var classForCircular = function(d) {
|
|
2
2
|
return d.circular ? 'circular' : '';
|
3
3
|
};
|
4
4
|
|
5
|
-
var
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
container.attr("transform", d3.event.transform);
|
36
|
-
});
|
37
|
-
|
38
|
-
svg.call(zoom)
|
39
|
-
.on("dblclick.zoom", null);
|
40
|
-
|
41
|
-
var container = svg.append('g'),
|
42
|
-
simulation = d3.forceSimulation()
|
43
|
-
.force("link", d3.forceLink().id(function(d) { return d.id; }))
|
44
|
-
.force("charge", d3.forceManyBody())
|
45
|
-
.force("center", d3.forceCenter(width / 2, height / 2))
|
46
|
-
.force("forceCollide", d3.forceCollide(80));
|
47
|
-
|
48
|
-
simulation
|
49
|
-
.nodes(definitions)
|
50
|
-
.on("tick", ticked);
|
51
|
-
|
52
|
-
simulation.force("link")
|
53
|
-
.links(relations);
|
54
|
-
|
55
|
-
var link = container.append("g")
|
56
|
-
.attr("class", "links")
|
57
|
-
.selectAll("path")
|
58
|
-
.data(relations)
|
59
|
-
.enter().append("path")
|
60
|
-
.attr("class", function(d) { return 'link ' + classForCircular(d); })
|
61
|
-
.attr("marker-end", function(d){ return "url(#" + d.target.id + ")"; }),
|
62
|
-
node = container.append("g")
|
63
|
-
.attr("class", "nodes")
|
64
|
-
.selectAll("g")
|
65
|
-
.data(definitions)
|
66
|
-
.enter().append("g")
|
67
|
-
.call(drag)
|
68
|
-
.on("dblclick", dblclick),
|
69
|
-
circle = node
|
70
|
-
.append("circle")
|
71
|
-
.attr("r", function(d) { return d.lines / max_lines * max_circle_r + 6; })
|
72
|
-
.attr("class", function (d) { return classForCircular(d) ; }),
|
73
|
-
type = node
|
74
|
-
.append("text")
|
75
|
-
.attr("class", "type")
|
76
|
-
.attr("x", "-0.4em")
|
77
|
-
.attr("y", "0.4em")
|
78
|
-
.text(function(d) { return d.type[0]; }),
|
79
|
-
text = node
|
80
|
-
.append("text")
|
81
|
-
.attr("class", "namespace")
|
82
|
-
.attr("x", function(d) { return d.lines / max_lines * max_circle_r + 8; })
|
83
|
-
.attr("y", ".31em")
|
84
|
-
.text(function(d) { return d.id; });
|
85
|
-
|
86
|
-
container.append("defs").selectAll("marker")
|
87
|
-
.data(definitions)
|
88
|
-
.enter().append("marker")
|
89
|
-
.attr("id", function(d) { return d.id; })
|
90
|
-
.attr("viewBox", "0 -5 10 10")
|
91
|
-
.attr("refX", function(d){ return d.lines / max_lines * max_circle_r + 20; })
|
92
|
-
.attr("refY", 0)
|
93
|
-
.attr("markerWidth", 6)
|
94
|
-
.attr("markerHeight", 6)
|
95
|
-
.attr("orient", "auto")
|
96
|
-
.append("path")
|
97
|
-
.attr("d", "M0,-5L10,0L0,5");
|
98
|
-
|
99
|
-
function ticked() {
|
100
|
-
link.attr("d", linkArc);
|
101
|
-
node.attr("transform", transform);
|
102
|
-
}
|
103
|
-
|
104
|
-
function linkArc(d) {
|
105
|
-
var dx = d.target.x - d.source.x,
|
106
|
-
dy = d.target.y - d.source.y,
|
107
|
-
dr = 0;
|
108
|
-
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
|
109
|
-
}
|
110
|
-
|
111
|
-
function dragstarted(d) {
|
112
|
-
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
|
113
|
-
d3.select(this).classed("fixed", true);
|
114
|
-
d.fx = d.x;
|
115
|
-
d.fy = d.y;
|
116
|
-
}
|
117
|
-
|
118
|
-
function dragged(d) {
|
119
|
-
d.fx = d3.event.x;
|
120
|
-
d.fy = d3.event.y;
|
121
|
-
}
|
122
|
-
|
123
|
-
function dragended(d) {
|
124
|
-
if (!d3.event.active) simulation.alphaTarget(0);
|
125
|
-
}
|
126
|
-
|
127
|
-
function dblclick(d) {
|
128
|
-
d3.select(this).classed("fixed", false);
|
129
|
-
d.fx = null;
|
130
|
-
d.fy = null;
|
131
|
-
}
|
132
|
-
|
133
|
-
function transform(d) {
|
134
|
-
return "translate(" + d.x + "," + d.y + ")";
|
135
|
-
}
|
136
|
-
|
137
|
-
|
138
|
-
node.on('mouseover', function(d) {
|
139
|
-
var relatives = [];
|
140
|
-
link.classed('downlighted', function(l) {
|
141
|
-
if (d === l.source || d === l.target){
|
142
|
-
relatives.push(l.source);
|
143
|
-
relatives.push(l.target);
|
144
|
-
return false;
|
145
|
-
}else{
|
146
|
-
return true;
|
147
|
-
}
|
5
|
+
var svg = d3.select(".dependency_graph svg"),
|
6
|
+
$svg = $('.dependency_graph svg'),
|
7
|
+
width = $svg.width(),
|
8
|
+
height = $svg.height(),
|
9
|
+
drag = d3.drag()
|
10
|
+
.on("start", dragstarted)
|
11
|
+
.on("drag", dragged)
|
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 }; }),
|
14
|
+
definitions = _(dup_definitions).groupBy('id').map(function(group) {
|
15
|
+
return {
|
16
|
+
id: group[0].id,
|
17
|
+
type: group[0].type,
|
18
|
+
lines: _(group).sumBy('lines'),
|
19
|
+
circular: group[0].circular
|
20
|
+
};
|
21
|
+
}).value(),
|
22
|
+
namespaces = definitions.map(function(d){ return d.id; }),
|
23
|
+
relations = data.relations.map(function(d){ return {source: d.caller, target: d.resolved_namespace, circular: d.circular}; }),
|
24
|
+
max_lines = _.maxBy(definitions, 'lines').lines,
|
25
|
+
max_circle_r = 50;
|
26
|
+
|
27
|
+
relations = relations.filter(function(d){
|
28
|
+
return namespaces.indexOf(d.source) >= 0 && namespaces.indexOf(d.target) >= 0;
|
29
|
+
});
|
30
|
+
relations = _.uniqWith(relations, _.isEqual);
|
31
|
+
|
32
|
+
var zoom = d3.zoom()
|
33
|
+
.on("zoom", function () {
|
34
|
+
container.attr("transform", d3.event.transform);
|
148
35
|
});
|
149
|
-
node.classed('downlighted', function(n) {
|
150
|
-
return !(n == d || relatives.indexOf(n) > -1);
|
151
|
-
});
|
152
|
-
});
|
153
36
|
|
154
|
-
|
155
|
-
|
156
|
-
|
37
|
+
svg.call(zoom)
|
38
|
+
.on("dblclick.zoom", null);
|
39
|
+
|
40
|
+
var container = svg.append('g'),
|
41
|
+
simulation = d3.forceSimulation()
|
42
|
+
.force("link", d3.forceLink().id(function(d) { return d.id; }))
|
43
|
+
.force("charge", d3.forceManyBody())
|
44
|
+
.force("center", d3.forceCenter(width / 2, height / 2))
|
45
|
+
.force("forceCollide", d3.forceCollide(80));
|
46
|
+
|
47
|
+
simulation
|
48
|
+
.nodes(definitions)
|
49
|
+
.on("tick", ticked);
|
50
|
+
|
51
|
+
simulation.force("link")
|
52
|
+
.links(relations);
|
53
|
+
|
54
|
+
var link = container.append("g")
|
55
|
+
.attr("class", "links")
|
56
|
+
.selectAll("path")
|
57
|
+
.data(relations)
|
58
|
+
.enter().append("path")
|
59
|
+
.attr("class", function(d) { return 'link ' + classForCircular(d); })
|
60
|
+
.attr("marker-end", function(d){ return "url(#" + d.target.id + ")"; }),
|
61
|
+
node = container.append("g")
|
62
|
+
.attr("class", "nodes")
|
63
|
+
.selectAll("g")
|
64
|
+
.data(definitions)
|
65
|
+
.enter().append("g")
|
66
|
+
.call(drag)
|
67
|
+
.on("dblclick", dblclick),
|
68
|
+
circle = node
|
69
|
+
.append("circle")
|
70
|
+
.attr("r", function(d) { return d.lines / max_lines * max_circle_r + 6; })
|
71
|
+
.attr("class", function (d) { return classForCircular(d) ; }),
|
72
|
+
type = node
|
73
|
+
.append("text")
|
74
|
+
.attr("class", "type")
|
75
|
+
.attr("x", "-0.4em")
|
76
|
+
.attr("y", "0.4em")
|
77
|
+
.text(function(d) { return d.type[0]; }),
|
78
|
+
text = node
|
79
|
+
.append("text")
|
80
|
+
.attr("class", "namespace")
|
81
|
+
.attr("x", function(d) { return d.lines / max_lines * max_circle_r + 8; })
|
82
|
+
.attr("y", ".31em")
|
83
|
+
.text(function(d) { return d.id; });
|
84
|
+
|
85
|
+
container.append("defs").selectAll("marker")
|
86
|
+
.data(definitions)
|
87
|
+
.enter().append("marker")
|
88
|
+
.attr("id", function(d) { return d.id; })
|
89
|
+
.attr("viewBox", "0 -5 10 10")
|
90
|
+
.attr("refX", function(d){ return d.lines / max_lines * max_circle_r + 20; })
|
91
|
+
.attr("refY", 0)
|
92
|
+
.attr("markerWidth", 6)
|
93
|
+
.attr("markerHeight", 6)
|
94
|
+
.attr("orient", "auto")
|
95
|
+
.append("path")
|
96
|
+
.attr("d", "M0,-5L10,0L0,5");
|
97
|
+
|
98
|
+
function ticked() {
|
99
|
+
link.attr("d", linkArc);
|
100
|
+
node.attr("transform", transform);
|
101
|
+
}
|
102
|
+
|
103
|
+
function linkArc(d) {
|
104
|
+
var dx = d.target.x - d.source.x,
|
105
|
+
dy = d.target.y - d.source.y,
|
106
|
+
dr = 0;
|
107
|
+
return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
|
108
|
+
}
|
109
|
+
|
110
|
+
function dragstarted(d) {
|
111
|
+
if (!d3.event.active) simulation.alphaTarget(0.3).restart();
|
112
|
+
d3.select(this).classed("fixed", true);
|
113
|
+
d.fx = d.x;
|
114
|
+
d.fy = d.y;
|
115
|
+
}
|
116
|
+
|
117
|
+
function dragged(d) {
|
118
|
+
d.fx = d3.event.x;
|
119
|
+
d.fy = d3.event.y;
|
120
|
+
}
|
121
|
+
|
122
|
+
function dragended(d) {
|
123
|
+
if (!d3.event.active) simulation.alphaTarget(0);
|
124
|
+
}
|
125
|
+
|
126
|
+
function dblclick(d) {
|
127
|
+
d3.select(this).classed("fixed", false);
|
128
|
+
d.fx = null;
|
129
|
+
d.fy = null;
|
130
|
+
}
|
131
|
+
|
132
|
+
function transform(d) {
|
133
|
+
return "translate(" + d.x + "," + d.y + ")";
|
134
|
+
}
|
135
|
+
|
136
|
+
|
137
|
+
node.on('mouseover', function(d) {
|
138
|
+
var relatives = [];
|
139
|
+
link.classed('downlighted', function(l) {
|
140
|
+
if (d === l.source || d === l.target){
|
141
|
+
relatives.push(l.source);
|
142
|
+
relatives.push(l.target);
|
143
|
+
return false;
|
144
|
+
}else{
|
145
|
+
return true;
|
146
|
+
}
|
157
147
|
});
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
148
|
+
node.classed('downlighted', function(n) {
|
149
|
+
return !(n == d || relatives.indexOf(n) > -1);
|
150
|
+
});
|
151
|
+
});
|
152
|
+
|
153
|
+
node.on('mouseout', function() {
|
154
|
+
link.classed('downlighted', false);
|
155
|
+
node.classed('downlighted', false);
|
156
|
+
});
|
157
|
+
|
158
|
+
window.rubrowser = {
|
159
|
+
data: data,
|
160
|
+
definitions: definitions,
|
161
|
+
relations: relations,
|
162
|
+
simulation: simulation,
|
163
|
+
node: node,
|
164
|
+
link: link
|
168
165
|
};
|
169
|
-
|
170
|
-
parseGraph(data);
|
@@ -5,46 +5,44 @@ $(document).on('click', '.panel .title', function(){
|
|
5
5
|
// --------------------------------
|
6
6
|
// Details Panel
|
7
7
|
// --------------------------------
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
8
|
+
rubrowser.node.on('click', function(d){
|
9
|
+
var namespace = d.id;
|
10
|
+
var lines = d.lines;
|
11
|
+
var dependents = rubrowser.relations.filter(function(i){ return i.target.id == namespace; });
|
12
|
+
var dependencies = rubrowser.relations.filter(function(i){ return i.source.id == namespace; });
|
13
|
+
var definitions = rubrowser.data.definitions.filter(function(i){ return i.namespace == namespace; });
|
14
|
+
var relations = rubrowser.data.relations.filter(function(i){ return i.resolved_namespace == namespace || i.caller == namespace; });
|
15
|
+
|
16
|
+
var content = $('<div>');
|
17
|
+
content.append('<label><strong>'+namespace+' ('+d.lines+' Lines)</strong></label>');
|
18
|
+
|
19
|
+
content.append('<strong>Defined in:</strong>');
|
20
|
+
var definitions_ol = $("<ol>");
|
21
|
+
for(var i=0; i<definitions.length; i++){
|
22
|
+
definitions_ol.append("<li>"+definitions[i].file+":"+definitions[i].line.toString()+"</li>");
|
23
|
+
}
|
24
|
+
content.append(definitions_ol);
|
25
|
+
|
26
|
+
if( dependents.length > 0 ){
|
27
|
+
content.append('<strong>Dependents:</strong>');
|
28
|
+
var dependents_ol = $("<ol>");
|
29
|
+
for(var i=0; i<dependents.length; i++){
|
30
|
+
dependents_ol.append("<li>"+dependents[i].source.id+"</li>");
|
24
31
|
}
|
25
|
-
content.append(
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
content.append(dependents_ol);
|
32
|
+
content.append(dependents_ol);
|
33
|
+
}
|
34
|
+
|
35
|
+
if( dependencies.length > 0 ){
|
36
|
+
content.append('<strong>Dependencies:</strong>');
|
37
|
+
var dependencies_ol = $("<ol>");
|
38
|
+
for(var i=0; i<dependencies.length; i++){
|
39
|
+
dependencies_ol.append("<li>"+dependencies[i].target.id+"</li>");
|
34
40
|
}
|
41
|
+
content.append(dependencies_ol);
|
42
|
+
}
|
35
43
|
|
36
|
-
|
37
|
-
|
38
|
-
var dependencies_ol = $("<ol>");
|
39
|
-
for(var i=0; i<dependencies.length; i++){
|
40
|
-
dependencies_ol.append("<li>"+dependencies[i].target.id+"</li>");
|
41
|
-
}
|
42
|
-
content.append(dependencies_ol);
|
43
|
-
}
|
44
|
-
|
45
|
-
$('#information_panel').html(content);
|
46
|
-
return true;
|
47
|
-
});
|
44
|
+
$('#information_panel').html(content);
|
45
|
+
return true;
|
48
46
|
});
|
49
47
|
|
50
48
|
|