Commit 233d285c authored by Dmitriy Zaporozhets's avatar Dmitriy Zaporozhets

Merge pull request #3741 from hiroponz/improve-performance-of-network-graph

Improve performance of network graph
parents 75fbdc40 1ae9c697
...@@ -9,6 +9,7 @@ class BranchGraph ...@@ -9,6 +9,7 @@ class BranchGraph
@offsetY = 20 @offsetY = 20
@unitTime = 30 @unitTime = 30
@unitSpace = 10 @unitSpace = 10
@prev_start = -1
@load() @load()
load: -> load: ->
...@@ -24,10 +25,18 @@ class BranchGraph ...@@ -24,10 +25,18 @@ class BranchGraph
prepareData: (@days, @commits) -> prepareData: (@days, @commits) ->
@collectParents() @collectParents()
@graphHeight = $(@element).height()
@graphWidth = $(@element).width()
ch = Math.max(@graphHeight, @offsetY + @unitTime * @mtime + 150)
cw = Math.max(@graphWidth, @offsetX + @unitSpace * @mspace + 300)
@r = Raphael(@element.get(0), cw, ch)
@top = @r.set()
@barHeight = Math.max(@graphHeight, @unitTime * @days.length + 320)
for c in @commits for c in @commits
c.isParent = true if c.id of @parents c.isParent = true if c.id of @parents
@preparedCommits[c.id] = c @preparedCommits[c.id] = c
@markCommit(c)
@collectColors() @collectColors()
...@@ -49,18 +58,12 @@ class BranchGraph ...@@ -49,18 +58,12 @@ class BranchGraph
k++ k++
buildGraph: -> buildGraph: ->
graphHeight = $(@element).height() r = @r
graphWidth = $(@element).width()
ch = Math.max(graphHeight, @offsetY + @unitTime * @mtime + 150)
cw = Math.max(graphWidth, @offsetX + @unitSpace * @mspace + 300)
@r = r = Raphael(@element.get(0), cw, ch)
top = r.set()
cuday = 0 cuday = 0
cumonth = "" cumonth = ""
barHeight = Math.max(graphHeight, @unitTime * @days.length + 320)
r.rect(0, 0, 26, barHeight).attr fill: "#222" r.rect(0, 0, 26, @barHeight).attr fill: "#222"
r.rect(26, 0, 20, barHeight).attr fill: "#444" r.rect(26, 0, 20, @barHeight).attr fill: "#444"
for day, mm in @days for day, mm in @days
if cuday isnt day[0] if cuday isnt day[0]
...@@ -81,7 +84,26 @@ class BranchGraph ...@@ -81,7 +84,26 @@ class BranchGraph
) )
cumonth = day[1] cumonth = day[1]
for commit in @commits @renderPartialGraph()
@bindEvents()
renderPartialGraph: ->
start = Math.floor((@element.scrollTop() - @offsetY) / @unitTime) - 10
start = 0 if start < 0
end = start + 40
end = @commits.length if @commits.length < end
if @prev_start == -1 or Math.abs(@prev_start - start) > 10
i = start
@prev_start = start
while i < end
commit = @commits[i]
i += 1
if commit.hasDrawn isnt true
x = @offsetX + @unitSpace * (@mspace - commit.space) x = @offsetX + @unitSpace * (@mspace - commit.space)
y = @offsetY + @unitTime * commit.time y = @offsetY + @unitTime * commit.time
...@@ -89,34 +111,23 @@ class BranchGraph ...@@ -89,34 +111,23 @@ class BranchGraph
@drawLines(x, y, commit) @drawLines(x, y, commit)
@appendLabel(x, y, commit.refs) if commit.refs @appendLabel(x, y, commit)
@appendAnchor(top, commit, x, y) @appendAnchor(x, y, commit)
@markCommit(x, y, commit, graphHeight) commit.hasDrawn = true
top.toFront() @top.toFront()
@bindEvents()
bindEvents: -> bindEvents: ->
drag = {} drag = {}
element = @element element = @element
dragger = (event) ->
element.scrollLeft drag.sl - (event.clientX - drag.x) $(element).scroll (event) =>
element.scrollTop drag.st - (event.clientY - drag.y) @renderPartialGraph()
element.on mousedown: (event) ->
drag =
x: event.clientX
y: event.clientY
st: element.scrollTop()
sl: element.scrollLeft()
$(window).on "mousemove", dragger
$(window).on $(window).on
mouseup: -> keydown: (event) =>
$(window).off "mousemove", dragger
keydown: (event) ->
# left # left
element.scrollLeft element.scrollLeft() - 50 if event.keyCode is 37 element.scrollLeft element.scrollLeft() - 50 if event.keyCode is 37
# top # top
...@@ -125,17 +136,20 @@ class BranchGraph ...@@ -125,17 +136,20 @@ class BranchGraph
element.scrollLeft element.scrollLeft() + 50 if event.keyCode is 39 element.scrollLeft element.scrollLeft() + 50 if event.keyCode is 39
# bottom # bottom
element.scrollTop element.scrollTop() + 50 if event.keyCode is 40 element.scrollTop element.scrollTop() + 50 if event.keyCode is 40
@renderPartialGraph()
appendLabel: (x, y, commit) ->
return unless commit.refs
appendLabel: (x, y, refs) ->
r = @r r = @r
shortrefs = refs shortrefs = commit.refs
# Truncate if longer than 15 chars # Truncate if longer than 15 chars
shortrefs = shortrefs.substr(0, 15) + "…" if shortrefs.length > 17 shortrefs = shortrefs.substr(0, 15) + "…" if shortrefs.length > 17
text = r.text(x + 4, y, shortrefs).attr( text = r.text(x + 4, y, shortrefs).attr(
"text-anchor": "start" "text-anchor": "start"
font: "10px Monaco, monospace" font: "10px Monaco, monospace"
fill: "#FFF" fill: "#FFF"
title: refs title: commit.refs
) )
textbox = text.getBBox() textbox = text.getBBox()
# Create rectangle based on the size of the textbox # Create rectangle based on the size of the textbox
...@@ -156,8 +170,9 @@ class BranchGraph ...@@ -156,8 +170,9 @@ class BranchGraph
# Set text to front # Set text to front
text.toFront() text.toFront()
appendAnchor: (top, commit, x, y) -> appendAnchor: (x, y, commit) ->
r = @r r = @r
top = @top
options = @options options = @options
anchor = r.circle(x, y, 10).attr( anchor = r.circle(x, y, 10).attr(
fill: "#000" fill: "#000"
...@@ -240,16 +255,18 @@ class BranchGraph ...@@ -240,16 +255,18 @@ class BranchGraph
stroke: color stroke: color
"stroke-width": 2) "stroke-width": 2)
markCommit: (x, y, commit, graphHeight) -> markCommit: (commit) ->
if commit.id is @options.commit_id if commit.id is @options.commit_id
r = @r r = @r
x = @offsetX + @unitSpace * (@mspace - commit.space)
y = @offsetY + @unitTime * commit.time
r.path(["M", x + 5, y, "L", x + 15, y + 4, "L", x + 15, y - 4, "Z"]).attr( r.path(["M", x + 5, y, "L", x + 15, y + 4, "L", x + 15, y - 4, "Z"]).attr(
fill: "#000" fill: "#000"
"fill-opacity": .5 "fill-opacity": .5
stroke: "none" stroke: "none"
) )
# Displayed in the center # Displayed in the center
@element.scrollTop(y - graphHeight / 2) @element.scrollTop(y - @graphHeight / 2)
Raphael::commitTooltip = (x, y, commit) -> Raphael::commitTooltip = (x, y, commit) ->
boxWidth = 300 boxWidth = 300
......
...@@ -13,7 +13,8 @@ ...@@ -13,7 +13,8 @@
background: #f1f1f1; background: #f1f1f1;
cursor: move; cursor: move;
height: 500px; height: 500px;
overflow: hidden; overflow-y: scroll;
overflow-x: hidden;
} }
} }
...@@ -4,8 +4,7 @@ module GraphHelper ...@@ -4,8 +4,7 @@ module GraphHelper
refs += commit.refs.collect{|r|r.name}.join(" ") if commit.refs refs += commit.refs.collect{|r|r.name}.join(" ") if commit.refs
# append note count # append note count
notes = @project.notes.for_commit_id(commit.id) refs += "[#{@graph.notes[commit.id]}]" if @graph.notes[commit.id] > 0
refs += "[#{notes.count}]" if notes.any?
refs refs
end end
......
...@@ -2,7 +2,7 @@ require "grit" ...@@ -2,7 +2,7 @@ require "grit"
module Network module Network
class Graph class Graph
attr_reader :days, :commits, :map attr_reader :days, :commits, :map, :notes
def self.max_count def self.max_count
@max_count ||= 650 @max_count ||= 650
...@@ -16,10 +16,19 @@ module Network ...@@ -16,10 +16,19 @@ module Network
@commits = collect_commits @commits = collect_commits
@days = index_commits @days = index_commits
@notes = collect_notes
end end
protected protected
def collect_notes
h = Hash.new(0)
@project.notes.where('noteable_type = ?' ,"Commit").group('notes.commit_id').select('notes.commit_id, count(notes.id) as note_count').each do |item|
h[item["commit_id"]] = item["note_count"]
end
h
end
# Get commits from repository # Get commits from repository
# #
def collect_commits def collect_commits
...@@ -181,7 +190,7 @@ module Network ...@@ -181,7 +190,7 @@ module Network
l.spaces << space l.spaces << space
# Also add space to parent # Also add space to parent
l.parents(@map).each do |parent| l.parents(@map).each do |parent|
if parent.space > 0 if 0 < parent.space && parent.space < space
parent.spaces << space parent.spaces << space
end end
end end
......
...@@ -11,14 +11,16 @@ Feature: Project Network Graph ...@@ -11,14 +11,16 @@ Feature: Project Network Graph
And page should have "master" on graph And page should have "master" on graph
@javascript @javascript
Scenario: I should switch ref to "stable" Scenario: I should switch "branch" and "tag"
When I switch ref to "stable" When I switch ref to "stable"
Then page should have network graph Then page should select "stable" in select box
And page should select "stable" in select box
And page should have "stable" on graph And page should have "stable" on graph
When I switch ref to "v2.1.0"
Then page should select "v2.1.0" in select box
And page should have "v2.1.0" on graph
@javascript @javascript
Scenario: I should looking for a commit by SHA of "v2.1.0" Scenario: I should looking for a commit by SHA
When I looking for a commit by SHA of "v2.1.0" When I looking for a commit by SHA of "v2.1.0"
Then page should have network graph Then page should have network graph
And page should select "master" in select box And page should select "master" in select box
......
...@@ -30,10 +30,19 @@ class ProjectNetworkGraph < Spinach::FeatureSteps ...@@ -30,10 +30,19 @@ class ProjectNetworkGraph < Spinach::FeatureSteps
sleep 2 sleep 2
end end
When 'I switch ref to "v2.1.0"' do
page.select 'v2.1.0', :from => 'ref'
sleep 2
end
And 'page should select "stable" in select box' do And 'page should select "stable" in select box' do
page.should have_selector '#ref_chzn span', :text => "stable" page.should have_selector '#ref_chzn span', :text => "stable"
end end
And 'page should select "v2.1.0" in select box' do
page.should have_selector '#ref_chzn span', :text => "v2.1.0"
end
And 'page should have "stable" on graph' do And 'page should have "stable" on graph' do
within '.graph' do within '.graph' do
page.should have_content 'stable' page.should have_content 'stable'
......
...@@ -98,9 +98,7 @@ module ExtractsPath ...@@ -98,9 +98,7 @@ module ExtractsPath
@ref, @path = extract_ref(@id) @ref, @path = extract_ref(@id)
# It is used "@project.repository.commits(@ref, @path, 1, 0)", @commit = @project.repository.commit(@ref)
# because "@project.repository.commit(@ref)" returns wrong commit when @ref is tag name.
@commit = @project.repository.commits(@ref, @path, 1, 0).first
@tree = Tree.new(@project.repository, @commit.id, @ref, @path) @tree = Tree.new(@project.repository, @commit.id, @ref, @path)
......
...@@ -49,7 +49,16 @@ module Gitlab ...@@ -49,7 +49,16 @@ module Gitlab
def commit(commit_id = nil) def commit(commit_id = nil)
commit = if commit_id commit = if commit_id
# Find repo.refs first,
# because if commit_id is "tag name",
# repo.commit(commit_id) returns wrong commit sha
# that is git tag object sha.
ref = repo.refs.find {|r| r.name == commit_id}
if ref
ref.commit
else
repo.commit(commit_id) repo.commit(commit_id)
end
else else
repo.commits(root_ref).first repo.commits(root_ref).first
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment