git-visualiser 0.0.1
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 +15 -0
- data/bin/git_vis +19 -0
- data/lib/application/application.rb +82 -0
- data/lib/application/coffee_engine.rb +20 -0
- data/lib/application/images/ajax-loader.gif +0 -0
- data/lib/application/javascripts/branch_graph.coffee +424 -0
- data/lib/application/javascripts/commit_graph.coffee +442 -0
- data/lib/application/javascripts/common.coffee +50 -0
- data/lib/application/javascripts/d3.min.js +5 -0
- data/lib/application/javascripts/data_convert.coffee +56 -0
- data/lib/application/javascripts/jquery.min.js +6 -0
- data/lib/application/javascripts/moment.min.js +6 -0
- data/lib/application/javascripts/namespace.coffee +2 -0
- data/lib/application/sass_engine.rb +14 -0
- data/lib/application/stylesheets/scss/app.scss +172 -0
- data/lib/application/stylesheets/scss/flat_ui/_config.sass +16 -0
- data/lib/application/stylesheets/scss/flat_ui/_icon-font-24.sass +91 -0
- data/lib/application/stylesheets/scss/flat_ui/_icon-font.sass +91 -0
- data/lib/application/stylesheets/scss/flat_ui/_mixins.sass +96 -0
- data/lib/application/stylesheets/scss/flat_ui/_spaces.sass +129 -0
- data/lib/application/stylesheets/scss/flat_ui/flat-ui.sass +39 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_btn.sass +73 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_checkbox-and-radio.sass +86 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_demo.sass +228 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_footer.sass +57 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_input.sass +66 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_login.sass +95 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_navbar.sass +152 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_pager.sass +56 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_pagination.sass +75 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_palette.sass +88 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_progress.sass +29 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_select.sass +163 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_share.sass +34 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_tagsinput.sass +91 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_tile.sass +42 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_todo.sass +77 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_toggle.sass +85 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_tooltip.sass +45 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_type.sass +43 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_ui-slider.sass +44 -0
- data/lib/application/stylesheets/scss/flat_ui/modules/_video.sass +358 -0
- data/lib/application/views/authors_list.haml +11 -0
- data/lib/application/views/index.haml +48 -0
- data/lib/application/visualisation.rb +156 -0
- metadata +87 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NDBlYWUyNDk3NmY2MWM0Mzc1ZGEwYmJmNWFiYThhOGM5NjJjM2I4Yw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YzEzZWFiZGMzYjUwODJlNWI4Nzc2NWRiMjRlNmUxOTEzM2MxM2I5MQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MzY1MTFhNjhlZmUxOGI5YjA1ZmI1NmNjNGE4MDBlZGQ0MGNlNjM4ZGZhOTg2
|
10
|
+
NmMyMTUzMjIxODdlZjAyNzE5MDc5MTcxMWUxZGQxZmM2N2U3MWY0MjEwYjAx
|
11
|
+
ZTMwNjk3MDVjZDk5ZDk5NjJkNDg3NjY5MjdiZDg1NjYzMjI5ZTY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
M2YzOGZkZDA5MjJjNTI4ZjkyZDA3YTAyZTZiMDQ5NDBiNzIzYWQ1ZTE4MTlh
|
14
|
+
MWYwOWVjMTczYTViYzM5ZGFkODAwMDE1YjVlYzA0YzhmMjgwMTczZjIxZDFl
|
15
|
+
NmRkZjhkNmFlZDc1MWJkMTdkNjhjNGMwMzQyMTExZTYzOGFkNzA=
|
data/bin/git_vis
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'rubygems'
|
6
|
+
require 'bundler'
|
7
|
+
require 'sinatra'
|
8
|
+
require 'haml'
|
9
|
+
require 'coffee-script'
|
10
|
+
require 'sass'
|
11
|
+
require 'json'
|
12
|
+
|
13
|
+
require 'application/sass_engine'
|
14
|
+
require 'application/coffee_engine'
|
15
|
+
require 'application/visualisation'
|
16
|
+
|
17
|
+
#start the application
|
18
|
+
require 'application/application'
|
19
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
class GitVisualiser < Sinatra::Base
|
2
|
+
|
3
|
+
use SassEngine
|
4
|
+
use CoffeeEngine
|
5
|
+
|
6
|
+
set :static, true
|
7
|
+
set :public_dir, File.expand_path('..', __FILE__)
|
8
|
+
|
9
|
+
set :views, File.expand_path('../views', __FILE__)
|
10
|
+
set :haml, { :format => :html5 }
|
11
|
+
|
12
|
+
get '/' do
|
13
|
+
haml :'/index'
|
14
|
+
end
|
15
|
+
|
16
|
+
get '/branches.json' do
|
17
|
+
branches = Visualisation.branches
|
18
|
+
content_type :json
|
19
|
+
branches.to_json
|
20
|
+
end
|
21
|
+
|
22
|
+
get '/merged_branches.json' do
|
23
|
+
merged_branches = Visualisation.repo_branches_merged
|
24
|
+
content_type :json
|
25
|
+
merged_branches.to_json
|
26
|
+
end
|
27
|
+
|
28
|
+
get '/filter_branch_commits.json' do
|
29
|
+
include_commit_sha = params[:include]
|
30
|
+
exclude_commit_sha = params[:exclude]
|
31
|
+
|
32
|
+
branches = branches_include = branches_exclude = []
|
33
|
+
branches_include = Visualisation.branches_containing_commit(include_commit_sha) if include_commit_sha != ''
|
34
|
+
branches_exclude = Visualisation.branches_excluding_commit(exclude_commit_sha) if exclude_commit_sha != ''
|
35
|
+
|
36
|
+
if !branches_include == {}
|
37
|
+
branches = Hash[branches_include.to_a - branches_exclude.to_a]
|
38
|
+
else
|
39
|
+
branches = branches_exclude
|
40
|
+
end
|
41
|
+
|
42
|
+
content_type :json
|
43
|
+
branches.to_json
|
44
|
+
end
|
45
|
+
|
46
|
+
get '/author_stats.json' do
|
47
|
+
ref = params[:ref]
|
48
|
+
|
49
|
+
@authors = Visualisation.branch_author_stats(ref)
|
50
|
+
@authors = @authors.slice(0, 3) #show a max of 3 authors
|
51
|
+
|
52
|
+
haml :'/authors_list' if @authors.length > 0
|
53
|
+
end
|
54
|
+
|
55
|
+
get '/commits.json' do
|
56
|
+
ref = params[:ref]
|
57
|
+
commits = Visualisation.commits_for_branch(ref)
|
58
|
+
|
59
|
+
content_type :json
|
60
|
+
commits.to_json
|
61
|
+
end
|
62
|
+
|
63
|
+
get '/commit_diff_stats.json' do
|
64
|
+
ref = params[:ref]
|
65
|
+
file_diff_stats = Visualisation.merge_base_file_stats(ref)
|
66
|
+
|
67
|
+
content_type :json
|
68
|
+
file_diff_stats.to_json
|
69
|
+
end
|
70
|
+
|
71
|
+
helpers do
|
72
|
+
|
73
|
+
def gravatar_image(email)
|
74
|
+
hash = Digest::MD5.hexdigest(email).to_s
|
75
|
+
"<img src=\"http://www.gravatar.com/avatar/#{hash}?s=48\" />"
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
puts "Running GitVisualiser"
|
82
|
+
GitVisualiser.run!
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class CoffeeEngine < Sinatra::Base
|
2
|
+
|
3
|
+
set :views, File.dirname(__FILE__) + '/javascripts'
|
4
|
+
set :public_dir, File.expand_path('..', __FILE__)
|
5
|
+
|
6
|
+
get "/javascripts/d3.min.js" do
|
7
|
+
end
|
8
|
+
|
9
|
+
get "/javascripts/jquery.min.js" do
|
10
|
+
end
|
11
|
+
|
12
|
+
get "/javascripts/moment.min.js" do
|
13
|
+
end
|
14
|
+
|
15
|
+
get "/javascripts/*.js" do
|
16
|
+
filename = params[:splat].first
|
17
|
+
coffee filename.to_sym
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
Binary file
|
@@ -0,0 +1,424 @@
|
|
1
|
+
class BranchGraph
|
2
|
+
constructor: ->
|
3
|
+
@initializeD3()
|
4
|
+
@getGraphData()
|
5
|
+
@initializeControls()
|
6
|
+
@commitGraph = new Visualisation.CommitGraph()
|
7
|
+
# @commitGraph.load("git-vis-2")
|
8
|
+
|
9
|
+
initializeD3: ->
|
10
|
+
# set up SVG for D3
|
11
|
+
@width = $("#branches-display").width();
|
12
|
+
@height = $("#branches-display").height();
|
13
|
+
@body = d3.select("body")
|
14
|
+
@svg = @body.select("#branches-display")
|
15
|
+
.append("svg")
|
16
|
+
.attr("width", @width)
|
17
|
+
.attr("height", @height)
|
18
|
+
@lastKeyDown = -1;
|
19
|
+
|
20
|
+
getGraphData: ->
|
21
|
+
# set up initial nodes and links
|
22
|
+
# - nodes are known by 'id', not by index in array.
|
23
|
+
# - links are always source < target; edge directions are set by 'left' and 'right'.
|
24
|
+
$.get "/branches.json", (data) ->
|
25
|
+
branch_data = data
|
26
|
+
$.get "/merged_branches.json", (merge_data) ->
|
27
|
+
Visualisation.branchGraph.initGraphData(branch_data, merge_data)
|
28
|
+
|
29
|
+
initializeControls: ->
|
30
|
+
$("#apply-filters-btn").click () =>
|
31
|
+
@apply_filters()
|
32
|
+
false
|
33
|
+
|
34
|
+
initGraphData: (branch_data, merge_data) =>
|
35
|
+
@branches = branch_data.branches;
|
36
|
+
@diff_lines = branch_data.diff;
|
37
|
+
|
38
|
+
@master = undefined
|
39
|
+
#remove the master branch from branches array
|
40
|
+
@branches = $.grep(@branches, (el, i) =>
|
41
|
+
if el.name is "master"
|
42
|
+
@master = el
|
43
|
+
return false
|
44
|
+
true
|
45
|
+
)
|
46
|
+
|
47
|
+
percent_diff = 0.0
|
48
|
+
total_diff = @diff_lines.add + @diff_lines.del
|
49
|
+
average_diff = total_diff / @branches.length
|
50
|
+
|
51
|
+
@nodes = []
|
52
|
+
@links = []
|
53
|
+
@branch_names = {}
|
54
|
+
@nodes.push
|
55
|
+
id: 0
|
56
|
+
branch: @master
|
57
|
+
size: 5.0
|
58
|
+
reflexive: false
|
59
|
+
fixed: true
|
60
|
+
x: @width / 2
|
61
|
+
y: @height / 2
|
62
|
+
@branch_names["master"] = 0
|
63
|
+
$.each @branches, (i, obj) =>
|
64
|
+
#calculate the percentage diff for this branch
|
65
|
+
percent_diff = (obj.diff.add + obj.diff.del) / average_diff
|
66
|
+
@nodes.push id: i + 1, branch: obj, size: percent_diff, reflexive: false, hidden: false
|
67
|
+
@branch_names[obj.name] = i + 1
|
68
|
+
|
69
|
+
#check for merges/edges for each branch/node
|
70
|
+
@linked_nodes = {}
|
71
|
+
$.each merge_data, (base_key, base) =>
|
72
|
+
$.each base, (branch_key, merged_branch) =>
|
73
|
+
if merged_branch.left || merged_branch.right
|
74
|
+
@linked_nodes[@branch_names[base_key] + ", " + @branch_names[branch_key]] = 1
|
75
|
+
@links.push
|
76
|
+
source: @branch_names[base_key]
|
77
|
+
target: @branch_names[branch_key]
|
78
|
+
left: merged_branch.left
|
79
|
+
right: merged_branch.right
|
80
|
+
hidden: false
|
81
|
+
|
82
|
+
#store original state
|
83
|
+
@all_nodes = @nodes
|
84
|
+
@all_links = @links
|
85
|
+
@all_branches = @branches
|
86
|
+
@all_branch_names = @branch_names
|
87
|
+
|
88
|
+
@initGraph(false)
|
89
|
+
|
90
|
+
initGraph: (redraw) ->
|
91
|
+
if redraw is true
|
92
|
+
d3.select("svg").remove()
|
93
|
+
@svg = @body.select("#vis-display")
|
94
|
+
.append("svg")
|
95
|
+
.attr("width", @width)
|
96
|
+
.attr("height", @height)
|
97
|
+
@recalculate_node_sizes()
|
98
|
+
|
99
|
+
lastNodeId = @nodes.length - 1
|
100
|
+
|
101
|
+
# init D3 force layout
|
102
|
+
@force = d3.layout.force()
|
103
|
+
.nodes(@nodes)
|
104
|
+
.links(@links)
|
105
|
+
.size([@width, @height])
|
106
|
+
.linkDistance(150)
|
107
|
+
.charge(-500)
|
108
|
+
.on("tick", @tick)
|
109
|
+
|
110
|
+
# define arrow markers for graph links
|
111
|
+
@svg.append('svg:defs').append('svg:marker')
|
112
|
+
.attr('id', 'end-arrow')
|
113
|
+
.attr('viewBox', '0 -5 10 10')
|
114
|
+
.attr('refX', 6)
|
115
|
+
.attr('markerWidth', 3)
|
116
|
+
.attr('markerHeight', 3)
|
117
|
+
.attr('orient', 'auto')
|
118
|
+
.append('svg:path')
|
119
|
+
.attr('d', 'M0,-5L10,0L0,5')
|
120
|
+
.attr('fill', '#999');
|
121
|
+
|
122
|
+
@svg.append('svg:defs').append('svg:marker')
|
123
|
+
.attr('id', 'start-arrow')
|
124
|
+
.attr('viewBox', '0 -5 10 10')
|
125
|
+
.attr('refX', 4)
|
126
|
+
.attr('markerWidth', 3)
|
127
|
+
.attr('markerHeight', 3)
|
128
|
+
.attr('orient', 'auto')
|
129
|
+
.append('svg:path')
|
130
|
+
.attr('d', 'M10,-5L0,0L10,5')
|
131
|
+
.attr('fill', '#999');
|
132
|
+
|
133
|
+
# handles to link and node element groups
|
134
|
+
@path = @svg.append('svg:g').selectAll('path')
|
135
|
+
@circle = @svg.append('svg:g').selectAll('g');
|
136
|
+
|
137
|
+
# mouse event vars
|
138
|
+
@selected_node = null
|
139
|
+
@selected_link = null
|
140
|
+
@mousedown_link = null
|
141
|
+
@mousedown_node = null
|
142
|
+
@mouseup_node = null
|
143
|
+
|
144
|
+
#remove the loading div here
|
145
|
+
$("#vis-loading").hide();
|
146
|
+
@restart()
|
147
|
+
|
148
|
+
resetMouseVars: ->
|
149
|
+
@mousedown_node = null
|
150
|
+
@mouseup_node = null
|
151
|
+
@mousedown_link = null
|
152
|
+
|
153
|
+
# update force layout (called automatically each iteration)
|
154
|
+
tick: ->
|
155
|
+
# draw directed edges with proper padding from node centers
|
156
|
+
Visualisation.branchGraph.path.attr "d", (d) ->
|
157
|
+
deltaX = d.target.x - d.source.x
|
158
|
+
deltaY = d.target.y - d.source.y
|
159
|
+
dist = Math.sqrt(deltaX * deltaX + deltaY * deltaY)
|
160
|
+
normX = deltaX / dist
|
161
|
+
normY = deltaY / dist
|
162
|
+
sourcePadding = node_size(d.source) + 7
|
163
|
+
targetPadding = node_size(d.target) + 7
|
164
|
+
sourceX = d.source.x + (sourcePadding * normX)
|
165
|
+
sourceY = d.source.y + (sourcePadding * normY)
|
166
|
+
targetX = d.target.x - (targetPadding * normX)
|
167
|
+
targetY = d.target.y - (targetPadding * normY)
|
168
|
+
"M" + sourceX + "," + sourceY + "L" + targetX + "," + targetY
|
169
|
+
|
170
|
+
Visualisation.branchGraph.circle.attr "transform", (d) ->
|
171
|
+
"translate(" + d.x + "," + d.y + ")"
|
172
|
+
|
173
|
+
# update graph (called when needed)
|
174
|
+
restart: ->
|
175
|
+
# path (link) group
|
176
|
+
@path = @path.data(@links)
|
177
|
+
|
178
|
+
# update existing links
|
179
|
+
@path.classed("selected", (d) ->
|
180
|
+
d is @selected_link
|
181
|
+
).style("marker-start", (d) ->
|
182
|
+
(if d.left then "url(#start-arrow)" else "")
|
183
|
+
).style "marker-end", (d) ->
|
184
|
+
(if d.right then "url(#end-arrow)" else "")
|
185
|
+
|
186
|
+
# add new links
|
187
|
+
@path.enter().append("svg:path").attr("class", "link").classed("selected", (d) ->
|
188
|
+
d is @selected_link
|
189
|
+
).style("marker-start", (d) ->
|
190
|
+
(if d.left then "url(#start-arrow)" else "")
|
191
|
+
).style("marker-end", (d) ->
|
192
|
+
(if d.right then "url(#end-arrow)" else "")
|
193
|
+
)
|
194
|
+
|
195
|
+
# remove old links
|
196
|
+
@path.exit().remove()
|
197
|
+
|
198
|
+
# circle (node) group
|
199
|
+
# NB: the function arg is crucial here! nodes are known by id, not by index!
|
200
|
+
@circle = @circle.data(@nodes, (d) ->
|
201
|
+
d.id
|
202
|
+
)
|
203
|
+
|
204
|
+
#hide filtered nodes
|
205
|
+
@circle.selectAll("circle").select((d) ->
|
206
|
+
d.branch.hidden == false ? this : null
|
207
|
+
)
|
208
|
+
|
209
|
+
# update existing nodes (reflexive & selected visual states)
|
210
|
+
@circle.selectAll("circle").style("fill", (d) ->
|
211
|
+
(if (d is @selected_node) then d3.rgb(branch_color(d)).brighter().toString() else d3.rgb(branch_color(d)))
|
212
|
+
).classed "reflexive", (d) ->
|
213
|
+
d.reflexive
|
214
|
+
|
215
|
+
@circle.selectAll("text")
|
216
|
+
.attr("x", (d) -> node_size(d)+5)
|
217
|
+
.attr("y", (d) -> node_size(d)/2)
|
218
|
+
|
219
|
+
# add new nodes
|
220
|
+
g = @circle.enter().append("svg:g")
|
221
|
+
|
222
|
+
# reposition drag line
|
223
|
+
vis = @
|
224
|
+
g.append("svg:circle").attr("class", "node")
|
225
|
+
.attr("branch", (d) -> d.branch.name)
|
226
|
+
.attr("r", (d) -> node_size(d))
|
227
|
+
.style("fill", (d) -> (d3.rgb(branch_color(d))))
|
228
|
+
.style("stroke", (d) -> d3.rgb(branch_color(d)).darker().toString())
|
229
|
+
.classed("reflexive", (d) -> d.reflexive)
|
230
|
+
.on("mouseover", (d) ->
|
231
|
+
d3.selectAll("circle").filter((d2) -> d != d2).transition().style "opacity", "0.25"
|
232
|
+
d3.selectAll("text").filter((d2) -> d != d2).transition().style "opacity", "0.10"
|
233
|
+
d3.selectAll("path.link").filter((d2) -> d != d2).transition().style "opacity", "0.10"
|
234
|
+
vis.getAuthorStats(d.branch.name))
|
235
|
+
.on("mouseout", (d) ->
|
236
|
+
d3.selectAll("circle").transition().style "opacity", "1"
|
237
|
+
d3.selectAll("text").transition().style "opacity", "1"
|
238
|
+
d3.selectAll("path").transition().style "opacity", "1"
|
239
|
+
vis.clearAuthorStats())
|
240
|
+
.on("mousedown", (d) ->
|
241
|
+
vis.mousedown_node = d
|
242
|
+
d3.selectAll("circle").filter((d2) ->
|
243
|
+
vis.neighbouring(vis.dom_node(d)[0].__data__.id, vis.dom_node(d2)[0].__data__.id)
|
244
|
+
).transition().style "opacity", "1"
|
245
|
+
d3.selectAll("text").filter((d2) ->
|
246
|
+
vis.neighbouring(vis.dom_node(d)[0].__data__.id, vis.dom_node(d2)[0].__data__.id)
|
247
|
+
).transition().style "opacity", "1"
|
248
|
+
d3.selectAll("path.link").filter((d2) ->
|
249
|
+
return false if d2 is undefined
|
250
|
+
return true if d2.source == vis.mousedown_node || d2.target == vis.mousedown_node
|
251
|
+
).transition().style "opacity", "1")
|
252
|
+
.on("dblclick", (d) ->
|
253
|
+
vis.commitGraph.load(d.branch.name)
|
254
|
+
)
|
255
|
+
.call(@force.drag())
|
256
|
+
|
257
|
+
# show node IDs
|
258
|
+
g.append("svg:text")
|
259
|
+
.attr("x", (d) -> node_size(d)+5)
|
260
|
+
.attr("y", (d) -> node_size(d)/2)
|
261
|
+
.attr("class", "name").text (d) ->
|
262
|
+
d.branch.name + " " + d.branch.diff.add + " / " + d.branch.diff.del
|
263
|
+
|
264
|
+
# remove old nodes
|
265
|
+
@circle.exit().remove()
|
266
|
+
|
267
|
+
# set the graph in motion
|
268
|
+
@force.start()
|
269
|
+
|
270
|
+
clear_filters : () ->
|
271
|
+
@nodes = @all_nodes
|
272
|
+
@links = @all_links
|
273
|
+
@branches = @all_branches
|
274
|
+
@branch_names = @all_branch_names
|
275
|
+
|
276
|
+
apply_filters: () ->
|
277
|
+
@clear_filters()
|
278
|
+
|
279
|
+
#filter branches merged with master
|
280
|
+
if $("#filter_merged_checkbox").is(":checked")
|
281
|
+
@filter_merged_with_master()
|
282
|
+
|
283
|
+
#filter branches merged with master
|
284
|
+
if $("#filter_remotes_checkbox").is(":checked")
|
285
|
+
@filter_remotes()
|
286
|
+
|
287
|
+
#filter branches by name
|
288
|
+
filter_name_query = $("#filter_names_input").val()
|
289
|
+
@filter_branch_names(filter_name_query) if filter_name_query.length > 0
|
290
|
+
|
291
|
+
additional_requests = false
|
292
|
+
#filter branches containing commit
|
293
|
+
show_commit_sha = $("#show_commit_input").val()
|
294
|
+
exclude_commit_sha = $("#exclude_commit_input").val()
|
295
|
+
|
296
|
+
if show_commit_sha.length > 0 || exclude_commit_sha.length > 0
|
297
|
+
additional_requests = true
|
298
|
+
@filter_branch_commits(show_commit_sha, exclude_commit_sha)
|
299
|
+
|
300
|
+
# if we arent making any more requests for this data then
|
301
|
+
# restart, otherwise the additional requests callback will make restart call
|
302
|
+
if !additional_requests
|
303
|
+
@restart()
|
304
|
+
|
305
|
+
dom_node: (data) ->
|
306
|
+
return if !data.branch
|
307
|
+
$("circle[branch=" + "'#{data.branch.name}'" + "]")
|
308
|
+
|
309
|
+
filter_merged_with_master: () ->
|
310
|
+
@nodes = $.grep @nodes, (node, i) =>
|
311
|
+
if node.branch.merged_with_master is true
|
312
|
+
return true if node.branch.name == "master"
|
313
|
+
@links = $.grep @links, (link, i) ->
|
314
|
+
return false if link.source == node or link.target == node
|
315
|
+
true
|
316
|
+
@branches = $.grep @branches, (branch, i) ->
|
317
|
+
return false if branch == node.branch
|
318
|
+
true
|
319
|
+
@branch_names = $.grep @branch_names, (name, i) ->
|
320
|
+
return false if name == node.branch.name
|
321
|
+
true
|
322
|
+
return false
|
323
|
+
true
|
324
|
+
|
325
|
+
filter_remotes: () ->
|
326
|
+
@nodes = $.grep @nodes, (node, i) =>
|
327
|
+
if node.branch.remote is true
|
328
|
+
return true if node.branch.name == "master"
|
329
|
+
@links = $.grep @links, (link, i) ->
|
330
|
+
return false if link.source == node or link.target == node
|
331
|
+
true
|
332
|
+
@branches = $.grep @branches, (branch, i) ->
|
333
|
+
return false if branch == node.branch
|
334
|
+
true
|
335
|
+
@branch_names = $.grep @branch_names, (name, i) ->
|
336
|
+
return false if name == node.branch.name
|
337
|
+
true
|
338
|
+
return false
|
339
|
+
true
|
340
|
+
|
341
|
+
filter_branch_names: (query) ->
|
342
|
+
@nodes = $.grep @nodes, (node, i) =>
|
343
|
+
if node.branch.name.indexOf(query) == -1
|
344
|
+
return true if node.branch.name == "master"
|
345
|
+
@links = $.grep @links, (link, i) ->
|
346
|
+
return false if link.source == node or link.target == node
|
347
|
+
true
|
348
|
+
@branches = $.grep @branches, (branch, i) ->
|
349
|
+
return false if branch == node.branch
|
350
|
+
true
|
351
|
+
@branch_names = $.grep @branch_names, (name, i) ->
|
352
|
+
return false if name == node.branch.name
|
353
|
+
true
|
354
|
+
return false
|
355
|
+
true
|
356
|
+
|
357
|
+
filter_branch_commits: (include_commit_sha, exclude_commit_sha) ->
|
358
|
+
json_data = {include: include_commit_sha, exclude: exclude_commit_sha}
|
359
|
+
$.get "/filter_branch_commits.json", json_data, (data) =>
|
360
|
+
branch_names = data
|
361
|
+
@nodes = $.grep @nodes, (node, i) =>
|
362
|
+
if $.inArray(node.branch.name, branch_names) is -1
|
363
|
+
return true if node.branch.name == "master"
|
364
|
+
@links = $.grep @links, (link, i) ->
|
365
|
+
return false if link.source == node or link.target == node
|
366
|
+
true
|
367
|
+
@branches = $.grep @branches, (branch, i) ->
|
368
|
+
return false if branch == node.branch
|
369
|
+
true
|
370
|
+
@branch_names = $.grep @branch_names, (name, i) ->
|
371
|
+
return false if name == node.branch.name
|
372
|
+
true
|
373
|
+
return false
|
374
|
+
true
|
375
|
+
@restart()
|
376
|
+
|
377
|
+
branch_color = (node) ->
|
378
|
+
return "#1f77b4" if node.branch.name is "master"
|
379
|
+
return "#9CDECD" if node.branch.merged_with_master
|
380
|
+
#color based on additions and deletions
|
381
|
+
branch_diff = node.branch.diff.add - node.branch.diff.del
|
382
|
+
if branch_diff > 100
|
383
|
+
"#6ACD72"
|
384
|
+
else if branch_diff > 0 && branch_diff <= 100
|
385
|
+
"#FFF48F"
|
386
|
+
else
|
387
|
+
"#C3554B"
|
388
|
+
|
389
|
+
node_size = (node_data) ->
|
390
|
+
rad = 5 * node_data.size
|
391
|
+
|
392
|
+
rad = 5 if rad < 5
|
393
|
+
rad = 20 if rad > 20
|
394
|
+
return rad
|
395
|
+
|
396
|
+
recalculate_node_sizes: () ->
|
397
|
+
percent_diff = 0.0
|
398
|
+
total_diff = 0.0
|
399
|
+
# recalculate total diff of all filtered branches
|
400
|
+
$.each @branches, (i, branch) ->
|
401
|
+
total_diff += branch.diff.add + branch.diff.del
|
402
|
+
average_diff = total_diff / @branches.length
|
403
|
+
|
404
|
+
# recalculate size for each node based on new average
|
405
|
+
$.each @nodes, (i, node) ->
|
406
|
+
if node.branch.name != "master"
|
407
|
+
node.size = (node.branch.diff.add + node.branch.diff.del) / average_diff
|
408
|
+
|
409
|
+
neighbouring: (node_id, other_id) ->
|
410
|
+
@linked_nodes[node_id + ", " + other_id] == 1 ||
|
411
|
+
@linked_nodes[other_id + ", " + node_id] == 1 ||
|
412
|
+
node_id == other_id
|
413
|
+
|
414
|
+
getAuthorStats: (branch_name) ->
|
415
|
+
$.get "/author_stats.json", {ref: branch_name}, (data) ->
|
416
|
+
$("#authors-list").html(data)
|
417
|
+
|
418
|
+
clearAuthorStats: ->
|
419
|
+
$("#authors-list").empty()
|
420
|
+
|
421
|
+
|
422
|
+
|
423
|
+
Visualisation.BranchGraph = BranchGraph
|
424
|
+
Visualisation.branchGraph = new BranchGraph()
|