Last active
December 10, 2015 23:28
-
-
Save artzub/4509035 to your computer and use it in GitHub Desktop.
Work with github api.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.idea/ | |
*.iml | |
*.iws |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* User: ArtZub | |
* Date: 15.01.13 | |
* Time: 2:13 | |
*/ | |
'use strict'; | |
(function(window) { | |
var lastTime = 0; | |
var vendors = ['ms', 'moz', 'webkit', 'o']; | |
for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) { | |
window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame']; | |
window.cancelAnimationFrame = | |
window[vendors[x]+'CancelAnimationFrame'] || window[vendors[x]+'CancelRequestAnimationFrame']; | |
} | |
if (!window.requestAnimationFrame) | |
window.requestAnimationFrame = function(callback, element) { | |
var currTime = new Date().getTime(); | |
var timeToCall = Math.max(0, 16 - (currTime - lastTime)); | |
var id = window.setTimeout(function() { callback(currTime + timeToCall); }, | |
timeToCall); | |
lastTime = currTime + timeToCall; | |
return id; | |
}; | |
if (!window.cancelAnimationFrame) | |
window.cancelAnimationFrame = function(id) { | |
clearTimeout(id); | |
}; | |
})(window); | |
var ONE_SECOND = 1000, | |
ONE_MINUTE = 60 * ONE_SECOND, | |
ONE_HOUR = 60 * ONE_MINUTE, | |
ONE_DAY = 24 * ONE_HOUR, | |
PI_CIRCLE = 2 * Math.PI; | |
var ghcs = { | |
users: {}, | |
states: {cur:0, max:0}, | |
limits: { | |
commits : 100, | |
stepShow : 1, | |
stepType : ONE_DAY | |
}, | |
settings : { | |
access : { | |
client_id : "c45417c5d6249959a91d", | |
client_secret : "4634b3aa7549c3d6306961e819e5ec9b355a6548" | |
}, | |
cs : { | |
fileLife : 255 // number of steps of life a file | |
, userLife : 255 // number of steps of life a user | |
, edgeLife : 255 // number of steps of life a edge | |
, showCountExt : true // show table of file's extension | |
, onlyShownExt : true // show only extension which is shown | |
, showHistogram : true // displaying histogram of changed files | |
, showHalo : true // show a file's halo | |
, padding : 25 // padding around a user | |
, rateOpacity : .5 // rate of decrease of opacity | |
, rateFlash : 2.5 // rate of decrease of flash | |
, sizeFile : 2 // size of file | |
, sizeUser : 24 // size of user | |
, showPaddingCircle : false // show circle of padding | |
, useAvatar : true // show user's avatar | |
, showEdge : true // show a edge | |
, showFile : true // show a file | |
, showUser : true // show a user | |
, showLabel : true // show user name | |
, showFilename : true // show file name TODO: надо-ли? | |
, labelPattern : "%n <%e>" // pattern for label of user | |
, showCommitMessage : false // show commit message | |
, skipEmptyDate : true // skip empty date | |
} | |
}, | |
asyncForEach: function(items, fn, time) { | |
if (!(items instanceof Array)) | |
return; | |
var workArr = items.reverse().concat(); | |
function loop() { | |
if (workArr.length > 0) | |
fn(workArr.shift(), workArr); | |
if (workArr.length > 0) | |
setTimeout(loop, time || 1); | |
} | |
loop(); | |
}, | |
imageHash : d3.map({}) | |
}; | |
(function(ghcs) { | |
ghcs.storage = sessionStorage; | |
if (ghcs.storage) { | |
Storage.prototype.set = function(key, value) { | |
this.setItem(key, JSON.stringify(value)); | |
}; | |
Storage.prototype.get = function(key) { | |
var res = this.getItem(key); | |
return res ? JSON.parse(res) : res; | |
}; | |
Storage.prototype.setImageData = setImageData; | |
} | |
else { | |
ghcs.storage = d3.map({}); | |
ghcs.storage.clear = function() { | |
var ks = ghcs.storage.keys, | |
l = ks.length; | |
while(--l > -1) | |
ghcs.storage.remove(ks[l]); | |
}; | |
ghcs.storage.setImageData = setImageData; | |
} | |
var canvas = document.createElement("canvas"), | |
ctx = canvas.getContext("2d"); | |
/** | |
* @param url {String} | |
* @param image {Image} | |
*/ | |
function setImageData(url, image) { | |
canvas.width = image.width; | |
canvas.height = image.height; | |
ctx.drawImage(image, 0, 0); | |
ghcs.storage.set(url, canvas.toDataURL("image/png")); | |
canvas.width = 0; | |
canvas.height = 0; | |
} | |
})(ghcs); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* User: ArtZub | |
* Date: 15.01.13 | |
* Time: 1:36 | |
*/ | |
'use strict'; | |
var TYPE_REQUEST = { | |
repos : 1, | |
commits : 2 | |
} | |
, TYPE_STATUS_FILE = { | |
removed : 0, | |
modified : 1, | |
added : 2, | |
renamed : 3 | |
} | |
; | |
function makeUrl(url, type, limit) { | |
limit = limit || 0; | |
var sec = "client_id=" + ghcs.settings.access.client_id + "&client_secret=" + ghcs.settings.access.client_secret; | |
if (type == TYPE_REQUEST.repos) { | |
sec += (ghcs.rot ? "&per_page=100&type=" + ghcs.rot : "" ); | |
} | |
else if(type == TYPE_REQUEST.commits) { | |
limit = limit < 0 ? ghcs.limits.commits : limit; | |
sec += "&per_page=" + (limit > 100 ? 100 : limit) | |
} | |
return url ? (url + (url.indexOf('?') === -1 ? '?' : '&') + sec) : url; | |
} | |
function crossUrl(url, rt) { | |
return url; | |
/*var result = url, arr = /(.*)?\?(.*)/.exec(url); | |
if (arr) { | |
result = "http://artzub.com/cross/?" | |
+ ( rt ? "rt=" + rt + "&" : "" ) | |
+ "u=" + arr[1]; | |
if (arr.length > 2) | |
result += "&d=" + encodeURIComponent(arr[2]); | |
} | |
return result;*/ | |
} | |
function randTrue() { | |
return Math.round((Math.random() * 2) % 2); | |
} | |
function getDataFromRequest(req) { | |
return req && req.meta && req.meta.status == 200 && req.data ? req.data : (log(req) && null); | |
} | |
function parseCommit(org_commit, commit){ | |
if (!commit || !org_commit || commit.sha != org_commit.sha) | |
return; | |
var s = commit.stats = { | |
f : { | |
m : 0, | |
a : 0, | |
d : 0 | |
}, | |
changes : 0, | |
additions : 0, | |
deletions : 0 | |
}; | |
commit.files = org_commit.files.map(function(f) { | |
if (TYPE_STATUS_FILE[f.status] == undefined) | |
console.log(f.status); | |
f.status = TYPE_STATUS_FILE[f.status]; | |
if (f.changes > 0) { | |
s.changes += f.changes; | |
s.additions += f.additions; | |
s.deletions += f.deletions; | |
} | |
else if(f.status) { | |
commit.stats.changes++; | |
commit.stats.additions++; | |
} | |
else if(!f.status) { | |
commit.stats.changes -= commit.stats.changes ? 1 : 0; | |
commit.stats.additions -= commit.stats.additions ? 1 : 0; | |
} | |
(f.status == TYPE_STATUS_FILE.modified || f.status == TYPE_STATUS_FILE.renamed) && s.f.m++; | |
f.status == TYPE_STATUS_FILE.added && s.f.a++; | |
!f.status && s.f.d++; | |
return { | |
name : f.filename.toLowerCase(), | |
changes : f.changes || 0, | |
additions : f.additions || 0, | |
deletions : f.deletions || 0, | |
status : f.status | |
} | |
}); | |
ghcs.repo.stats = ghcs.repo.stats || {}; | |
ghcs.repo.stats.changes = d3.max([ghcs.repo.stats.changes || 0, commit.stats.deletions, commit.stats.additions]); | |
ghcs.repo.stats.files = d3.max([ghcs.repo.stats.files || 0, s.f.a + s.f.m, s.f.d]); | |
} | |
function upCommits() { | |
redrawStats(); | |
updateStatus(ghcs.states.cur++); | |
ldrTop.show(); | |
psBar.show(); | |
checkCompleted(); | |
} | |
function preloadImage(url) { | |
var ava, image; | |
image = ghcs.imageHash.get(url); | |
if (!image) { | |
image = new Image(); | |
//ava = ghcs.storage.get(url); | |
//if (!ava) { | |
image.onerror = function () { | |
return console.log(this); | |
}; | |
/*image.onload = (function (url) { | |
return function () { | |
if (url) | |
ghcs.storage.setImageData(url, this); | |
}; | |
})(url);*/ | |
image.src = crossUrl((url || (url = "https://secure.gravatar.com/avatar/" + Date.now() + Date.now() + "?d=identicon&f=y")) + "&s=48", "image"); | |
/*} | |
else { | |
image.src = ava; | |
}*/ | |
ghcs.imageHash.set(url, image); | |
} | |
return image; | |
} | |
function parseCommits(commits) { | |
ghcs.repo.commits = ghcs.repo.commits || d3.map({}); | |
if (commits && commits.length) { | |
updateStatus(ghcs.states.cur); | |
psBar.show(); | |
ldrTop.show(); | |
commits.forEach(function(d, i) { | |
var obj = ghcs.repo.commits.get(d.sha); | |
if (!obj) { | |
obj = { | |
url : d.url, | |
sha : d.sha, | |
author : { | |
name : d.commit.author.name, | |
email : d.commit.author.email, | |
login : d.author && d.author.login ? d.author.login : d.commit.author.email | |
}, | |
committer : { | |
name : d.commit.committer.name, | |
email : d.commit.committer.email, | |
login : d.committer && d.committer.login ? d.committer.login : d.commit.committer.email | |
}, | |
date : Date.parse(d.commit.author.date), | |
avatar_url : (d.author && d.author.avatar_url ? d.author.avatar_url : null), | |
message : d.commit.message, | |
parents : d.parents | |
}; | |
ghcs.repo.commits.set(obj.sha, obj); | |
obj.author.avatar = preloadImage(obj.avatar_url); | |
} | |
if (!obj.files) { | |
JSONP(makeUrl(obj.url), (function(c) { | |
ghcs.repo.dates.push(c.date); | |
ghcs.repo.dates.sort(d3.ascending); | |
return function(req) { | |
parseCommit(getDataFromRequest(req), ghcs.repo.commits.get(c.sha)); | |
upCommits(); | |
}; | |
})(obj), { | |
onerror : function(err) { | |
console.log(err); | |
upCommits(); | |
} | |
}); | |
} | |
else { | |
upCommits(); | |
} | |
}); | |
} | |
else { | |
upCommits(); | |
} | |
} | |
function clearUserRepos() { | |
if (ghcs.users.hasOwnProperty(ghcs.login) && ghcs.users[ghcs.login].hasOwnProperty("repos")) | |
delete ghcs.users[ghcs.login]["repos"] | |
} | |
function parseRepos(data) { | |
if (data) { | |
ghcs.users[ghcs.login] = ghcs.users[ghcs.login] || {}; | |
ghcs.users[ghcs.login].repos = (ghcs.users[ghcs.login].repos || []).concat( | |
data.filter(function (d) { | |
return !d.private && !d.hasOwnProperty("nodeValue"); | |
}).map(function (d) { | |
return { | |
x : (Math.random() * w) || 1, | |
y : (Math.random() * h) || 1, | |
nodeValue : { | |
id: d.id, | |
name: d.name, | |
url: d.url, | |
html_url: d.html_url, | |
commits_url : d.commits_url.replace(/{.*$/, ""), | |
size : d.size, | |
date : Date.parse(d.pushed_at || d.updated_at), | |
cdate : Date.parse(d.created_at), | |
desc : d.description, | |
lang : d.language || "Multi" | |
} | |
}; | |
}) | |
); | |
ghcs.states.cur = ghcs.users[ghcs.login].repos.length; | |
} | |
updateStatus(ghcs.states.cur, "loading ..."); | |
ldrTop.show(); | |
psBar.show(); | |
checkCompleted(); | |
redrawRepos(); | |
} | |
function chSelect(e) { | |
if (e) { | |
ghcs.repo = e.nodeValue; | |
ghcs.repo.dates = []; | |
ghcs.repo.changes = []; | |
runBtn.enable(); | |
curRep.setName(e); | |
} | |
else { | |
ghcs.repo = null; | |
runBtn.disable(); | |
curRep.setName(null); | |
stepsBar.secondStep(); | |
} | |
} | |
function chUser() { | |
if (ghcs.chUserTimer) { | |
clearTimeout(ghcs.chUserTimer); | |
delete ghcs.chUserTimer; | |
} | |
ghcs.chUserTimer = setTimeout((function (login) { | |
return function () { | |
if (login) { | |
stepsBar.firstStep(); | |
curRep.setName(null); | |
vis.clearRepos(); | |
userTxt.disable(); | |
showBtn.disable(); | |
runBtn.disable(); | |
ghcs.login = login; | |
ghcs.repo = null; | |
redrawStats(); | |
ghcs.states.complete = function() { | |
stepsBar.secondStep(); | |
ldrTop.hide(); | |
setTimeout(nextStepApplyParams, 500); | |
}; | |
cbDlr.check(); | |
if (!ghcs.users.hasOwnProperty(login) || !ghcs.users[login].hasOwnProperty("repos")) { | |
ldrTop.show(); | |
JSONP(makeUrl("https://api.github.com/users/" + login), function (req) { | |
var data = getDataFromRequest(req); | |
if (!data) { | |
parseRepos(null); | |
return; | |
} | |
var u = ghcs.users[data.login] = {info: data}; | |
u.info.avatar = new Image();//preloadeImage(u.info.avatar_url); | |
u.info.avatar.src = u.info.avatar_url; | |
ghcs.login = data.login; | |
ghcs.states.max = +u.info.public_repos; | |
ghcs.states.cur = 0; | |
updateStatus(ghcs.states.cur, "loading ..."); | |
psBar.show(); | |
if (data.repos_url) | |
JSONP(makeUrl(data.repos_url, TYPE_REQUEST.repos), function getAll(req) { | |
parseRepos(getDataFromRequest(req)); | |
getNext(req, function(next) { | |
if (next) { | |
ldrTop.show(); | |
JSONP(next, getAll); | |
} | |
}); | |
divStat.updateInfo(); | |
}, { | |
onerror : function(err) { | |
console.log(err); | |
} | |
}); | |
else | |
parseRepos(null); | |
divStat.updateInfo(); | |
}); | |
} | |
else { | |
ghcs.states.max = ghcs.users[login].repos ? ghcs.users[login].repos.length : 0; | |
parseRepos(ghcs.users[login].repos); | |
} | |
divStat.updateInfo(); | |
userTxt.enable(); | |
} | |
} | |
})(userTxt.property("value")), 300); | |
} | |
function getNext(req, fn) { | |
var next; | |
if (req && req.meta && req.meta.Link) { | |
next = req.meta.Link.reduce(function (a, b) { | |
if (!a && b[1].rel == "next") | |
return b[0]; | |
return a; | |
}, null); | |
} | |
fn && fn(next); | |
} | |
function analyseCommits() { | |
runBtn.disable(); | |
ldrTop.show(); | |
ghcs.states.max = ghcs.limits.commits; | |
ghcs.states.cur = 0; | |
ghcs.states.loaded = 0; | |
ghcs.states.complete = function() { | |
stepsBar.thirdStep(); | |
runBtn.enable(); | |
ldrTop.hide(); | |
visBtn.enable(); | |
if (ghcs.repo && ghcs.repo.commits) | |
ghcs.repo.commitsCount = ghcs.repo.commits.values().filter(function(d) { | |
return !!d.files; | |
}).length; | |
vis.redrawStat(ghcs.repo); | |
setTimeout(nextStepApplyParams, 500); | |
}; | |
vis.layers.stat.toFront(); | |
cbDlsr.check(); | |
if (!ghcs.repo || !ghcs.repo.commits_url || ghcs.repo.loadedAll) { | |
updateStatus(ghcs.states.cur = ghcs.states.max); | |
checkCompleted(); | |
return; | |
} | |
JSONP(makeUrl(ghcs.repo.commits_url, TYPE_REQUEST.commits, ghcs.limits.commits), function getAll(req) { | |
getNext(req, function(next) { | |
var l = req && req.data && req.data instanceof Array ? req.data.length : 0; | |
ghcs.states.loaded += l; | |
l = ghcs.states.max - ghcs.states.loaded; | |
if (next && l > 0) { | |
updateStatus(ghcs.states.cur); | |
psBar.show(); | |
ldrTop.show(); | |
JSONP(next.replace("per_page=100", "per_page=" + (l > 100 ? 100 : l)), | |
getAll, { | |
onerror : (function(len) { | |
return function() { | |
ghcs.states.max -= len; | |
}; | |
})(l) | |
}); | |
} | |
else { | |
if (!next) | |
ghcs.repo.loadedAll = true; | |
ghcs.states.max = | |
ghcs.states.loaded; | |
} | |
}); | |
parseCommits(getDataFromRequest(req)); | |
}); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html xmlns="http://www.w3.org/1999/html"> | |
<head> | |
<meta charset="utf-8"> | |
<link rel="stylesheet" href="style.css"> | |
<script src="http://d3js.org/d3.v3.js"></script> | |
<script src="jsonp.js"></script> | |
<script src="ghcs.js"></script> | |
<script src="main.js"></script> | |
<script src="github.js"></script> | |
<script src="vis.js"></script> | |
<script src="stat.js"></script> | |
<script src="repo.js"></script> | |
<script src="langhg.js"></script> | |
<script src="show.js"></script> | |
</head> | |
<body onload="init()"> | |
<header> | |
<div id="controls" class="popup"> | |
<div class="row"> | |
<ul class="steps sfirst"> | |
<li style="z-index: 2" class="first"> | |
<label><strong>1.</strong></label> | |
<input placeholder="User" type="text" id="user"> | |
<button id="showBtn" title="Press for loading data about user repositories." class="btn" disabled="disabled">Show</button> | |
<div class="sub"> | |
<div class="row"> | |
<blockquote>Enter user's login of github.</blockquote> | |
<div class="row"> | |
<ul class="setting"> | |
<li class="field"><h1>Display:</h1> | |
<ul class="group"> | |
<li class="field"> | |
<input id="cb-dllh" type="checkbox" checked="checked"> | |
<label for="cb-dllh">Layer histogram languages</label> | |
</li> | |
</ul> | |
</li> | |
</ul> | |
</div> | |
</div> | |
</div> | |
</li> | |
<li style="z-index: 1" class="second"> | |
<label><strong>2.</strong></label> | |
<label id="curRep"><span>Select Repo...</span></label> | |
<button id="runBtn" title="Press for analyse repository." class="btn" disabled="disabled">Analyse</button> | |
<div class="sub"> | |
<div class="row"> | |
<blockquote>Click to repo in graph of repos.</blockquote> | |
<div class="row"> | |
<ul class="setting"> | |
<li class="field"><h1>Display:</h1> | |
<ul class="group"> | |
<li class="field"> | |
<input id="cb-dlr" type="checkbox" checked="checked"> | |
<label for="cb-dlr">Layer repos</label> | |
</li> | |
<li class="field"> | |
<input id="cb-dlsr" type="checkbox" checked="checked"> | |
<label for="cb-dlsr">Layer stat repo</label> | |
</li> | |
</ul> | |
<ul class="group"> | |
<li class="field"> | |
<input id="cb-dlcmrs" type="checkbox" checked="checked"> | |
<label for="cb-dlcmrs">Layer committers</label> | |
</li> | |
</ul> | |
</li> | |
<li class="field"><h1>Settings:</h1> | |
<ul class="group"> | |
<li class="field"> | |
<label for="txt-lc">Limit of commits</label> | |
<input id="txt-lc" type="number" value="100" max="10000000" min="0" step="1"> | |
</li> | |
</ul> | |
</li> | |
</ul> | |
</div> | |
</div> | |
</div> | |
</li> | |
<li class="third"> | |
<label><strong>3.</strong></label> | |
<button id="visBtn" title="Press for dynamic visualization." class="btn" disabled="disabled"><span class="mono">►</span> Run</button> | |
<button id="visBtnPause" title="Pause" class="btn" style="display: none" disabled="disabled"><span class="mono">▌▌</span>Pause</button> | |
<button id="visBtnStop" title="Stop" class="btn" style="display: none" disabled="disabled"><span class="mono">■</span> Stop</button> | |
<button id="visBtnResume" title="Restart" class="btn" style="display: none" disabled="disabled"><span class="mini-icon mini-icon-history"></span> Restart</button> | |
<div class="sub"> | |
<div class="row"> | |
<blockquote>Select type visualization, change setting and press button run.</blockquote> | |
<div class="row"> | |
<ul class="setting"> | |
<li class="field"><h1>Display:</h1> | |
<ul class="group"> | |
<li class="field"> | |
<input id="cb-dlvml" type="checkbox" checked="checked"> | |
<label for="cb-dlvml">Layer canvas</label> | |
</li> | |
</ul> | |
</li> | |
<li class="field"><h1>Type visualization:</h1> | |
<ul class="group"> | |
<li class="field"> | |
<input name="typeVis" id="rb_lacs" checked="checked" type="radio"> | |
<label for="rb_lacs">Code_swarm</label> | |
</li> | |
<li class="field"> | |
<input name="typeVis" id="rb_lag" type="radio"> | |
<label for="rb_lag">Gource</label> | |
</li> | |
</ul> | |
</li> | |
<li class="field"><h1>Settings:</h1> | |
<ul class="setting" id="st-cs"> | |
<li class="field"><h1>Code_swarm:</h1> | |
<ul class="setting"> | |
<li class="field"><h1>The number of cycles of life element:</h1> | |
<ul class="group"> | |
<li class="field"> | |
<label for="n-cs-userLife">User</label> | |
<input data-ns="cs" id="n-cs-userLife" type="number" step="1" min="0" max="1000000"> | |
</li> | |
<li class="field"> | |
<input data-ns="cs" id="cb-cs-showUser" type="checkbox" checked="checked"> | |
<label for="cb-cs-showUser">visible</label> | |
</li> | |
</ul> | |
<ul class="group"> | |
<li class="field"> | |
<label for="n-cs-fileLife"> File</label> | |
<input data-ns="cs" id="n-cs-fileLife" type="number" step="1" min="0" max="1000000"> | |
</li> | |
<li class="field"> | |
<input data-ns="cs" id="cb-cs-showFile" type="checkbox" checked="checked"> | |
<label for="cb-cs-showFile">visible</label> | |
</li> | |
</ul> | |
<ul class="group"> | |
<li class="field"> | |
<label for="n-cs-edgeLife">Edge</label> | |
<input data-ns="cs" id="n-cs-edgeLife" type="number" step="1" min="0" max="1000000"> | |
</li> | |
<li class="field"> | |
<input data-ns="cs" id="cb-cs-showEdge" type="checkbox"> | |
<label for="cb-cs-showEdge">visible</label> | |
</li> | |
</ul> | |
</li> | |
</ul> | |
<ul class="setting"> | |
<li class="field"><h1>Display:</h1> | |
<ul class="group"> | |
<li class="field"> | |
<input data-ns="cs" id="cb-cs-showCountExt" type="checkbox" checked="checked"> | |
<label for="cb-cs-showCountExt">Legend extension</label> | |
</li> | |
</ul> | |
<ul class="group"> | |
<li class="field"> | |
<input data-ns="cs" id="cb-cs-showHistogram" type="checkbox" checked="checked"> | |
<label for="cb-cs-showHistogram">Changes Histogram</label> | |
</li> | |
</ul> | |
<ul class="group"> | |
<li class="field"> | |
<input data-ns="cs" id="cb-cs-showCommitMessage" type="checkbox" checked="checked"> | |
<label for="cb-cs-showCommitMessage">Commit Messages</label> | |
</li> | |
</ul> | |
<ul class="group"> | |
<li class="field"> | |
<input data-ns="cs" id="cb-cs-onlyShownExt" type="checkbox"> | |
<label for="cb-cs-onlyShownExt">Only current commit extensions</label> | |
</li> | |
</ul> | |
<ul class="group"> | |
<li class="field"> | |
<input data-ns="cs" id="cb-cs-showLabel" type="checkbox" checked="checked"> | |
<label for="cb-cs-showLabel">User's name</label> | |
</li> | |
<li class="field"> | |
<input data-ns="cs" id="cb-cs-showHalo" type="checkbox" checked="checked"> | |
<label for="cb-cs-showHalo">Halo</label> | |
</li> | |
</ul> | |
<ul class="group"> | |
<!--<li class="field"> | |
<input id="cb-cs-showFilename" type="checkbox" checked="checked"> | |
<label for="cb-cs-showFilename">Show file's name</label> | |
</li>--> | |
</ul> | |
<ul class="group"> | |
<li class="field"> | |
<input data-ns="cs" id="cb-cs-showPaddingCircle" type="checkbox"> | |
<label for="cb-cs-showPaddingCircle">Circle of padding</label> | |
</li> | |
</ul> | |
</li> | |
</ul> | |
<ul class="setting"> | |
<li class="field"><h1>Rate of decrease of:</h1> | |
<ul class="group"> | |
<li class="field"> | |
<label for="n-cs-rateFlash">Flash</label> | |
<input data-ns="cs" id="n-cs-rateFlash" type="number" step="0.5" min="0" max="100"> | |
</li> | |
</ul> | |
<ul class="group"> | |
<li class="field"> | |
<label for="n-cs-rateOpacity">Opacity</label> | |
<input data-ns="cs" id="n-cs-rateOpacity" type="number" step="0.5" min="0" max="100"> | |
</li> | |
</ul> | |
</li> | |
</ul> | |
<ul class="setting"> | |
<li class="field"><h1>Size of:</h1> | |
<ul class="group"> | |
<li class="field"> | |
<label for="n-cs-sizeUser">User</label> | |
<input data-ns="cs" id="n-cs-sizeUser" type="number" step="0.1" min="0.1" max="100"> | |
</li> | |
</ul> | |
<ul class="group"> | |
<li class="field"> | |
<label for="n-cs-sizeFile">File (initial)</label> | |
<input data-ns="cs" id="n-cs-sizeFile" type="number" step="0.1" min="0.1" max="100"> | |
</li> | |
</ul> | |
</li> | |
</ul> | |
<ul class="group"> | |
<li class="field"> | |
<label for="n-cs-padding">Padding around a user</label> | |
<input data-ns="cs" id="n-cs-padding" type="number" step="0.1" min="0" max="100"> | |
</li> | |
</ul> | |
<ul class="group"> | |
<li class="field"> | |
<label for="txt-cs-labelPattern">Pattern for label of user</label> | |
<input data-ns="cs" id="txt-cs-labelPattern" type="text" value="%n <%e>"> | |
<blockquote>%n - name; %e - email; %l - login</blockquote> | |
</li> | |
</ul> | |
<ul class="group"> | |
<li class="field"> | |
<input data-ns="cs" id="cb-cs-useAvatar" type="checkbox" checked="checked"> | |
<label for="cb-cs-useAvatar">Use user's avatar</label> | |
</li> | |
</ul> | |
<ul class="group"> | |
<li class="field"> | |
<input data-ns="cs" id="cb-cs-skipEmptyDate" type="checkbox" checked="checked"> | |
<label for="cb-cs-skipEmptyDate">Skip empty date</label> | |
</li> | |
</ul> | |
</li> | |
</ul> | |
</li> | |
</ul> | |
</div> | |
</div> | |
</div> | |
</li> | |
</ul> | |
</div> | |
</div> | |
<div id="userInfo" class="popup tooltip"> | |
<div class="row" id="divStat"></div> | |
</div> | |
</header> | |
<!--https://github.com/images/spinners/octocat-spinner-128.gif--> | |
<!--data:image/gif;base64,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--> | |
<div id="ldrCont" class="popup" style="display: none"><img id="ldrTop" src="octocat-spinner-128.gif"></div> | |
<div id="about" class="popup" style="display: none;"> | |
<div class="row"> | |
<h1>The visualization the history of repositories from the Github</h1> | |
</div> | |
<div class="row"> | |
</div> | |
<div class="row"> | |
<hr> | |
Create by <a href="http://artzub.com">Artem Zubkov</a> (<a href="mailto:[email protected]" title="Write me...">[email protected]</a>) | |
<br /> | |
Powered by <a href="http://d3js.org" title="Perfect javascript framework">D3.js</a> | |
</div> | |
</div> | |
<div id="tooltip" class="popup tooltip"></div> | |
<div id="layers"> | |
<div id="canvas"></div> | |
<div id="svg"></div> | |
</div> | |
<footer> | |
<div id="statusBar" class="popup"> | |
<ul> | |
<li class="progressBar"> | |
<div class="meter orange" style="display: none"> | |
<span id="progressBar" style="width: 0%"></span> | |
</div> | |
</li> | |
</ul> | |
</div> | |
<div id="console" class="popup"></div> | |
</footer> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* repo https://github.com/artzub/JSONP | |
*/ | |
(function(window) { | |
if (!window || !window.document) | |
return; | |
var seq = 0, // sequent | |
document = window.document; | |
/** | |
* JSONP | |
* @param {String} uri The URL you are requesting with the JSON data (you may include URL params). | |
* @param {Function} callback The callback function which you want to execute for JSON data (JSON response is first argument). | |
* @param {Object} params The params contains data about callback param's name, onload function and onerror function. | |
* Params have next structure: | |
* params = { | |
* callbackParam : '', default is callback | |
* onerror_callback : function() {}, | |
* onload_callback : function() {}, | |
* script_order : 'defer' | 'async' (is default) | |
*} | |
*/ | |
window.JSONP = function(uri, callback, params) { | |
if (!arguments.length || arguments.length < 2) | |
return; | |
uri = uri || ''; | |
callback = callback || function() {}; | |
params = params || {}; | |
params.callbackParam = params.callbackParam || 'callback' | |
uri += uri.indexOf('?') === -1 ? '?' : '&'; | |
function clear() { | |
try { | |
delete window[id]; | |
} catch(e) { | |
window[id] = null; | |
} | |
document.documentElement.removeChild(script); | |
} | |
function response() { | |
clear(); | |
callback.apply(this, arguments); | |
} | |
function doError() { | |
clear(); | |
params.onerror && params.onerror.apply(this, arguments); | |
} | |
function doLoad() { | |
params.onload && params.onload.apply(this, arguments); | |
} | |
var id = '_JSONP_' + seq++, | |
script = document.createElement('script'); | |
window[id] = response; | |
params.script_order = params.script_order || 'async'; | |
script.onload = doLoad; | |
script.onerror = doError; | |
script.setAttribute(params.script_order, params.script_order); | |
script.setAttribute('src', uri + params.callbackParam + '=' + id); | |
document.documentElement.insertBefore( | |
script, | |
document.documentElement.lastChild | |
); | |
} | |
})(window); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Created with IntelliJ IDEA. | |
* User: ArtZub | |
* Date: 23.01.13 | |
* Time: 13:32 | |
* To change this template use File | Settings | File Templates. | |
*/ | |
'use strict'; | |
(function(vis) { | |
vis.clearLangHg = function() { | |
vis.layers && vis.layers.repo && vis.layers.repo.langHg && vis.layers.repo.langHg.selectAll("*") | |
.transition() | |
.duration(750) | |
.ease("elastic") | |
.remove(); | |
}; | |
vis.redrawLangHg = function(data, layout) { | |
layout = layout || vis.layers.repo; | |
if (!data) { | |
vis.clearLangHg(); | |
return; | |
} | |
data = data.sort(function(a, b) { | |
return d3.ascending(a.key, b.key); | |
}); | |
var w_hg = w / 4, | |
h_hg = h / 6, | |
m = {left : 10, top : 10, right : 10, bottom : 10}, | |
pos = {top : h - h_hg - m.bottom - m.top - margin.bottom, left : margin.left}; | |
var x = d3.scale.ordinal() | |
.rangeRoundBands([0, 28 * data.length], .2) | |
.domain(data.map(function(d) { return d.key; })); | |
var xc = x.rangeBand() / 2; | |
var y = d3.scale.linear() | |
.domain([0, d3.max(data, function(d) { return d.values.length; })]) | |
.range([h_hg, 0]); | |
if (layout.langHg && layout.langHg.empty()) | |
layout.langHg = null; | |
layout.langHg = (layout.langHg || layout.insert("g", ":first-child")) | |
.attr("class", "langHg") | |
.attr("width", w_hg + m.left + m.right) | |
.attr("height", h_hg + m.top + m.bottom) | |
.attr("transform", "translate(" + pos.left + "," + pos.top + ")"); | |
function mei(d) { | |
d._g | |
&& d._g.selectAll("circle") | |
.style("stroke", d3.rgb(colors.decolor).darker()) | |
.style("fill", toRgba(colors.decolor, vis.forceRep.opt(vis.forceRep.radO(d)))) | |
&& d._g.selectAll("text") | |
.style("fill", d3.rgb(colors.decolor).darker()); | |
} | |
function moi(d) { | |
d._g | |
&& d._g.selectAll("circle") | |
.style("stroke", d3.rgb(vis.forceRep.colors(d.nodeValue.lang))) | |
.style("fill", toRgba(vis.forceRep.colors(d.nodeValue.lang), vis.forceRep.opt(vis.forceRep.radO(d)))) | |
&& d._g.selectAll("text") | |
.style("fill", d3.rgb(vis.forceRep.colors(d.nodeValue.lang)).brighter()); | |
} | |
function me(d) { | |
vis.forceRep.nodes().filter(function(k) { | |
return k.nodeValue.lang != d.key; | |
}).forEach(mei); | |
} | |
function mo(d) { | |
vis.forceRep.nodes().filter(function(k) { | |
return k.nodeValue.lang != d.key; | |
}).forEach(moi); | |
} | |
function appendItems(g) { | |
g.append("path") | |
.attr("class", "hLine") | |
.style("stroke", "rgba(255, 255, 255, .3)"); | |
g.append("text") | |
.attr("class", "tLang") | |
.style("fill", function(d) { return d3.rgb(vis.forceRep.colors(d.key)); }) | |
.attr("dy", ".33em") | |
.attr("dx", "-6px") | |
.attr("transform", "rotate(90)") | |
.style("text-anchor", "end") | |
.text(function(d) { return d.key; }) | |
.each(function() { | |
var pr = d3.select(this.parentNode); | |
pr.insert("rect", ":first-child") | |
.attr("class", "barSelect") | |
.attr("fill", "rgba(244, 244, 244, .2)"); | |
}); | |
var gg = g.append("g") | |
.attr("class", "barChain"); | |
gg.append("path") | |
.attr("class", "vLine") | |
.style("stroke", function(d) { return d3.rgb(vis.forceRep.colors(d.key)).darker(); }) | |
.attr("d", "M0,0 L0,0"); | |
gg.append("circle") | |
.style("fill", function(d) { return d3.rgb(vis.forceRep.colors(d.key)).darker(); }) | |
.attr("r", 2); | |
var dg = gg.append("g") | |
.attr("class", "dCircle") | |
.attr("transform", "translate(" + [0 , 0] + ")"); | |
dg.append("circle") | |
.style("fill", function(d) { return d3.rgb(vis.forceRep.colors(d.key)); }) | |
.style("stoke", function(d) { return d3.rgb(vis.forceRep.colors(d.key)).darker(); }) | |
; | |
dg.append("text") | |
.attr("text-anchor", "middle") | |
.attr("dy", ".32em") | |
.style("fill", function(d) { return d3.rgb(vis.forceRep.colors(d.key)).brighter(); }) | |
; | |
} | |
var bar = layout.langHg.selectAll(".barLang") | |
.data(data, function(d) { return d.key; }); | |
bar.exit().remove(); | |
bar.enter() | |
.append("g") | |
.attr("transform", "translate(" + [0 , -xc * 2] + ")") | |
.attr("class", "barLang") | |
.on("mouseover", me) | |
.on("mouseout", mo) | |
.call(appendItems); | |
bar.transition() | |
.duration(3500) | |
.ease("elastic") | |
.attr("transform", function(d) { return "translate(" + [x(d.key) , -xc * 2] + ")"; }) | |
bar.each(function(k) { | |
d3.select(this).selectAll("*") | |
.datum(k); | |
}); | |
bar.selectAll("path.hLine") | |
.attr("d", "M0,0 L" + (xc * 2) + ",0"); | |
bar.selectAll("text.tLang") | |
.attr("y", -xc) | |
.each(function(d) { | |
var pr = d3.select(this.parentNode); | |
pr.selectAll("rect.barSelect") | |
.attr("transform", "translate(" + [-xc * .2 , -(this.clientWidth + 6 + xc * .4) ] + ")") | |
.attr("width", xc * 2.4 ) | |
.attr("height", (this.clientWidth + 6 + xc * .4) + h_hg - y(d.values.length) + xc * 2.4); | |
}); | |
var gg = bar.selectAll("g.barChain") | |
.attr("transform", "translate(" + [x.rangeBand() / 2 , 0] + ")"); | |
var dg = gg.selectAll("g.dCircle"); | |
dg.selectAll("circle") | |
.attr("r", xc); | |
dg.selectAll("text") | |
.text(function(d) { return d.values.length; }); | |
dg.transition() | |
.delay(100) | |
.duration(3500) | |
.ease("elastic") | |
.attr("transform", function(d) { | |
return "translate(" + [0 , h_hg - y(d.values.length) + xc] + ")"; | |
}); | |
gg.selectAll("path.vLine").transition() | |
.duration(3500) | |
.ease("elastic") | |
.attr("d", function(d) { return "M0,0 L0," + (h_hg - y(d.values.length) + xc); }); | |
} | |
})(vis || (vis = {})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* User: ArtZub | |
* Date: 11.01.13 | |
* Time: 21:41 | |
*/ | |
'use strict'; | |
var timeFormat = (function() { | |
var fd = d3.time.format("%b %d, %Y"); | |
return function(ms) { | |
return fd(new Date(ms)); | |
} | |
})(); | |
var log; | |
var cs, svg_cs, svg, | |
margin = {top: 20, right: 20, bottom: 20, left: 20}, | |
w, h, stackLoad = 0, | |
psBar, runBtn, ldrTop, toolTip, showBtn, visBtn, | |
userTxt, curRep, divStat, stepsBar, cbDlr, cbDlsr; | |
function updateStatus(pos, label) { | |
pos = pos > ghcs.states.max ? ghcs.states.max : pos; | |
psBar.setPos((pos * 100 / (ghcs.states.max || 1)) + "%") | |
.setLabel(label || "Completed " + pos + " of " + ghcs.states.max + " commits ..."); | |
} | |
d3.select(window).on("hashchange", applyParams); | |
function parseParams(hash) { | |
var params = {}; | |
hash.replace(/^#/, "").split("&").forEach(function(item) { | |
var values = item.split("="); | |
var key = values[0].toLowerCase(); | |
params[key] = values.length > 1 ? values[1] : ""; | |
}); | |
ghcs.params = params; | |
ghcs.params.climit = params.climit || ghcs.limits.commits; | |
} | |
function rewriteHash() { | |
var step, | |
hash = []; | |
if (this == showBtn.node() && ghcs.params) { | |
step = 0; | |
} | |
else if (this == runBtn.node() && ghcs.params) { | |
step = 1; | |
} | |
switch (step) { | |
case 1: | |
ghcs.params.repo = ghcs.repo ? ghcs.repo.name : null; | |
ghcs.params.repo && hash.push("repo=" + ghcs.params.repo); | |
ghcs.params.climit > 0 && hash.push("climit=" + ghcs.params.climit); | |
case 0: | |
ghcs.params.user && hash.push("user=" + ghcs.params.user); | |
ghcs.params.rot && hash.push("rot=" + ghcs.params.rot); | |
break; | |
} | |
document.location.hash = "#" + hash.join("&"); | |
} | |
function applyParams() { | |
d3.event && d3.event.preventDefault(); | |
parseParams(document.location.hash); | |
stackLoad = stackLoad-- < 1 ? 0 : stackLoad; | |
if (ghcs.rot != ghcs.params.rot || ghcs.login != ghcs.params.user) { | |
ghcs.rot = ghcs.params.rot; | |
userTxt.property("value", ghcs.params.user); | |
ghcs.user = null; | |
if (ghcs.params.repo) | |
stackLoad++; | |
chUser(); | |
} | |
else if (ghcs.user && ghcs.user.repos) { | |
// && (!ghcs.repo || ghcs.repo.name != ghcs.params.repo || (ghcs.params.climit > 0 && ghcs.limits.commits != ghcs.params.climit)) | |
var r; | |
ghcs.limits.commits = ghcs.params.climit || ghcs.limits.commits; | |
d3.select("#txt-lc").property("value", ghcs.limits.commits); | |
if (!ghcs.repo | |
|| ghcs.repo.name != ghcs.params.repo | |
|| !ghcs.repo.commits | |
|| (!ghcs.repo.loadedAll && ghcs.repo.commitsCount < ghcs.limits.commits)) { | |
if (ghcs.repo && ghcs.repo.name == ghcs.params.repo) | |
r = ghcs.repo; | |
else | |
r = ghcs.user.repos.reduce(function(a, b) { | |
if (!a && b.nodeValue.name == ghcs.params.repo) | |
a = b; | |
return a; | |
}, null) | |
; | |
} | |
if (r) { | |
if (ghcs.repo != r) { | |
vis.meRepo(r); | |
vis.clRepo(r); | |
vis.mlRepo(r); | |
} | |
} | |
analyseCommits(); | |
} | |
} | |
function nextStepApplyParams() { | |
if (stackLoad) | |
applyParams(); | |
} | |
function chRadio(d) { | |
switch(this.name) { | |
case "participation" : { | |
} | |
} | |
} | |
function chCheckbox(d) { | |
var ln; | |
d = d3.select(this); | |
switch(d.attr("id")) { | |
case "cb-dlr": | |
case "cb-dlsr": | |
ln = d.datum(); | |
vis.layers[ln] | |
&& ((d.property("checked") && vis.layers[ln].show()) || vis.layers[ln].hide()); | |
break; | |
case "cb-dllh": | |
vis.layers.repo | |
&& vis.layers.repo.langHg | |
&& vis.layers.repo.langHg.style("display", d.property("checked") ? null : "none"); | |
break; | |
case "cb-dlvml": | |
d.property("checked") ? cs.show() : cs.hide(); | |
break; | |
default : | |
(ln = d.datum()) && ln.ns | |
&& (ln.ns[ln.key] = d.property("checked")); | |
break; | |
} | |
} | |
function chValue(d) { | |
var ln; | |
d = d3.select(this); | |
(ln = d.datum()) && ln.ns | |
&& (ln.ns[ln.key] = d.property("value")); | |
} | |
function checkCompleted() { | |
if (ghcs.states.cur >= ghcs.states.max) { | |
psBar.setPos("100%").hide(); | |
if (ghcs.states.complete) | |
ghcs.states.complete(); | |
return true; | |
} | |
return false; | |
} | |
function redrawStats() { | |
if (ghcs.redrawStatsTimer) { | |
clearTimeout(ghcs.redrawStatsTimer); | |
ghcs.redrawStatsTimer = null; | |
} | |
ghcs.redrawStatsTimer = setTimeout(function () { | |
vis.redrawStat(ghcs.repo); | |
ghcs.redrawStatsTimer = null; | |
}, 100); | |
} | |
function runShow() { | |
if (ghcs.repo && ghcs.repo.commits) { | |
visBtn.disable(); | |
vis.runShow(ghcs.repo); | |
} | |
} | |
function redrawRepos() { | |
if (ghcs.redrawReposTimer) { | |
clearTimeout(ghcs.redrawReposTimer); | |
ghcs.redrawReposTimer = null; | |
} | |
ghcs.redrawReposTimer = setTimeout(function () { | |
vis.redrawRepos(ghcs.users | |
&& ghcs.users[ghcs.login] | |
&& ghcs.users[ghcs.login].repos | |
? ghcs.users[ghcs.login].repos | |
: null | |
); | |
vis.redrawLangHg(ghcs.users | |
&& ghcs.users[ghcs.login] | |
&& ghcs.users[ghcs.login].repos | |
? d3.nest().key(function(d) { return d.nodeValue.lang; }).entries(ghcs.users[ghcs.login].repos) | |
: null); | |
ghcs.redrawReposTimer = null; | |
}, 100); | |
} | |
function init() { | |
log = (function () { | |
var logCont = d3.select("#console") | |
.append("ul"); | |
return function (msg) { | |
logCont.append("li").text(msg instanceof Object ? JSON.stringify(msg) : msg); | |
} | |
})(); | |
cs = d3.select("#canvas"); | |
cs.hide = function() { | |
this.style("display", "none"); | |
vis.inited && vis.layers.show.hide(); | |
return this; | |
}; | |
cs.show = function() { | |
this.style("display", null); | |
vis.inited && vis.layers.show.show(); | |
return this; | |
}; | |
svg_cs = d3.select("#svg"); | |
svg = svg_cs.append("svg"); | |
w = svg.property("clientWidth") || document.body.clientWidth; | |
h = svg.property("clientHeight")|| document.body.clientHeight; | |
svg.attr("width", w).attr("height", h); | |
d3.selectAll("input").datum(function() { | |
var obj = null; | |
if (this.dataset && this.dataset.ns) { | |
var reg = new RegExp("(cb|n|txt)-" + this.dataset.ns + "-"); | |
obj = { | |
ns : ghcs.settings[this.dataset.ns], | |
key : this.id.replace(reg, "") | |
}; | |
if (this.type == "checkbox") { | |
this.checked = obj.ns[obj.key]; | |
} | |
else { | |
this.value = obj.ns[obj.key]; | |
} | |
} | |
return obj; | |
}); | |
d3.selectAll("input[type=checkbox]").on("change", chCheckbox); | |
d3.selectAll("input[type=number], input[type=text]").on("change", chValue); | |
psBar = d3.select("#progressBar"); | |
psBar.pntNode = d3.select(psBar.node().parentNode); | |
psBar.show = function() { | |
this.pntNode.style("display", null); | |
return this; | |
}; | |
psBar.hide = function() { | |
this.pntNode.style("display", "none"); | |
return this; | |
}; | |
psBar.setLabel = function(lbl) { | |
this.text(lbl); | |
return this; | |
}; | |
psBar.setPos = function(pos) { | |
this.style("width", pos); | |
return this; | |
}; | |
stepsBar = d3.select(".steps"); | |
stepsBar.firstStep = function() { | |
this.attr("class", "steps sfirst"); | |
return this; | |
}; | |
stepsBar.secondStep = function() { | |
this.attr("class", "steps ssecond"); | |
return this; | |
}; | |
stepsBar.thirdStep = function() { | |
this.attr("class", "steps"); | |
return this; | |
}; | |
runBtn = d3.select("#runBtn"); | |
showBtn = d3.select("#showBtn"); | |
visBtn = d3.select("#visBtn"); | |
userTxt = d3.select("#user").on("change", function() { | |
stepsBar.firstStep(); | |
showBtn.disable(); | |
if (this.value) { | |
if (this.value != ghcs.login) | |
showBtn.enable(); | |
else | |
stepsBar.secondStep(); | |
} | |
(ghcs.params || (ghcs.params = {})).user = this.value; | |
}); | |
[runBtn, showBtn, userTxt, visBtn].forEach(function(item) { | |
item.enable = function () { | |
this.attr("disabled", null); | |
return this; | |
}; | |
item.disable = function () { | |
this.attr("disabled", "disabled"); | |
return this; | |
}; | |
}); | |
runBtn.on("click", rewriteHash); | |
showBtn.on("click", rewriteHash); | |
visBtn.on("click", runShow); | |
ldrTop = d3.select("#ldrTop"); | |
ldrTop.pntNode = d3.select(ldrTop.node().parentNode); | |
ldrTop.show = function () { | |
this.pntNode.style("display", null); | |
return this; | |
}; | |
ldrTop.hide = function () { | |
this.pntNode.style("display", "none"); | |
return this; | |
}; | |
toolTip = d3.select("#tooltip"); | |
toolTip.show = function () { | |
this.style("display", "block"); | |
return this; | |
}; | |
toolTip.hide = function () { | |
this.style("display", null); | |
return this; | |
}; | |
cbDlr = d3.select("#cb-dlr").datum("repo"); | |
cbDlsr = d3.select("#cb-dlsr").datum("stat"); | |
[cbDlr, cbDlsr].forEach(function(item) { | |
item.check = function() { | |
this.property("checked", true); | |
chCheckbox.apply(this.node()); | |
}; | |
item.uncheck = function() { | |
this.property("checked", false); | |
chCheckbox.apply(this.node()); | |
}; | |
item.trigger = function() { | |
this.property("checked", !this.property("checked")); | |
chCheckbox.apply(this.node()); | |
}; | |
}); | |
d3.select("#txt-lc").on("change", function() { | |
(ghcs.params || (ghcs.params = {})).climit = +this.value; | |
if (ghcs.params.climit < 1) | |
ghcs.params.climit = ghcs.limits.commits; | |
}); | |
initGraphics(svg); | |
curRep = d3.select("#curRep") | |
.on("mouseover", function(d) { | |
if (d) { | |
vis.meRepo(d); | |
vis.mtt(d, null, null, {pageX : d.x, pageY : d.y}); | |
} | |
}) | |
.on("mouseout", function(d) { | |
if (d) | |
vis.mlRepo(d); | |
}); | |
curRep.setName = function(r) { | |
this.selectAll("*").remove(); | |
this.datum(r); | |
if (!r) | |
this.append("span") | |
.text("Select Repo..."); | |
else { | |
this.append("span") | |
.style("color", d3.rgb(vis.forceRep.colors(r.nodeValue.lang)).brighter()) | |
.attr("class", "mega-icon mega-icon-public-repo"); | |
this.append("strong") | |
.style("margin-right", "5px") | |
.style("text-shadow", "0 0 3px rgba(0, 0, 0, 1)") | |
.style("color", d3.rgb(vis.forceRep.colors(r.nodeValue.lang)).brighter()) | |
.text((r.nodeValue.name || "")); | |
this.append("a") | |
.attr("target", "_blank") | |
.attr("title", "Go to Github") | |
.attr("href", (r.nodeValue.html_url || "#")) | |
.attr("class", "mega-icon mini-icon-link a-icon"); | |
} | |
return this; | |
}; | |
divStat = d3.select("#divStat"); | |
divStat.updateInfo = function() { | |
var user; | |
if (ghcs.login && (user = ghcs.user = ghcs.users[ghcs.login]) && user.info) { | |
divStat.selectAll("*").remove(); | |
user.info.avatar && divStat.node().appendChild(user.info.avatar); | |
divStat.append("ul") | |
.call(function(ul) { | |
(user.info.name || user.info.login) && ul.append("li").call(function(li) { | |
li.append("h1") | |
.text((user.info.name || user.info.login)) | |
.append("a") | |
.attr("class", "a-icon") | |
.attr("target", "_blank") | |
.attr("title", "Go to GitHub") | |
.attr("href", user.info.html_url) | |
.append("span") | |
.attr("class", "mini-icon mini-icon-octocat") | |
; | |
li.append("hr"); | |
}); | |
user.info.location && ul.append("li") | |
.html("<span class='mini-icon mini-icon-location'></span><strong>" + user.info.location + "</strong>") | |
user.info.blog && ul.append("li") | |
.call(function(li) { | |
li.append("span") | |
.attr("class", "mini-icon mini-icon-link"); | |
li.append("a") | |
.attr("target", "_blank") | |
.attr("href", user.info.blog) | |
.text(user.info.blog) | |
}); | |
ul.append("li") | |
.call(function(li) { | |
li.append("span") | |
.attr("class", "mini-icon mini-icon-public-repo") | |
li.append("strong") | |
.text(user.info.public_repos) | |
}); | |
user.info.updated_at && ul.append("li") | |
.call(function(li) { | |
li.append("span") | |
.attr("class", "mini-icon mini-icon-time"); | |
li.append("strong") | |
.text(timeFormat(Date.parse(user.info.updated_at))) | |
}); | |
}) | |
} | |
}; | |
applyParams(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* User: ArtZub | |
* Date: 23.01.13 | |
* Time: 13:29 | |
*/ | |
'use strict'; | |
(function(vis) { | |
vis.mdRepo = function(d) { | |
}; | |
vis.meRepo = function(d) { | |
vis.layers.repo.langHg | |
&& vis.layers.repo.langHg.style("pointer-events", "none"); | |
vis.layers.repo.toFront(); | |
d._tg = (d._g || (d._g = d3.select(this))); | |
d._tg.selectAll("circle") | |
.style("fill", d3.rgb(vis.forceRep.colors(d.nodeValue.lang)).brighter()); | |
d._tg.selectAll("text") | |
.style("fill", function(d) { | |
return d3.rgb(vis.forceRep.colors(d.nodeValue.lang)).darker(); | |
}) | |
.style("visibility", "visible"); | |
toolTip.selectAll("*").remove(); | |
toolTip.append("h1") | |
.text(d.nodeValue.name); | |
toolTip.append("hr"); | |
d.nodeValue.desc | |
&& toolTip.append("blockquote") | |
.text(d.nodeValue.desc) | |
&& toolTip.append("br") | |
; | |
toolTip.append("span") | |
.attr("class", "mini-icon mini-icon-time") | |
toolTip.append("strong") | |
.style("margin-left", "5px") | |
.text(timeFormat(d.nodeValue.date)); | |
toolTip.append("br"); | |
toolTip.append("span") | |
.text("Primary language: ") | |
.append("strong") | |
.style("color", vis.forceRep.colors(d.nodeValue.lang)) | |
.style("text-shadow", "0 0 3px rgba(0, 0, 0, 0.8)") | |
.text(d.nodeValue.lang); | |
toolTip.show(); | |
}; | |
vis.mlRepo = function(d, i) { | |
if (vis.forceRep.selected && vis.forceRep.selected == d && i !== "deselect") { | |
vis.muRepo(d); | |
} | |
else { | |
var g = d._tg || d._g; | |
if (!g) | |
return; | |
g.selectAll("circle") | |
.style("fill", toRgba(vis.forceRep.colors(d.nodeValue.lang), vis.forceRep.opt(vis.forceRep.radO(d)))); | |
g.selectAll("text") | |
.style("fill", function(d) { | |
return d3.rgb(vis.forceRep.colors(d.nodeValue.lang)).brighter(); | |
}) | |
.style("visibility", vis.forceRep.visible); | |
d._tg = null; | |
} | |
vis.layers.repo.langHg | |
&& vis.layers.repo.langHg.style("pointer-events", "all"); | |
toolTip.hide(); | |
}; | |
vis.clRepo = function(d) { | |
if (vis.forceRep.selected && vis.forceRep.selected == d) { | |
vis.forceRep.selected = null; | |
d && (d.fixed = 4); | |
} | |
else { | |
if (vis.forceRep.selected) { | |
vis.forceRep.selected.fixed = 0; | |
vis.mlRepo(vis.forceRep.selected, "deselect"); | |
toolTip.show(); | |
vis.layers.repo.langHg | |
&& vis.layers.repo.langHg.style("pointer-events", "none"); | |
} | |
vis.forceRep.selected = d; | |
d && (d.fixed = true); | |
} | |
chSelect(vis.forceRep.selected); | |
}; | |
vis.muRepo = function(d){ | |
}; | |
vis.clearRepos = function() { | |
if (vis.forceRep) { | |
vis.forceRep.stop().nodes([]); | |
delete vis.forceRep; | |
} | |
vis.layers && vis.layers.repo && vis.layers.repo.selectAll("*") | |
.transition() | |
.duration(750) | |
.ease("elastic") | |
.remove(); | |
vis.layers.repo.langHg = null; | |
}; | |
vis.redrawRepos = function(data, layout) { | |
layout = layout || vis.layers.repo; | |
if (!data) { | |
vis.clearRepos(); | |
return; | |
} | |
function tr(d) { | |
return "translate(" + [d.x, d.y] + ")"; | |
} | |
vis.forceRep = vis.forceRep || d3.layout.force() | |
.size([w, h]) | |
.friction(.99) | |
.gravity(.005) | |
.charge(function(d) { return -vis.forceRep.radius(vis.forceRep.rad(d)) / 2; }) | |
.on("tick", tick) | |
; | |
vis.forceRep.dateNow = Date.now(); | |
vis.forceRep.rad = vis.forceRep.rad || function (d) { | |
return d.nodeValue.cdate; | |
}; | |
vis.forceRep.radO = vis.forceRep.radO || function (d) { | |
return d.nodeValue.date - vis.forceRep.dateNow; | |
}; | |
data = data.sort(function(a, b) { return a.nodeValue.date - b.nodeValue.date; }); | |
var kof = (h > w ? h : w) / (4 * ((Math.log(data.length || 1) / Math.log(1.5)) || 1)); | |
var r = [kof / 5, kof]; | |
(vis.forceRep.radius || (vis.forceRep.radius = d3.scale.linear())) | |
.range(r) | |
.domain(d3.extent(data, vis.forceRep.rad)); | |
data.length == 1 && vis.forceRep.radius.domain([vis.forceRep.radius.domain()[0] - 1, vis.forceRep.radius.domain()[1]]); | |
(vis.forceRep.opt || (vis.forceRep.opt = d3.scale.log().range([.01,.9]))) | |
.domain( | |
d3.extent(data, vis.forceRep.radO) | |
// [d3.min(data, vis.forceRep.radO), vis.forceRep.dateNow] | |
); | |
vis.forceRep.colors = vis.reposColors || (vis.reposColors = d3.scale.category20()); | |
vis.forceRep.visible = vis.forceRep.visible || function(d) { | |
return this.clientWidth < vis.forceRep.radius(vis.forceRep.rad(d)) * 2.1 ? null : "hidden"; | |
}; | |
vis.forceRep.appCT = vis.forceRep.appCT || function(g) { | |
g.each(function(d) { | |
d._g = d3.select(this); | |
}); | |
g.append("circle") | |
.attr("r", 0); | |
g.append("text") | |
.attr("text-anchor", "middle") | |
.attr("dy", ".31em") | |
.text(function(d) { return d.nodeValue.name; }); | |
}; | |
vis.forceRep.upCT = vis.forceRep.upCT || function(g) { | |
g.selectAll("circle") | |
.style("stroke-width", 1) | |
.style("stroke", function(d) { return d3.rgb(vis.forceRep.colors(d.nodeValue.lang)); }) | |
.style("fill", function(d) { return toRgba(d3.rgb(vis.forceRep.colors(d.nodeValue.lang)), vis.forceRep.opt(vis.forceRep.radO(d))); }) | |
.transition() | |
.duration(2500) | |
.ease("elastic") | |
.attr("r", function(d) { return vis.forceRep.radius(vis.forceRep.rad(d)); }) | |
g.selectAll("text") | |
.style("fill", function(d) { | |
return d3.rgb(vis.forceRep.colors(d.nodeValue.lang)).brighter(); | |
}) | |
.style("visibility", vis.forceRep.visible); | |
}; | |
vis.forceRep | |
.stop() | |
.nodes(data) | |
.start() | |
; | |
vis.forceRep.circle = layout.selectAll(".cRepo") | |
.data(data, function(d) { return d.nodeValue.id }) | |
; | |
vis.forceRep.circle.enter() | |
.append("g") | |
.attr("class", "cRepo") | |
.attr("transform", tr) | |
.call(vis.forceRep.drag) | |
.on("mouseover.select", vis.meRepo) | |
.on("mouseout.select", vis.mlRepo) | |
.on("mousedown.select", vis.mdRepo) | |
.on("mouseup.select", vis.muRepo) | |
.on("mousemove.mtt", vis.mtt) | |
.on("click.select", vis.clRepo) | |
.call(vis.forceRep.appCT); | |
vis.forceRep.circle.call(vis.forceRep.upCT); | |
vis.forceRep.circle.exit().remove(); | |
function tick(e) { | |
var quadtree = d3.geom.quadtree(vis.forceRep.nodes()); | |
vis.forceRep.circle | |
.each(cluster(.025/*10 * e.alpha * e.alpha*/)) | |
.each(collide(.5, quadtree)) | |
.attr("transform", tr); | |
vis.forceRep.resume(); | |
} | |
// Move d to be adjacent to the cluster node. | |
function cluster(alpha) { | |
vis.forceRep.cenralNodes = vis.forceRep.cenralNodes || {}; | |
// Find the largest node for each cluster. | |
vis.forceRep.nodes().forEach(function(d, n) { | |
n = vis.forceRep.cenralNodes[d.nodeValue.lang]; | |
(!n || vis.forceRep.radO(d) > vis.forceRep.radO(n)) && | |
(vis.forceRep.cenralNodes[d.nodeValue.lang] = d); | |
}); | |
return function(d) { | |
var node = vis.forceRep.cenralNodes[d.nodeValue.lang], | |
l, | |
r, | |
x, | |
y; | |
if (node == d) return; | |
x = d.x - node.x; | |
y = d.y - node.y; | |
l = Math.sqrt(x * x + y * y); | |
r = vis.forceRep.radius(vis.forceRep.rad(d)) + vis.forceRep.radius(vis.forceRep.rad(node)) * 1.5; | |
if (l != r) { | |
l = (l - r) / (l || 1) * (alpha || 1); | |
x *= l; | |
y *= l; | |
//if (!d.fixed) { | |
if (true) { | |
d.x -= x; | |
d.y -= y; | |
} | |
//if (!node.fixed) { | |
if (true) { | |
node.x += x; | |
node.y += y; | |
} | |
} | |
}; | |
} | |
// Resolves collisions between d and all other circles. | |
function collide(alpha, quadtree) { | |
return function(d) { | |
var padding = vis.forceRep.radius.range()[1] / 2, | |
r = vis.forceRep.radius(vis.forceRep.rad(d)) + 3 * padding, | |
nx1 = d.x - r, | |
nx2 = d.x + r, | |
ny1 = d.y - r, | |
ny2 = d.y + r; | |
quadtree.visit(function(quad, x1, y1, x2, y2) { | |
if (quad.point && (quad.point !== d)) { | |
var x = d.x - quad.point.x, | |
y = d.y - quad.point.y, | |
l = Math.sqrt(x * x + y * y), | |
r = (vis.forceRep.radius(vis.forceRep.rad(d)) + vis.forceRep.radius(vis.forceRep.rad(quad.point))) * 1.02 /*+ (d.nodeValue.lang !== quad.point.nodeValue.lang) * padding*/; | |
if (l < r) { | |
l = (l - r) / (l || 1) * (alpha || 1); | |
x *= l; | |
y *= l; | |
//if (!d.fixed) { | |
if (true) { | |
d.x -= x; | |
d.y -= y; | |
} | |
//if (!quad.point.fixed) { | |
if (true) { | |
quad.point.x += x; | |
quad.point.y += y; | |
} | |
} | |
} | |
return x1 > nx2 | |
|| x2 < nx1 | |
|| y1 > ny2 | |
|| y2 < ny1; | |
}); | |
}; | |
} | |
}; | |
})(vis || (vis = {})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* User: ArtZub | |
* Date: 23.01.13 | |
* Time: 15:00 | |
*/ | |
"use strict"; | |
(function(vis) { | |
var _worker, | |
_data, | |
nodes, | |
dateRange, | |
authorHash, | |
filesHash, | |
extHash, | |
extMax, | |
_force, | |
_forceAuthor, | |
links, | |
lCom, lLeg, lHis, | |
canvas, ctx, | |
bufCanvas, bufCtx, | |
layer, | |
valid, | |
pause, | |
stop, | |
particle, | |
defImg, | |
lastEvent, | |
zoomScale, | |
xW, | |
yH, | |
setting, | |
rd3 = d3.random.irwinHall(8); | |
var extColor = d3.scale.category20(), | |
userColor = d3.scale.category20b(); | |
var typeNode = { | |
author : 0, | |
file : 1 | |
}; | |
function reCalc(d) { | |
if (stop) | |
return; | |
lCom.showCommitMessage(d.message); | |
appendExtLegend(d.sha); | |
var l = d.nodes.length, | |
n, a, fn; | |
a = d.cuserNode ? d.cuserNode : d.userNode; | |
a.fixed = false; | |
if (!l) | |
console.log(d); | |
else { | |
a.alive = setting.userLife > 0 ? setting.userLife : 1; | |
a.opacity = 100; | |
a.flash = 100; | |
a.visible = true; | |
} | |
while(--l > -1) { | |
n = d.nodes[l]; | |
if (n.fixed) { | |
n.x = xW(n.x); | |
n.y = yH(n.y); | |
} | |
n.size += 2; | |
n.fixed = false; | |
n.author = a.nodeValue.email; | |
n.visible = !!n.statuses[d.sha].status; | |
fn = n.nodeValue.name.toLowerCase(); | |
if (n.visible) { | |
n.ext.now.indexOf(fn) < 0 | |
&& n.ext.now.push(fn); | |
n.flash = 100; | |
n.alive = setting.fileLife > 0 ? setting.fileLife : 1; | |
n.opacity = 100; | |
} | |
else { | |
(fn = n.ext.now.indexOf(fn)) > -1 | |
&& n.ext.now.splice(fn, 1); | |
n.alive = (setting.fileLife > 0 ? setting.fileLife : 1) * .2; | |
n.opacity = 50; | |
} | |
/*data.push(n); | |
if (d.cuserNode) { | |
links.push({ | |
source : n, | |
target : d.cuserNode | |
}); | |
} | |
links.push({ | |
source : n, | |
target : d.userNode | |
});*/ | |
} | |
updateLegend(d.sha); | |
_force.nodes(nodes.filter(function(d) { | |
return d.type != typeNode.author && (d.visible || d.opacity); | |
}).sort(sortBySize) | |
).start(); | |
_forceAuthor.nodes(nodes.filter(function(d) { | |
return d.type == typeNode.author && (d.visible || d.opacity); | |
})).start(); | |
} | |
function loop() { | |
if (pause) | |
return; | |
var dl, dr; | |
dl = dateRange[0]; | |
dr = dl + ghcs.limits.stepShow * ghcs.limits.stepType; | |
dateRange[0] = dr; | |
var visTurn = _data.filter(function (d) { | |
return d.date >= dl && d.date < dr; | |
}); | |
ghcs.asyncForEach(visTurn, reCalc, ONE_SECOND / (visTurn.length > 1 ? visTurn.length : ONE_SECOND)); | |
//visTurn.forEach(reCalc); | |
updateStatus(ghcs.states.cur += ghcs.limits.stepShow * ghcs.limits.stepType, timeFormat(new Date(dr))); | |
if (dl >= dateRange[1]) { | |
if (_worker) | |
clearInterval(_worker); | |
} else { | |
if (!visTurn.length && setting.skipEmptyDate) | |
loop(); | |
} | |
updateExtHistogram(); | |
} | |
function run() { | |
if (_worker) | |
clearInterval(_worker); | |
anim(); | |
_worker = setInterval(loop, ONE_SECOND); | |
} | |
function nr(d) { | |
return d.size > 0 ? d.size : 0; | |
} | |
function ncb(d) { | |
return d3.rgb(d.color).brighter().brighter(); | |
} | |
function nc(d) { | |
return d.color; | |
} | |
function randomTrue() { | |
return Math.floor(rd3() * 8) % 2; | |
} | |
function radius(d) { | |
return Math.sqrt(d); | |
} | |
function node(d, type) { | |
var c = type == typeNode.file ? d.name : userColor(d.email), | |
ext, x, y, | |
w2 = w/2, | |
w5 = w/5, | |
h2 = h/2, | |
h5 = h/5; | |
if (type == typeNode.file) { | |
c = c && c.match(/.*(\.\w+)$/) ? c.replace(/.*(\.\w+)$/, "$1").toLowerCase() : "Mics"; | |
ext = extHash.get(c); | |
if (!ext) { | |
ext = { | |
all : 0, | |
currents : {}, | |
color : extColor(c), | |
now : [] | |
}; | |
extHash.set(c, ext); | |
} | |
ext.all++; | |
c = ext.color; | |
} | |
x = w * Math.random(); | |
y = h * Math.random(); | |
if (type == typeNode.author) { | |
if (randomTrue()) { | |
x = x > w5 && x < w2 | |
? x / 5 | |
: x > w2 && x < w - w5 | |
? w - x / 5 | |
: x | |
; | |
} | |
else { | |
y = y > h5 && y < h2 | |
? y / 5 | |
: y > h2 && y < h - h5 | |
? h - y / 5 | |
: y | |
; | |
} | |
} | |
return { | |
x : x, | |
y : y, | |
id : type + (type == typeNode.file ? d.name : d.email), | |
size : type != typeNode.file ? 24 : 2, | |
weight : type != typeNode.file ? 24 : 2, | |
fixed : true, | |
visible : false, | |
links : 0, | |
type : type, | |
color : c, | |
ext : ext, | |
author : type == typeNode.author ? d.email : null, | |
img : type == typeNode.author ? d.avatar : null, | |
nodeValue : d | |
} | |
} | |
function getAuthor(d) { | |
if (!d || !d.author) | |
return null; | |
var n = authorHash.get(d.author.email); | |
if (!n) { | |
n = node(d.author, typeNode.author); | |
authorHash.set(d.author.email, n); | |
} | |
return n; | |
} | |
function getFile(d) { | |
if (!d || !d.name) | |
return null; | |
var n = filesHash.get(d.name); | |
if (!n) { | |
n = node(d, typeNode.file); | |
n.links = 1; | |
filesHash.set(d.name, n); | |
} | |
return n; | |
} | |
function initNodes(data) { | |
var ns = [], | |
i, j, n, d, df; | |
authorHash = d3.map({}); | |
filesHash = d3.map({}); | |
extHash = d3.map({}); | |
extMax = 0; | |
if (data) { | |
i = data.length; | |
while(--i > -1) { | |
d = data[i]; | |
d.nodes = []; | |
if (!d) continue; | |
n = getAuthor(d); | |
d.userNode = n; | |
!n.inserted && (n.inserted = ns.push(n)); | |
if (d.author.login != d.committer.login) { | |
n = getAuthor(d); | |
d.cuserNode = n; | |
!n.inserted && (n.inserted = ns.push(n)); | |
/*links.push({ | |
source : d.userNode, | |
target : d.cuserNode | |
})*/ | |
} | |
if (!d.files) continue; | |
j = d.files.length; | |
while(--j > -1) { | |
df = d.files[j]; | |
if (!df) continue; | |
n = getFile(df); | |
d.nodes.push(n); | |
n.size = 2; | |
n.statuses = n.statuses || {}; | |
n.statuses[d.sha] = df; | |
n.ext.currents[d.sha] = (n.ext.currents[d.sha] || 0); | |
n.ext.currents[d.sha]++; | |
!n.inserted && (n.inserted = ns.push(n)); | |
} | |
j = extHash.values().reduce(function(a, b) { | |
return a += b.currents[d.sha] || 0; | |
}, null); | |
extMax = j > extMax ? j : extMax; | |
} | |
} | |
return ns; | |
} | |
var tempCanvas, tempFileCanvas; | |
function setOpacity(img, a, f) { | |
if (!img || !img.width) | |
img = defImg; | |
return img; | |
} | |
function colorize(img, r, g, b, a) { | |
if (!img) | |
return img; | |
if (!tempFileCanvas) { | |
tempFileCanvas = document.createElement("canvas"); | |
tempFileCanvas.width = img.width; | |
tempFileCanvas.height = img.height; | |
} | |
var imgCtx = tempFileCanvas.getContext("2d"), imgdata, i; | |
imgCtx.clearRect(0, 0, img.width, img.height); | |
imgCtx.save(); | |
imgCtx.drawImage(img, 0, 0); | |
imgdata = imgCtx.getImageData(0, 0, img.width, img.height); | |
i = imgdata.data.length; | |
while((i -= 4) > -1) { | |
imgdata.data[i + 3] = imgdata.data[i] * a; | |
if (imgdata.data[i + 3]) { | |
imgdata.data[i] = r; | |
imgdata.data[i + 1] = g; | |
imgdata.data[i + 2] = b; | |
} | |
} | |
imgCtx.putImageData(imgdata, 0, 0); | |
imgCtx.restore(); | |
return tempFileCanvas; | |
} | |
function blink(d, aliveCheck, i, l) { | |
d.flash = (d.flash -= setting.rateFlash) > 0 ? d.flash : 0; | |
!d.flash && aliveCheck | |
&& (d.alive = (d.alive-- > 0 ? d.alive : 0)) | |
; | |
d.opacity = !d.alive | |
? ((d.opacity -= setting.rateOpacity) > 0 ? d.opacity : 0) | |
: d.opacity | |
; | |
d.visible && !d.opacity | |
&& (d.visible = false); | |
} | |
function sortBySize(a, b) { | |
return d3.descending(b.size, a.size); | |
} | |
function checkVisible(d, offsetx, offsety) { | |
var tx = lastEvent.translate[0]/lastEvent.scale, | |
ty = lastEvent.translate[1]/lastEvent.scale | |
; | |
offsetx = offsetx || 0; | |
if (!(offsetx instanceof Array)) | |
offsetx = [offsetx, offsetx]; | |
offsety = offsety || 0; | |
if (!(offsety instanceof Array)) | |
offsety = [offsety, offsety]; | |
return ( | |
d.x + d.size > -tx + offsetx[0] | |
&& d.x - d.size < -tx + offsetx[1] + w/lastEvent.scale | |
&& d.y + d.size > -ty + offsety[0] | |
&& d.y - d.size < -ty + offsety[1] + h/lastEvent.scale | |
); | |
} | |
function redrawCanvas() { | |
bufCtx.save(); | |
bufCtx.clearRect(0, 0, w, h); | |
bufCtx.translate(lastEvent.translate[0], lastEvent.translate[1]); | |
bufCtx.scale(lastEvent.scale, lastEvent.scale); | |
var n, l, i, j, | |
img, | |
d, d1, d2, | |
c, x, y, s; | |
if (setting.showFile) { | |
n = d3.nest() | |
.key(function(d) { | |
return d.opacity; | |
}) | |
.key(function(d) { | |
return d.flash ? ncb(d) : d3.rgb(nc(d)); | |
}) | |
.entries(_force.nodes().filter(function(d) { return checkVisible(d) && (d.visible || d.alive); })); | |
l = n.length; | |
while(--l > -1) { | |
d1 = n[l]; | |
i = d1.values.length; | |
while(--i > -1) { | |
d2 = d1.values[i]; | |
j = d2.values.length; | |
c = d3.rgb(d2.key); | |
if (!setting.showHalo) { | |
bufCtx.beginPath(); | |
bufCtx.strokeStyle = "none"; | |
bufCtx.fillStyle = toRgba(c, d1.key * .01); | |
} | |
else | |
img = colorize(particle, c.r, c.g, c.b, d1.key * .01); | |
while(--j > -1) { | |
d = d2.values[j]; | |
if (d.visible || d.alive) { | |
//blink(d, setting.fileLife > 0); | |
x = Math.floor(d.x); | |
y = Math.floor(d.y); | |
s = radius(nr(d)) * (setting.showHalo ? 8 : 1); | |
setting.showHalo | |
? bufCtx.drawImage(img, x - s / 2, y - s / 2, s, s) | |
: bufCtx.arc(x, y, s, 0, PI_CIRCLE, true) | |
; | |
} | |
} | |
if (!setting.showHalo) { | |
bufCtx.fill(); | |
bufCtx.stroke(); | |
bufCtx.closePath(); | |
} | |
} | |
} | |
} | |
if (setting.showUser || setting.showLabel) { | |
n = _forceAuthor.nodes(); | |
l = n.length; | |
while(--l > -1) { | |
d = n[l]; | |
if (checkVisible(d) && (d.visible || d.opacity)) { | |
//blink(d, !d.links && setting.userLife > 0); | |
x = Math.floor(d.x); | |
y = Math.floor(d.y); | |
if (setting.showUser) { | |
c = d.flash ? ncb(d) : d3.rgb(nc(d)); | |
bufCtx.save(); | |
if (setting.showPaddingCircle) { | |
bufCtx.beginPath(); | |
bufCtx.strokeStyle = "none"; | |
bufCtx.fillStyle = toRgba("#ff0000", .1); | |
bufCtx.arc(x, y, nr(d) + setting.padding, 0, PI_CIRCLE, true); | |
bufCtx.fill(); | |
bufCtx.stroke(); | |
} | |
bufCtx.beginPath(); | |
bufCtx.strokeStyle = "none"; | |
bufCtx.fillStyle = setting.useAvatar ? "none" : toRgba(c, d.opacity * .01); | |
bufCtx.arc(x, y, nr(d), 0, PI_CIRCLE, true); | |
bufCtx.fill(); | |
bufCtx.stroke(); | |
if (setting.useAvatar && d.img) { | |
bufCtx.clip(); | |
bufCtx.drawImage(setOpacity(d.img, d.opacity * .01, d.flash), x - nr(d), y - nr(d), nr(d) * 2, nr(d) * 2); | |
} | |
bufCtx.closePath(); | |
bufCtx.restore(); | |
} | |
if (setting.showLabel) { | |
c = d.flash ? "white" : "gray"; | |
bufCtx.save(); | |
bufCtx.fillStyle = toRgba(c, d.opacity * .01); | |
bufCtx.fillText(setting.labelPattern | |
.replace("%l", d.nodeValue.login) | |
.replace("%n", d.nodeValue.name != "unknown" ? d.nodeValue.name : d.nodeValue.login) | |
.replace("%e", d.nodeValue.email), x, y + nr(d) * 1.5); | |
bufCtx.restore(); | |
} | |
} | |
} | |
} | |
bufCtx.restore(); | |
} | |
function anim() { | |
requestAnimationFrame(anim); | |
lHis && lHis.style("display", setting.showHistogram ? null : "none"); | |
lLeg && lLeg.style("display", setting.showCountExt ? null : "none"); | |
if (valid) | |
return; | |
valid = true; | |
ctx.save(); | |
ctx.clearRect(0, 0, w, h); | |
redrawCanvas(); | |
ctx.drawImage(bufCanvas, 0, 0); | |
ctx.restore(); | |
valid = false; | |
} | |
function tick() { | |
if (_force.nodes()) { | |
_force.nodes() | |
.forEach(cluster(0.025)); | |
_forceAuthor.nodes( | |
_forceAuthor.nodes() | |
.filter(function(d, i) { | |
blink(d, !d.links && setting.userLife > 0, i, _forceAuthor.nodes().length); | |
if (d.visible && d.links === 0 && setting.userLife > 0) { | |
d.flash = 0; | |
d.alive = d.alive / 10; | |
} | |
return d.visible; | |
}) | |
); | |
} | |
_forceAuthor.resume(); | |
_force.resume(); | |
} | |
// Move d to be adjacent to the cluster node. | |
function cluster(alpha) { | |
authorHash.forEach(function(k, d) { | |
d.links = 0; | |
}); | |
return function(d, i) { | |
blink(d, setting.fileLife > 0, i, _force.nodes().length); | |
if (!d.author || !d.visible) | |
return; | |
var node = authorHash.get(d.author), | |
l, | |
r, | |
x, | |
y; | |
if (node == d) return; | |
node.links++; | |
x = d.x - node.x; | |
y = d.y - node.y; | |
l = Math.sqrt(x * x + y * y); | |
r = radius(nr(d)) / 2 + (nr(node) + setting.padding); | |
if (l != r) { | |
l = (l - r) / (l || 1) * (alpha || 1); | |
x *= l; | |
y *= l; | |
d.x -= x; | |
d.y -= y; | |
} | |
}; | |
} | |
function appendExtLegend(sha){ | |
if (!layer) | |
return; | |
var data = [], | |
w3 = w / 3, | |
ml = w * .01, | |
mb = 18, | |
h2 = (h / 2) - mb, | |
bw = 2, | |
i, ny | |
; | |
var y = d3.scale.linear() | |
.range([0, h2]) | |
.domain([0, extMax]); | |
lHis = (lHis || layer.append("g")) | |
.attr("width", w3) | |
.attr("height", h2) | |
.attr("transform", "translate(" + [ ml , h - h2 - mb ] + ")"); | |
if (!sha) | |
return; | |
ny = h2; | |
extHash.forEach(function(k, d) { | |
var obj = { | |
key : k, | |
h : y(d.currents[sha] || 0), | |
color : d.color | |
}; | |
obj.y = ny -= obj.h; | |
data.push(obj); | |
}); | |
updateExtHistogram(); | |
var g = lHis.append("g") | |
.attr("class", "colStack") | |
.datum({ x : w3, w : bw }) | |
.style("opacity", 0); | |
g.selectAll("rect") | |
.data(data) | |
.enter() | |
.append("rect") | |
.attr("x", 0) | |
.attr("y", function(d) { return d.y; }) | |
.attr("width", bw) | |
.attr("height", function(d) { return d.h; }) | |
.attr("fill", function(d) { return d.color; }) | |
; | |
g.style("opacity", 1) | |
.attr("transform", function(d) { | |
return "translate(" + [ d.x, 0] + ")"; | |
}); | |
} | |
function updateExtHistogram() { | |
if (!lHis || lHis.selectAll(".colStack").empty()) | |
return; | |
lHis.selectAll(".colStack") | |
.attr("transform", function(d) { | |
return "translate(" + [ d.x -= d.w - 1, 0] + ")"; | |
}) | |
.filter(function(d) { | |
return d.x < 0; | |
}) | |
.remove(); | |
} | |
function initLegend() { | |
if (!layer) | |
return; | |
var mt = 48, | |
ml = w * .01, | |
h2 = h / 2 - mt, | |
w3 = w / 3 | |
; | |
lLeg = (lLeg || layer.append("g")) | |
.attr("width", w3) | |
.attr("height", h2) | |
.attr("transform", "translate(" + [ml, mt] + ")"); | |
lLeg.selectAll("*").remove(); | |
var g = lLeg.selectAll(".gLeg") | |
.data(extHash.entries(), function(d) { return d.key; }); | |
g.exit().remove(); | |
g.enter().append("g") | |
.attr("class", "gLeg") | |
.attr("transform", function(d, i) { | |
return "translate(" + [0, i * 18] + ")"; | |
}) | |
.style("visibility", "hidden") | |
; | |
g.append("rect") | |
.attr("height", 16) | |
.style("fill", function(d) { return d.value.color; }) | |
; | |
g.append("text") | |
.attr("class", "gttLeg") | |
.style("font-size", "13px") | |
.text(function(d) { return d.key.substr(1); }) | |
.style("fill", function(d) { return d3.rgb(d.value.color).brighter().brighter(); }) | |
; | |
g.append("text") | |
.attr("class", "gtLeg") | |
.style("font-size", "11px") | |
.attr("transform", "translate(" + [2, 12] + ")") | |
; | |
} | |
function sortLeg(b, a) { | |
return d3.ascending(a.value.now.length, b.value.now.length); | |
} | |
function sortLegK(b, a) { | |
return d3.ascending(a.key, b.key); | |
} | |
function updateLegend(sha) { | |
if (!lLeg || lLeg.empty()) | |
return; | |
var g = lLeg.selectAll(".gLeg"); | |
function wl(d) { | |
return d.value.now.length; | |
} | |
var wb = 9 * d3.max(g.data(), function(d) { | |
return ((wl(d) || "") + "").length; | |
}); | |
g.selectAll("rect") | |
.attr("width", wb) | |
; | |
g.selectAll(".gttLeg") | |
.attr("transform", "translate(" + [wb + 2, 12] + ")") | |
; | |
g.selectAll(".gtLeg") | |
.text(wl) | |
; | |
g.sort(sortLegK).sort(sortLeg) | |
.style("visibility", function(d, i) { | |
return !wl(d) || i * 18 > lLeg.attr("height") ? "hidden" : "visible"; | |
}) | |
.transition() | |
.duration(500) | |
.attr("transform", function(d, i) { | |
return "translate(" + [0, i * 18] + ")"; | |
}) | |
; | |
} | |
vis.runShow = function(data, svg, params) { | |
if (_worker) | |
clearInterval(_worker); | |
_data = data && data.commits ? data.commits.values().sort(vis.sC) : null; | |
if (!_data || !_data.length) | |
return; | |
setting = ghcs.settings.cs; | |
vis.layers.repo && cbDlr.uncheck(); | |
vis.layers.stat && cbDlsr.uncheck(); | |
dateRange = d3.extent(data.dates); | |
layer = d3.select("#canvas"); | |
layer.select("#mainCanvas").remove(); | |
lastEvent = { | |
translate: [0, 0], | |
scale : 1 | |
}; | |
xW = d3.scale.linear() | |
.range([0, w]) | |
.domain([0, w]); | |
yH = d3.scale.linear() | |
.range([0, h]) | |
.domain([0, h]); | |
var zoom = d3.behavior.zoom() | |
.scaleExtent([.1, 8]) | |
.scale(1) | |
.translate([0, 0]) | |
.on("zoom", function() { | |
lastEvent.translate = d3.event.translate.slice(0); | |
lastEvent.scale = d3.event.scale; | |
var tl = lastEvent.translate[0] / lastEvent.scale, | |
tt = lastEvent.translate[1] / lastEvent.scale; | |
xW.range([-tl, -tl + w / lastEvent.scale]) | |
.domain([0, w]); | |
yH.range([-tt, -tt + h / lastEvent.scale]) | |
.domain([0, h]); | |
valid = false; | |
}); | |
canvas = layer.append("canvas") | |
.text("This browser don't support element type of Canvas.") | |
.attr("id", "mainCanvas") | |
.attr("width", w) | |
.attr("height", h) | |
.call(zoom) | |
.node(); | |
ctx = canvas.getContext("2d"); | |
bufCanvas = document.createElement("canvas"); | |
bufCanvas.width = w; | |
bufCanvas.height = h; | |
bufCtx = bufCanvas.getContext("2d"); | |
bufCtx.font = "normal normal " + setting.sizeUser / 2 + "px Tahoma"; | |
bufCtx.textAlign = "center"; | |
layer = svg || vis.layers.show; | |
layer && layer.show && layer.show(); | |
layer.append("g") | |
.call(zoom) | |
.append("rect") | |
.attr("width", w) | |
.attr("height", h) | |
.attr("x", 0) | |
.attr("y", 0) | |
.style("fill", "#ffffff") | |
.style("fill-opacity", 0); | |
lHis && lHis.selectAll("*").remove(); | |
lCom = ( | |
lCom || layer.append("g") | |
.attr("width", 10) | |
.attr("height", 14) | |
) | |
.attr("transform", "translate(" + [w/2, h - 18] + ")") | |
; | |
lCom.visible = !setting.showCommitMessage; | |
lCom.selectAll("text").remove(); | |
lCom.showCommitMessage = lCom.showCommitMessage || function(text) { | |
if (setting.showCommitMessage && !lCom.visible) { | |
lCom.visible = true; | |
lCom.style("display", null); | |
} | |
else if (!setting.showCommitMessage && lCom.visible) { | |
lCom.visible = false; | |
lCom.style("display", "none"); | |
} | |
lCom.append("text") | |
.attr("text-anchor", "middle") | |
.attr("class", "com-mess") | |
.attr("transform", "translate("+ [0, -lCom.node().childElementCount * 14] +")") | |
.text(text.split("\n")[0].substr(0, 100)) | |
.transition() | |
.delay(500) | |
.duration(2000) | |
.style("fill-opacity", 1) | |
.duration(200) | |
.style("font-size", "11.2pt") | |
.transition() | |
.duration(1500) | |
.style("fill-opacity", .3) | |
.style("font-size", "11pt") | |
.each("end", function() { | |
lCom.selectAll("text").each(function(d, i) { | |
d3.select(this) | |
.attr("transform", "translate("+ [0, -i * 14] +")"); | |
}); | |
}) | |
.remove(); | |
}; | |
psBar.show(); | |
ghcs.states.cur = 0; | |
ghcs.states.max = dateRange[1] - dateRange[0]; | |
updateStatus(ghcs.states.cur, timeFormat(new Date(dateRange[0]))); | |
links = []; | |
nodes = initNodes(_data); | |
defImg = new Image(); | |
defImg.src = "default.png"; | |
particle = new Image(); | |
particle.src = "particle.png"; | |
_force = (_force || d3.layout.force() | |
.stop() | |
.size([w, h]) | |
.friction(.75) | |
.gravity(0) | |
.charge(function(d) {return -3 * radius(nr(d)); } ) | |
.on("tick", tick)) | |
.nodes([]) | |
; | |
zoomScale = d3.scale.linear() | |
.range([5, 1]) | |
.domain([.1, 1]); | |
_forceAuthor = (_forceAuthor || d3.layout.force() | |
.stop() | |
.size([w, h]) | |
.gravity(setting.padding * .001) | |
.charge(function(d) { return -(setting.padding + d.size) * 8 | |
* (Math.sqrt(d.links / lastEvent.scale) || 1) | |
; | |
})) | |
.nodes([]) | |
; | |
initLegend(); | |
stop = false; | |
pause = false; | |
run(); | |
_force.start(); | |
_forceAuthor.start(); | |
}; | |
vis.pauseShow = function() { | |
pause = true; | |
}; | |
vis.stopShow = function() { | |
stop = true; | |
if (_worker) | |
clearInterval(_worker); | |
}; | |
vis.resumeShow = function() { | |
pause = false; | |
}; | |
})(vis || (vis = {})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* User: ArtZub | |
* Date: 23.01.13 | |
* Time: 12:54 | |
*/ | |
'use strict'; | |
(function (vis) { | |
var textFormat = d3.format(","); | |
vis.meArc = function(d) { | |
vis.layers.stat.toFront(); | |
if (!d._g) | |
return; | |
d._g.selectAll("path.bar") | |
.style({ | |
"fill-opacity" : .6, | |
"stroke-width" : 1, | |
"stroke" : function() { return toRgba("#000000", 1); } | |
}); | |
var self = d._g.node(); | |
self.barDel && self.barDel | |
.transition() | |
.attr("d", self.delArc.startAngle(PIdiv2 + smallRad ) | |
.endAngle(PIdiv2 * 3 - smallRad)()) | |
; | |
self.barAdd && self.barAdd | |
.transition() | |
.attr("d", self.addArc.startAngle(-PIdiv2 + smallRad ) | |
.endAngle(PIdiv2 - smallRad)()) | |
; | |
d._g.selectAll("text.del, text.add") | |
.style("visibility", "visible"); | |
toolTip.selectAll("*").remove(); | |
toolTip.append("div").attr("class", "row") | |
.append("blockquote") | |
.text(d.message.split("\n")[0]); | |
toolTip.append("div").attr("class", "row userInfo open").call(function(div) { | |
div = div.append("div").attr("class", "statInfo"); | |
div.node().appendChild(d.author.avatar); | |
div.append("ul").call(function(ul) { | |
(d.author.name || d.author.login) && ul.append("li").call(function(li) { | |
li.append("h1") | |
.text((d.author.name || d.author.login)) | |
; | |
li.append("hr"); | |
}); | |
ul.append("li").call(function(li) { | |
li.append("span") | |
.attr("class", "mini-icon mini-icon-time"); | |
li.append("strong") | |
.text(timeFormat(d.date)) | |
}); | |
d.files.length && ul.append("li") | |
.call(function(li) { | |
var stat = d.files.reduce(function(a, b) { | |
for(var key in TYPE_STATUS_FILE) { | |
if (TYPE_STATUS_FILE.hasOwnProperty(key) | |
&& b.status == TYPE_STATUS_FILE[key]) { | |
a[key] = (a[key] || 0); | |
a[key]++; | |
break; | |
} | |
} | |
return a; | |
}, {}); | |
li = li.append("ul") | |
.attr("class", "setting"); | |
li = li.append("li").attr("class", "field"); | |
li.append("h1") | |
.text("Changed files:"); | |
for(var key in stat) { | |
stat.hasOwnProperty(key) | |
&& li.append("ul") | |
.attr("class", "group") | |
.append("li") | |
.attr("class", "field") | |
.append("span") | |
.text(key + ": ") | |
.append("strong") | |
.text(stat[key]); | |
} | |
}); | |
ul.append("li") | |
.call(function(li) { | |
li = li.append("ul") | |
.attr("class", "setting"); | |
li = li.append("li").attr("class", "field"); | |
li.append("h1") | |
.text("Changed lines:"); | |
var stat = {changes : "", additions : " + ", deletions : " - "}; | |
for(var key in stat) { | |
d.stats.hasOwnProperty(key) | |
&& li.append("ul") | |
.attr("class", "group") | |
.append("li") | |
.attr("class", "field") | |
.append("span") | |
.text(key + ": ") | |
.append("strong") | |
.style("color", d3.rgb(colors[key]).darker(.2)) | |
.text(stat[key] + textFormat(d.stats[key])); | |
} | |
}); | |
}); | |
}); | |
toolTip.show(); | |
}; | |
vis.mlArc = function(d) { | |
if (!d._g) | |
return; | |
d._g.selectAll("path.bar") | |
.style({ | |
"fill-opacity" : .3, | |
"stroke" : null | |
}); | |
var self = d._g.node(); | |
if (!self) | |
return; | |
self.barDel && self.barDel | |
.transition() | |
.duration(750) | |
.ease("elastic") | |
.attr("d", self.delArc.startAngle(Math.PI - smallRad) | |
.endAngle(Math.PI + smallRad)()) | |
; | |
self.barAdd && self.barAdd | |
.transition() | |
.duration(750) | |
.ease("elastic") | |
.attr("d", self.addArc.startAngle(- smallRad ) | |
.endAngle(smallRad)()) | |
; | |
d._g.selectAll("text.del") | |
.style("visibility", d.stats && d.stats.delTextVis ? d.stats.delTextVis : "hidden"); | |
d._g.selectAll("text.add") | |
.style("visibility", d.stats && d.stats.addTextVis ? d.stats.addTextVis : "hidden"); | |
toolTip.hide(); | |
}; | |
vis.mmArc = function(d) { | |
vis.mtt(d); | |
}; | |
vis.clearStat = function() { | |
if (vis.layers && vis.layers.stat) { | |
vis.layers.stat.selectAll("*").remove(); | |
vis.layers.stat.cont && (vis.layers.stat.cont = null); | |
} | |
}; | |
vis.redrawStat = function(data, layout) { | |
layout = layout || vis.layers.stat; | |
var _commits = data && data.commits ? data.commits.values() : null; | |
if (!_commits || !_commits.length) { | |
vis.clearStat(); | |
return; | |
} | |
var bd = d3.extent(data.dates); | |
var delta = (bd[1] - bd[0]) * 0.1; | |
delta = delta || ONE_DAY; | |
bd = [bd[0] - delta, bd[1] + delta]; | |
var x = d3.time.scale() | |
.domain(d3.extent(bd)) | |
.range([0, w - margin.left - margin.right]) | |
; | |
var h6 = h/6; | |
var y = d3.scale.linear() | |
.range([2, h6 * 2]) | |
.domain([0, data.stats.changes || 1]); | |
var sorted = _commits.slice(0).concat([ | |
{ date : bd[0] + delta / 2, f : { d : 0, a : 0, m : 0 } }, | |
{ date : bd[1] - delta / 2, f : { d : 0, a : 0, m : 0 } } | |
]).sort(vis.sC); | |
var layers = | |
[ | |
{ | |
color: colors.deletedFile, | |
values: sorted.map(function (d) { | |
return {t : 1, x: d.date, y0 : 0, y: (d.stats ? -d.stats.f.d : 0)} | |
}) | |
}, | |
{ | |
color: colors.modifiedFile, | |
values: sorted.map(function (d) { | |
return {x: d.date, y0 : 0, y: (d.stats ? d.stats.f.m : 0)} | |
}) | |
}, | |
{ | |
color: colors.addedFile, | |
values: sorted.map(function (d) { | |
return {x: d.date, y0: (d.stats ? d.stats.f.m : 0), y : (d.stats ? d.stats.f.a : 0)} | |
}) | |
} | |
] | |
; | |
function interpolateSankey(points) { | |
var x0 = points[0][0], y0 = points[0][1], x1, y1, x2, | |
path = [x0, ",", y0], | |
i = 0, | |
n = points.length; | |
while (++i < n) { | |
x1 = points[i][0]; | |
y1 = points[i][1]; | |
x2 = (x0 + x1) / 2; | |
path.push("C", x2, ",", y0, " ", x2, ",", y1, " ", x1, ",", y1); | |
x0 = x1; | |
y0 = y1; | |
} | |
return path.join(""); | |
} | |
var y1 = d3.scale.linear() | |
.range([h6 * 4.5, h6 * 3, h6 * 1.5]) | |
.domain([-data.stats.files, 0, data.stats.files]), | |
area = d3.svg.area() | |
.interpolate(interpolateSankey /*true ? "linear" : "basis"*/) | |
.x(function(d) { return x(d.x); }) | |
.y0(function(d) { return y1(d.y0); }) | |
.y1(function(d) { return y1(d.y0 + d.y); }) | |
; | |
var xAxis = d3.svg.axis() | |
.scale(x) | |
; | |
layout.cont = layout.cont || layout | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")") | |
; | |
layout.cont.selectAll("path.areaFile").remove(); | |
layout.cont.selectAll("path.areaFile") | |
.data(layers) | |
.enter() | |
.insert("path", ":first-child") | |
.attr("class", "areaFile") | |
.style("fill-opacity",.1) | |
.style("fill", function(d) { return d.color; }) | |
.transition() | |
.duration(750) | |
.attr("d", function(d) { return area(d.values); }) | |
; | |
layout.cont.axis = layout.cont.axis || layout.cont.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + h/2 + ")") | |
; | |
layout.cont.axis | |
.selectAll("*").remove(); | |
layout.cont.axis | |
.call(xAxis) | |
.selectAll("text") | |
.attr("y", 0) | |
.attr("x", 9) | |
.attr("dy", ".35em") | |
.attr("transform", "rotate(90)") | |
.style("text-anchor", "start") | |
; | |
layout.cont.points = layout.cont.points || layout.cont.append("g") | |
.attr("transform", "translate(0," + h/2 + ")") | |
; | |
var cData = layout.cont.points.selectAll("g.com") | |
.data(_commits, function(d) { return d.sha; }); | |
cData.enter() | |
.append("g") | |
.attr("class", "com") | |
.on("mouseover", vis.meArc) | |
.on("mouseout", vis.mlArc) | |
.on("mousemove", vis.mmArc) | |
; | |
cData.each(function(d, g) { | |
g = d._g = d3.select(this); | |
g.transition() | |
.duration(1500) | |
.ease("elastic") | |
.attr("transform", "translate(" + [ x(d.date), 0] + ")"); | |
this.center = this.center || g.append("circle") | |
.attr("r", 2) | |
.style("fill", colors.center) | |
; | |
if (!d.stats) | |
return; | |
var add = this.addArc = d3.svg.arc() | |
.innerRadius(1) | |
.outerRadius(1) | |
.startAngle(- smallRad ) | |
.endAngle(smallRad) | |
; | |
var del = this.delArc = d3.svg.arc() | |
.innerRadius(1) | |
.outerRadius(1) | |
.startAngle(Math.PI - smallRad) | |
.endAngle(Math.PI + smallRad) | |
; | |
(this.barAdd || ( | |
this.barAdd = g.append("path") | |
.attr("class", "bar") | |
.style({ | |
"fill" : colors.additions, | |
"fill-opacity" : .3 | |
}) | |
.attr("d", add()) | |
)) | |
.transition() | |
.duration(750) | |
.ease("elastic") | |
.attr("d", add.outerRadius(y(d.stats.additions))()) | |
; | |
(this.barDel || ( | |
this.barDel = g.append("path") | |
.attr("class", "bar") | |
.style({ | |
"fill" : colors.deletions, | |
"fill-opacity" : .3 | |
}) | |
.attr("d", del()) | |
)) | |
.transition() | |
.duration(750) | |
.ease("elastic") | |
.attr("d", del.outerRadius(y(d.stats.deletions))()) | |
; | |
function sized(s, k) { | |
return s * (1 + k); | |
} | |
var addTop = this.addArcTop = d3.svg.arc() | |
.innerRadius(sized(y(d.stats.additions), .015)) | |
.outerRadius(sized(y(d.stats.additions), .025)) | |
.startAngle(- smallRad ) | |
.endAngle(smallRad) | |
; | |
var delTop = this.delArcTop = d3.svg.arc() | |
.innerRadius(sized(y(d.stats.deletions), .015)) | |
.outerRadius(sized(y(d.stats.deletions), .025)) | |
.startAngle(Math.PI - smallRad) | |
.endAngle(Math.PI + smallRad) | |
; | |
(this.barAddTop || ( | |
this.barAddTop = g.append("path") | |
.style("fill", toRgba(colors.additions)) | |
)) | |
.attr("d", addTop()) | |
; | |
(this.barDelTop || ( | |
this.barDelTop = g.append("path") | |
.style("fill", toRgba(colors.deletions)) | |
)) | |
.attr("d", delTop()) | |
; | |
if (d.stats.additions) { | |
d.stats.addTextVis = sized(y(d.stats.additions), .029) > h6 / 2 ? "visible" : "hidden"; | |
(this.labelAdd || ( | |
this.labelAdd = g.append("text") | |
.attr("class", "add") | |
.attr("dy", "-.31em") | |
.attr("text-anchor", "middle") | |
.style("fill", colors.additions) | |
.text(" + " + textFormat(d.stats.additions)) | |
)) | |
.attr("transform", "translate(" + [0, -sized(y(d.stats.additions), .027)] + ")") | |
.attr("visibility", d.stats.addTextVis) | |
; | |
} | |
if (d.stats.deletions) { | |
d.stats.delTextVis = sized(y(d.stats.deletions), .029) > h6 / 2 ? "visible" : "hidden"; | |
(this.labelDel || ( | |
this.labelDel = g.append("text") | |
.attr("class", "del") | |
.attr("dy", ".93em") | |
.attr("text-anchor", "middle") | |
.style("fill", colors.deletions) | |
.text(" - " + textFormat(d.stats.deletions)) | |
)) | |
.attr("transform", "translate(" + [0, sized(y(d.stats.deletions), .027)] + ")") | |
//rotate(180) | |
.attr("visibility", d.stats.delTextVis) | |
; | |
} | |
}); | |
cData.sort(function(a, b) { | |
return a.stats && b.stats ? d3.ascending(b.stats.changes, a.stats.changes) : 0; | |
}); | |
cData.exit().remove(); | |
}; | |
})(vis || (vis = {})); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* html5doctor.com Reset v1.6.1 - http://cssreset.com */ | |
html,body,div,span,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,abbr,address,cite,code,del,dfn,em,img,ins,kbd,q,samp,small,strong,sub,sup,var,b,i,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption,tbody,tfoot,thead,tr,th,td,article,aside,canvas,details,figcaption,figure,footer,header,hgroup,menu,nav,section,summary,time,mark,audio,video{margin:0;padding:0;border:0;outline:0;font-size:100%;vertical-align:baseline;background:transparent}body{line-height:1}article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{display:block}nav ul{list-style:none}blockquote,q{quotes:none}blockquote:before,blockquote:after,q:before,q:after{content:none}a{margin:0;padding:0;font-size:100%;vertical-align:baseline;background:transparent}ins{background-color:#ff9;color:#000;text-decoration:none}mark{background-color:#ff9;color:#000;font-style:italic;font-weight:bold}del{text-decoration:line-through}abbr[title],dfn[title]{border-bottom:1px dotted;cursor:help}table{border-collapse:collapse;border-spacing:0}hr{display:block;height:1px;border:0;border-top:1px solid #ccc;margin:1em 0;padding:0}input,select{vertical-align:middle} | |
/** взято с github.com */ | |
@font-face { | |
font-family: 'Octicons Regular'; | |
src: url(github_webfont.eot); | |
src: url(github_webfont_ie.eot) format("embedded-opentype"), | |
url(github_webfont.woff) format("woff"), | |
url(github_webfont.ttf) format("truetype"), | |
url(github_webfont.svg) format("svg"); | |
font-weight: normal; | |
font-style: normal | |
} | |
.mini-icon, .mega-icon { | |
font-family: 'Octicons Regular'; | |
font-weight: normal; | |
font-style: normal; | |
display: inline-block; | |
text-decoration: inherit; | |
line-height: 1; | |
-webkit-font-smoothing: antialiased; | |
line-height: 1; | |
text-decoration: none; | |
} | |
.mini-icon { | |
font-size: 16px; | |
width: 16px; | |
height: 16px; | |
} | |
.mega-icon { | |
font-size: 32px; | |
width: 32px; | |
height: 32px; | |
} | |
.mini-icon-octocat:before { | |
content: "\f008"; | |
} | |
.mini-icon-public-repo:before { | |
content: "\f001"; | |
} | |
.mini-icon-time:before { | |
content: "\f046"; | |
} | |
.mini-icon-link:before { | |
content: "\f05c"; | |
} | |
.mini-icon-location:before { | |
content: "\f060"; | |
} | |
.mini-icon-history:before { | |
content: "\f07e"; | |
} | |
.mega-icon-public-repo:before { | |
content: "\f201"; | |
} | |
/** end */ | |
html, | |
body { | |
width: 100%; | |
height: 100%; | |
overflow: hidden; | |
} | |
body { | |
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGYAAABmCAMAAAAOARRQAAABelBMVEUjJSU6OzshIyM5OjoqKy02NjgsLS01NTYjJCUzNTUgISMlJSc0NTUvMDA6PDwlJyg1NjYoKis2NjYrLS02ODkpKyw0NDYrLC04ODovLzA4Ojo0NDUtLy86OjwjIyU4OTosLS82ODgtLS8hIyQvMTEnKCooKSsrKy0qLCwkJSUnKCkrLCwpKiwwMjIxMzMqLC0tLS0pKissLC00NTYwMDIwMTQpKysoKSovMDEtLzA2OTkxMzUrKywvLy8qKyszNTY5OzsqKiw6OjswMDExNDUoKiozNDUvMDIyNDY1Njg2Njk5OTozMzU0NjY4ODkiIyUiIyQ4OTkuMDEmKCowMjQwMTErLS4qKywwMTMhIiMpKiopKy0tLjAkJScxNDQvLzExNDYyNDQmKCk5OTslJig5OjskJSYxMzQrLS8gISIwMTIoKCk1NTUlJSUnJygwMDA4ODgiIiMhISI8PDw6Ojo5OTkpKSojIyQ7OzsyMjIpKSssLCw6Ozw1NjlrfLakAAAg2UlEQVR42jR6i3ea6rYvPgANIAhVXh8WvkQlioUiFlFcBtAmoiRNdzxqu9p0J7vrdK29zuPeex77nnvO/35n1r1ndHRktI0jTOacv/l7lCBK5UqVpOha/YxmWK7BC4TQFKVXrbYsnimqxuuMVlOQ0XltWjUdCwRJ1M+tC1KudOs9q6+da2adUewG0SC0SwELfHtgDds93VEuydEbl3QMWeNoYkR7b/0x1ZRobGI3mLwzAhePqTAwhg6aogjNsGy7/jwQ4rkdqe7CWLxF8k9LfMVFyRS7VJqtkrW8Vt/bkR8FZJao16ipknbC3Yw2lM7laO6HBEOadEZ2tpf65c4v8e3u7FyU6qbiNNyCuzXZ6pawgnwgmrpTT/Q7w2EZmiIJ0dzWDI7mhQ80IfRnMu2kzA5r5r1pIFoia+/d93HRYp1GV8TbrkWoU/+jdI0Ff6yGwTjT1Hn8J+8m1rKpGiYPuNiHnMtNMIv+zpsk84MYTNW1/+DpwXLvckdOCMYowVNPREe0QlM8xRHXXFhcNDzupwsSmb5pH+0t0RP2Qk+QtI7F1Qm6JRC6ZPBtPq/dq/kH+jxtCljn9TIpW6rQIgmSVyj6lPICIw4N/taka41PFUInth0je9+jO6Kt1G4/a7V2LEgG02B0pHVuCZrgltSKMuIl5SyufUv9mYuQi+mFgzbBEtFo2g+Dh4sSTrLNu8JPh00sQydpb00tqXBvqRN7Q7kqzcnIxCGnvZt/WmJacoOEO6Dcn8Qre03pOCSQxbMOXUuDNx9SxuLz4W1I18gvjViQ67zV0rxdWL8Te/TQkuo8STS41DR48W7L6YP2uWIqiUV8rd6Gbf/rnegKZeG8TpAM6afhGze9JAOxbLjsnUXEbrZ9vLYd7MT32cPF5mKKxmjy7huaoD9n62GOxni3iIJwv0IzZAZjdZkUtolCNLVfYZNaquFjGszVVf+J0vrz4CawoKdHnOzb0NMH7CDBOybfYNJ4rfeMyFNjkFYVTzMFs87rnPGXLUOeNKRVc0LnU7/UIgelzsy3CMuth0YfvnY0wsD3vODUL3eJcKqHQpm8yM3XZQWJxO6Un9iYloyyLpOwN2obHy6W6gbpcb44XmyC+mg+itAcaprGcrwZCqMj/GmtKn0zPvpTz/Cv1dw21XwP3cRupg3H3MF/S71eTKj1YrdwKdc2Mw0fRmb2sFf8lW3aU6JbIZSEPqvXvjM7G/aApyXlXeqKfMq0g/Su3rUGJPSPrtGElgknrZM3xUXqsAP6zMCNVn5u8aJnSNpJv2uru7t2jfRziW2+GuhqfldUNbPk71olwo+46ePUo1U3WKk/e5YK07F/wGRgcpODmQnIlVeHCWBE4puBi2jq28UKpqiN1/4UOrGz59TNYrrQHtd+11sG40BGD+pXdelNqGOg4NXe8W4eacJV/NS9/2Umtym6WQqveqR9xdCMElpxnbkalM4Vf9uaEcWZaKdyibEIjWKxJZPN95niCL3GiaXyssIrHxoLkqkzLCXULN46/f2h3tQJgyip+Tk9EAjJ9aJshq7t8X45aowSKspMSvPf7r9R8yxNptIaHS5ozuEm6luPDApugyNP8OaqiQ4BjaequXA54SLC83eHIY2r+CZp4409Xqw8Aa2oI7XkCrQi+in0w5AqF/kLNrcUz+qkl/lAobY1jSnx5OJNhyXIz3qfNFlXc0TKaglNwdWkWYt9QQ1Kr6W8zue21iNrdJk+N5oCr2O9nEtWKC7IS5J/zdDEYrmnAYfg6agCy+qcgz7ZofeDc4PbUWSvkshWuAc7OjiUyLkj+RAtdlwXJcjxdpkTTHDhK8lBCi8+JtvDVL1W6elmOM++YS0LuSlaP1oUvAeiW3cFnvTr8EbTz1tsSMYdGeZe40sRWu5uAfj7q+ZoKv2FNQ0p5XY1lmlcigHZqTPpabufEVrNuNPi165w3uCVQJHyJqmSJ7ZHnguqwtCmwViIJijj04ba2JNYtB+yORf5gg1/9t9iw4vUpeqiunSAbf+IBdj/b+iG2qrHvuNP0Vd/+ThVZT/lrvHYjjgDbbyxaqgHNM2uhxa1GW3UedZYhMMwM4mQhltouK+IV4NdbIQNM+8Yv311RZk9kT4tiYR4LkyFcuPpdcjuhUuFqBAWRZa11lcZ3gEBlXywsNhrt+plISZP5DlsV9l4EgY6J3yZPTUcMrgaWAT3oI79eSbGEbcJpr6BD8kyDiVt+G0/hXosQN4NFXKlfWIfsIs0BHODVok1/IGnKFHJYIquh8Xo+2+bkQNTGgWmN/fZ0Y33LSj6lr1GyV7mWIKg7ZTRZPGuhF/zjRNcQ1UPtSYgnWQxSs0yrVhwNDcdGMNSNe2JT3WuzbAM3HykyAajS3Uphf6STKEqxLas9EnmnhA/lyj9Uj+JoY7SVgVmGLl46Rm2u98sbkap2lzAdKBG4r6LgulQOSSjQv1GWdQ0jtDUK/mAaqM1Uqjpu4k3Rvfvxv7YTxLSK+wN3E5jVIzmF23uZ7hiH/sVP49D7tvoKp4S8b1LuvRlivVB/algbhcFITYVXvDpLzpDfplR2uD5V4XJFxpjmIpLc9Y5sB2TpBRix7Bme6GZIq+06v3XzNeTcA4obQIKxrnT4C2JpOqD92dbmSX8MGazly5EsZVMvSU1f4RZwyu8iQXbVdeLlZrjuTT1jrY1uk5c7iZ7RsvhhluqAkq4JpVQAg7RJFtSu+xgJ8Pv6O1j5DkLxT8mkbfyRW5DrQmG7hiDIjCgBsADbjuof6YHLGeV6a5Q1Smx9joUXPpdaaDx97A/Wq00oJkdR7ZYuQRfS533JtxO1erduqWOYIt3wh0wpbLuCNIYkwxbswbikCUu2CDCS+Q+7rgVtfRcm+SOcdKPRlZ/rE7wNVUEE39KTS5uvUKN1PUnkloPkyzhyGQ8qkouEjJ3H/VXdqG6asSRiw3ecMlBvDDt8dDhBHXMwZ2Cajzjr7/76T+IavqPYvz6r7//E/3X3+N//h/0QozbjPgPiir69P/8X3/9F/yv8b/827/++98WItPu5/Hvwd8YPf5bp/2/lX/T/+Of/0MJ/lYTa+L/Ef+d9vN/3/2T6P/+jyTzu/evf6U7vxN7B6pJkRtAF6jUr8I+P8RsP/ptGhfqFk+pQ/DgAy6NJtRYJdXmp4gK7WLqLKJ+MaKhGjOojvL+SnIWrkpy0SLHDe4QuyNzaEA15mLMCcmE8Em+4HdOihW4/ZWuppJEmzeAwcDtv7MuLc9y2V5atvxXNe3S4DUMt5/Qy2LM9kSYKiVWBuKlfp4nxTntpuW03JbIlkiRvBXmT23g1I2OYe6IizUHPIq6zm6mbfsbteKmi/sg9J+ocQBMctGFO7iljo8TPN+z3jxw4do+ZwfqoR9dkNTKHyM305GpTkfhcHexVkPVGEbUOjuo9f0UMPHBFlGEx0SLvJvVRKTwW7PSew5oPme+E42+frJa9cGt2njS3dK5kIif2eYbhuSEQXEqMVfUjhGIuin0G0/W5ezJyJQy3SpMLai4M0JUWb5u1k9tny5bd1pPwYBpQuDCXZl62xg4CdVEAtflXHs6JKmP/pH6mOl796Lgopj0o8d5kKh00hxG3OSdEE/QBo9Hgr8JJqAeLDwJohG5j/DGh61Rc/+tf22/8kEnxHNCEjo0ElvvGfESZkqmz2BDcKV1H1buSkhkdg7p1IMGs2s17nYjpblrWuE2K9WEO/hcRp5e9oOF/QBmOaDtgil+oaU6szPrdwW65fOB0KUTsVUn7LFU7J8e6cxJIl9+FHw5MQMzuQJ+4oxMH3iW/5GK+hWuG0T+gTLs+fAjdtUd58TmIUq04EeyRCYCjkldow234aIgR5bqwrtZosZ+6YEqAmDqatJ9lWasz4IquKALPtd92hGI3Z2BdzzZue+REl1Om4DIWD+RrtUTOJLI+S0jHowXXdAxsGLSd40zYNuEUlOGhrwL6c7tcOtUOvpJCP7QBQS19H+GvZn05ewjlVLz+IGKoC9TyfQjLMBNmXCuqqtTdOSukZW48B0HqgSTCBrBnlFvF4CG2Su7yFzqmJFURK3UmTT3ru050r0ptUpMilYnBJWfl2Bv6kPlUuE1kxxpdzui9AubsR2N2boVSu81OulAwBqoSr1LZ0LLYOomyZHmjqnXlP72s8LnDouEJjtodBvdHaG1jMySYO7crWd90MpCRyCG14vb5IE7Arupw/y/RcCm/Tm3zK6zYj8PYNaGldiUfkB/LHWcmf2lVM+mwyU27a0qq2tscrQ/vzBjN26DnntIrOyGizzXK35yKQdYnUABkyN4saz3WD/viF+eCcsXnIajdWYJWaYHRstIis9CS+tqnFGmz2j5uzfr3Z4prqgK4XOT/PyftvjZqIm8lhkfxJ7Ol3CJF1piYBGAG8wtAk56Drw1YwmOpcz+NdfkSpSLplRXLXHL0Rquj6YW/gabqgK7Dgr6NwtH0B/AN7XrN+MVJ6AmXmUuqmQulrNNYPmH0RoDogydOKLo/QbfYNARSQQKISRCzRXU+q9WWJFL3LZW6u34CkeG97xC0NNGaJ0bvK6SnZS3zPskr5EtuCgjMWR5o2x5BqhKmDWJPRe7JMEOyRb5uUKlHaGVtq5ivSOaSliSXp9SQm2qk8MRJh10MAp9QQ2H5t59J8rjiwSZtoIfMGjlLPVNdYl/LBR0AO6WLGDmkLkIPRE45Y9MftdAK/yNu1Hn6tzOQTesgQ+8fSzB19wO91vCnO23vOWQdwJ63SJrYjdfKFW6W281PKs2k8iT9ai1cgJ4sa3xqdvmtxR8/+D1B8AKc2u+6JftryRhMWSQtoSBgIyyQGyxcnELuAasXN12oSriU4RMz1DD6RL0TSV+om7i1Yt+jEE/jnawM8cX/UhN4nkiv/w9eALrzNhXuQfOzFL0Fi6SjF7/4Qn8rLYBoa85cvgAnkCEBP+HPbEnquVXCZsMS/yzYw2Vru60P/+nJPYKkzZFjmbykzUoEqV836T5q3fP/L383dF82tx18/AZgZczMAgyeWYKmSZIqtHL+e+O4ZRcq9VI3g/qPeCoiK4pcgEqdbS0S/Be54sbVQOuJVPNBblIghzeasNu7h/g+Sz1IdhI5lCwq1nUb3Ji4OCIcqQZqtqJ5w7rXrg/DA9IgVmEGhDgGecEwnCTHffXcXs0V3OCEVzYDKS1vp/oX+ng+6XVU86UjA6FMO2RXOOOrqY1GgPvrAk9HV/BXtCu5RuwF8qgdGDLsBcui4E33ymdBip1X8uKyhIWT8qNRDsXz+gvO9UiEC0d8RG4Tf2x8H4slljgHtCBcxHLTWOYJm5H/fCPCzOgf9qgOUxTRZ0Pc6ha5yLuLVT9ntvIa6gacE99mCovdUumTQdRP4RPsS9129eEe2uSvvGh0bV4Y3QPPhPZMqhZWSMa5R0Hc1SGO4IVOQc0FrirlibTVfKRrYkD8kz3b+X65/QkUNaZdrdl3mCap0Hf3YcCw/LiouJYNbqz88UqeDYv93yO7vvXtgl4XCyAO4ODkY6W+83+LZU//p3/zXNGGrUKClCiOnL27iJZbNWDF02XXAOeFlB7IaADoMH1Yqr+UP9biyZDEa/iJt4MDeIz6GKTdLVBfWGVtRN4fdT2rgReX8UXwF2zOrradm4J0nyTgdPnai3RvzpZvCKDUqjOwD/QA6EDaMCLewX6QWYVnHY1sx1bd8ovYnPm1ZvPH+rE20lWjOCnZ66/xDt0QAl15FjfBcZp+i9OU0RNPQ0t3x2pSNWo8eiYudwsnuP1Hq6iH1LJCJynkYsfgJ0p3pF6SoQk2l+jqE8CPk+ziGJRSKjs+W5AO185umPdkYzlK4wl7TC9NxyyDP7ZoyYVoXiuS6SjnInlLWrwz1i8bGTKXX0AVQWkSfIlglW3zRJRJ8bg5VgE6ZEnqNu9B++0GNQvDQJvFize4ESNKBJP+8vA3LM4AX5SIBq08Mob+7QMTCZx4nwP/64+4BnlZC+8WtlP/CXw6t1PwMwkJ3jhP1FiXLhDF/3I6FGUzO2DSi9ABxKyyL9paZxSEz40ZCPQToDAJu1959k7QdbVxgB4icsu2s4zsTPJhcEDo+N1GX4zSk/wriRh8AqwL62972i9HJHd1ydaLXVzvKvOfGGw5RVcUVMiKXFH4APdkQU/dc5BX0YfKTNZYXCW9mb8bc8mufoQP6BbdQmT99ZjoYfr/go4TgQX9IDgztim7wyFeGMfbNaeqj8Dzs38pgcqwSv2hbqB3oSGKWKy+sesY7p57wAHldqE6NDudk/W7s/zjrK4rZFlFvaGxnSZdHbc1y47qDN6xkoK8O3bfr2j41dlJZ71rB4dlDqapPFa8N6xBrprUdtenUCHwxKNhw1uuTBh+9uU45k4REpQABN2bAO9DSLqoIL26gNroWgup5pUMxHUNSq4Gyz47vBPvilpo5f9OYI2ddAqTqmnxXERxQJ3UK8fHbVE9HagHi3+tqNRoNsArdmAxHA5LwtQo9ZAaNKUTljnokljo2x8scqVpEEIPc01fPCdHOCg0DeWBz8D5TVAAfx8aRH5X2ZYNI3ebKDZdeJ+oBDAxmRqJ30Eh2/DaeAy5diVNMpEDmXiPDsGTzBLXy8eVDdJoIafgx/gxMyQi454QrW56nCyeELgSuNNEmYkflF+t3CZQOVRWjKhIuCclmQSlAXT3+4JGG75B4t/5hQ+ldMP4LsAW6z3XmU6IJJwpnGVnsgUZhoY1fZlwTR8wSU7xRejf2uCx9Z5trVTRRJP9KnEb134dEieil6eCOGWgboI7xsqsqM99jfJLTePjygKlH2CVxxsse9QRzTBFjD/Kjqitr/CCTBt/SJ6nLxz7cKP9pFqBpp0lN5y+adKNsZjrPuroemZauH9aTTFD3EKHW8S55XBLFQAt1jgxTQCTwxmx/JyfsZDN1RroN3VaxpSenpIX7K+ZbL8VdlQDcI4Cbzg3QJLa9yVqNxUelu+EtxLVqeekaAvSJkO6sSVqbUajxqhKshNpvZqoeApF0k/0P0ikkwUcbdwc4A1ejN7Oo0O15kG7hTMoK3hZRBCX7YYeLW0wvcXx/18n/u37yLgzBYVBUvORGli+sfRcX/74uD6P4hq+7xu54TlWJLFzT63uwUDwuEDdOjJQqx7JV+ZjaEAPi7t0MMrR4Q8Rkf18uxD6RK0RKh0hL8YU+DeL97i4pa5ZSyAfXKwZRS/8gXcxdZXm62RBDj8U3sN8x95b5PpPs/mCBKYvpaA50pN5Ct/499AFTtwQ5vgeSh+NHrKIi4NVpwM/XzRaNfJD856lPE6M21zWPguFsH7jbLVyEDfRmt4VwrhCJ5VTYmcSPfGgO5clfN+vbaDZ7sakU5+2vZ2WCDY031NxJarVytfDDVtiafcTGO2rJ/taoL3zChN2qmjxofczTOYQPPVQPh0JVtYgdUQINcSiNEEy58UdYXX1MpWUCEBx7LbcGtAm8XWRQTVOaoV3ySri4RShhs/B/0m4jX6OAwXOvcA09bNSG4czEGv/Wey6V/jbTCNTW6awXdNTcA1GsPe1E9fZdGl7R0vyoVpIdJtfC6d32NNErrvq/R+d65VG+YOwRXppXxOCYyGNSf1K3x6VxAW/vtz4EC1SgCOSPdN62sLsoIzuDfg8GwZAbquVO8HIuFP/ToVoeUB7nnwMF35a1wK1tI6fkrqFKhQdeJpwyls0pIy8AZde3/6LUUbFaYJthyUJSU/kqDXTLQElnn0Jr4B2RVghNrmNmoEn7pXIeshPguXVsvwoTdmClq49JJU3LWhHyWTrJL9bRP6VKv3tZoA/th77p5Jw++OEENvyvWy/pNeExiDUVQaXIRGh8xySZTI36yueFaSXo1uJY0RnXYgEOoWWOJHeaVuX/bGNhHsh2yinznl/++NJcE9j6fBPRcBdq9hb8awNw8U7Bl6GM7x69EDOIIbX/npZ++amlHR9L/35mE/2Ss4gb0xCcY4VyTFLRE796vHysLAamqcyO+aFQyJIDBNslbH2/MrAvZiSEIedc/cqjmv4fbda2pXbv+F5a2szSsdkm9noiNURXt8edUhGUF6fSZWd1IJaXKFwD+49R6eCXD4Bkef7j9tRtNMVgW8BhRz/Qpy1TmeYk0doyjZoJSbePOReVHgkFsCFuQJ+Lgc4BxeAsK/cOiNDRmdNw0ctYhn/nQ498dYI5znzGLoJi1rav7Cn88rL3wLePVtDK5gl77Tki3gHEsIAQ2+IKgarj7Y8W1IQzV5V9N+0TjLqbg68WfKcOmBCOj3JkwJhVIkwDhc+JorXuZEPMEh0vvH3x7iqf+VAwXgd4diZiaJD1zHL9Snx6Wfg4IugreyhabQkcir+y5XgDtdx3Avs7lkeeCBwDvZoTUCXx5QrZkcEqWfYEiEYRs/EphmRALSNGR1Iclgdr5VFoELpzF4++f35w3/j0t5ucW3n2ch4PQCLuUXupsPRR7UA5FjSKrMtPcKAZJfagO4lGE7FH3YKMjorpK0ZxAv+i2JkJhtAMWWWFej4RhPR/cJ3DxwocCvXDi4SGZU4cu+K32XndiFWgopAl+0GApcwf1XvymJcFs39jExIBO4yUjU9MExBLQYc9H+W7+IgdESPRpciT+rKZPebVtaVq+1GYO/5xTAL3HASjNTGIgMvdjWbgc7JvdE1zIFpuC0U9ESiZyzBixzxWxj4Kwh8My34q+FK3KNLtmsA1qyrmKSNQOXCPUZd+ONelBTvFoUI/CYsqa/RhtKiyMf2CgSFqEPk59Y3uqnlZ8gFpswfSYyko23yVZYxzKGxGm49Zqxg1l8oz5Ra9XaRwHkuxepmgyhm0SoNy2KlbcEqK+9QqS9PNx9Ihm9U7gsR55SSJ1FBDNnkuWKxIZ0SDpXuOGwZdoUbOMDPHP4vBAgz2VlSEJAHZGJVbYIg7l/FO5KfIVvxC8pPPxMGcNMoevFDeStt2iqztE10n2TA4dgJH76YS9HDhKHD3iCx6ieFX84BAI3QQnngh76f5ruPQVbr5qZmck/5UjDc26lfrOvUBWy0Ogl8bCoOkMOns81TnC3cuUS9KW8+9A+fe3XYZOFUPG1u5epSSmDLw0s5s2F0W30ANeo+zJkJQz9SPZgzwYpEoktofhGVfmLOAB20boCbW1QWq/NpET/hnMecw/uSyAH4NJc3ECOU4nnkK1fj3S/i5dwb3R7k00AqQQUwt7Ie1qV0aY/VQX0J8hLPy7eBNXMHYZYDNxHZ2Qh6AuXJxq+AeRec/Q+JLhZV6hpXwQEzw7bf5v9uUf2vpq3qlhmy0IIGTkwYdCfSAFmqbdo+3XvDTDjFJde0mbeQLcn2n31xaAqJ0ixO/CLsT4I4G4DoncVTgRGNBtsCcjISWT+oeXZ4Iedw/8OsJI1aPnNKLX/60VvcZb94uasRxCkqlPQ11u1Sa2hHvB80WQENxVyzjns0/PiEByyil21Te6oisk3mNCEMrhouCFO3yEZTHHOCMy9eb/4Tmi8cVf3Lf7P53SY2hX3PSN033As3ETIMLHWumWEO9JXHA2y2SIBlIPpLGG2qvNsCIlIr+B1SWAqRKm2w6Blf7U+zCSBwJrfHG5i8J5Gax/cVonMlon7aHJX/gSvucIncRP93XCqkv7D8IFKFsLiBgHqUpXhE3pYjEcV1dk/JD9zFVCfEaQIVX8Jmfz7IIofcBKQ4OaG+C3xC2veX9CD+iAFXDNaGg9eTVxvkbJRJlW4Nk9Wk13kn696jWppRDe/8pDrYMO9ZyxZ98ReKSz9kWKLLyk2zCZgAniCkLJVX3n1M9DYbomyahWiv/KixRIV9hj/oFz87I+HLznbPTjpa+D+bZQnMuRsljTpv90vQUt/pK7jCFnA30B/jtroSF2/m/gpWn1aQs5WeA6ghzF8SdqWI20fghdSeDOCSCmLgTkfaGgGDmw7nHFkRzGtag57IHS2na06I+gzEphXo1w/Zx2BM/jKL2nZoFjHggtFQjYi8nSVRSXIE58RPbBObXk7uuIL9+rs/5Zo7suJInEUxgsiZZAWS25iBtpEiZeBgDtghEoAE0sjcayNq85M4tbu/LF5h51335PsGzQ09O875+vUS89lkWMyNOFoip2PuyWyMP/iU2XIZdfCCJNDjebDoBLQdpy7QQZC7s9c0wjHJervQNDu2jWzBW5MSAJMr7bP+Iv92BkS/GGgzjEn7MF1IRKFwwzbjbS4/slGOmhx9cZrFu7HSEefojNv3r0UaKfKOWzXsq1zEugbzlMDFsacRJJI/iJlK3vtkZ+PLZIVMFlKA32wbq2Kd5T0uCLZ1CPkAfCdzkz2EYscjDcZq2AWfziN2covN4kXE1lQXPPLTNM1xx3tbiepcO/t3SWm4w87qfh99SL0ZnY+LKFPLPeXVM2mIIoVWt+9Nk0I7nY4O79iGYqxZ8RVz289an6NVdJWnSKZvJQCAuHNiVaDxPAFoH392t9wot5t0/qmU95eEWNbU2udUW5sN9JVqcYlvAIfLeYC33oUzzxZgSktsv21mA7Uly1FA5VnoJFh6N244Wmv3YJGFv/TCPryaw+ZORlpZjQdq/2DYXr3EZskfed0G61P09ipTKmlTQ1067Rg5+PAk5FlQ9e0SWbGf2B/08kqymOTMVOznsALHHNFH4LFRKl2F/NOiYFl9khNHnSu9Ak5sq26Ynl/i2fdTle29Y1ugqmR5Yj4YT9pvslFyYCbw0mNFr5rVQm1LvkG27QMq9ph3t8fmn6r6SQ4oSbr5tz+J1kIawGzDxb6VYOvvWhobDTXfBeNv3b4aNm5XUinsCGqG2q/45m3+LoCOsddFceYhRx1Tsss9PLdPfJdErFMjYd3gddjiP0+XQjcRadZP6bwNLySvunFf20Czy6JqdEW2a96KxdYdOryBv1BjbuUq2yCHeh+6sk7fGmmPi50pe/1l5TyPe5oHW9oPnhPswLyf2TFDdCyYlhwBCstv5C1HwlW7xWoGT9XZt4qVj5WryLPLLD6h/5cMLEjWzgCeAIKNsLak92aBqBsHl4AJwl2N4jfvbSkBExGimv0nFvv09uDScQbjx+w4kPQjgjlW+g9ws9VEJvI2k8N6XxVu0uIwovgTFdunG24gBtaDi+y1YLQwZ8mwbip5fVlO3k0n0AEr/ETbtu8Vjkm+nNSiEb7X/3fMjBL5A8PdgG+/FnbexbFFExmEfetXAnisEKy5z44WVPpQZjSy/jzeGn4yDRsFGqhh87QPaDBWhlo37IFbe/C0xynS91d2tP/AJoJS0sVF6iwAAAAAElFTkSuQmCC'); | |
} | |
label { | |
color: #f9f9f9; | |
} | |
.popup { | |
position: absolute; | |
overflow: hidden; | |
z-index: 10; | |
} | |
#controls { | |
left: -1px; | |
top: -1px; | |
z-index: 11; | |
padding: 5px; | |
vertical-align: middle; | |
border-radius: 0 0 3px 0; | |
width: 100%; | |
} | |
#controls input, | |
#controls button, | |
#controls label { | |
display: inline-block; | |
} | |
input[type=text], | |
input[type=number] { | |
border: 1px solid #b9b9b9; | |
display: block; | |
padding: 5px; | |
font-size: 14px; | |
margin: 0; | |
outline: 0; | |
} | |
input[type=text]:hover, | |
input[type=number]:hover, | |
input[type=text]:focus, | |
input[type=number]:focus { | |
border-color: #000; | |
-webkit-box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3); | |
-moz-box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3); | |
-o-box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3); | |
-ms-box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3); | |
box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.3); | |
} | |
#controls input { | |
font-family: sans-serif; | |
font-weight: bolder; | |
} | |
#console { | |
bottom: 0; | |
left: 0; | |
z-index: 100; | |
} | |
/* progress bar */ | |
.meter { | |
overflow: hidden; | |
position: relative; | |
background: #555; | |
padding: 10px; | |
-webkit-box-shadow: inset 0 -1px 1px rgba(255, 255, 255, 0.3); | |
-moz-box-shadow: inset 0 -1px 1px rgba(255, 255, 255, 0.3); | |
box-shadow: inset 0 -1px 1px rgba(255, 255, 255, 0.3); | |
} | |
.meter > span { | |
display: block; | |
background-color: rgb(43, 194, 83); | |
/*background-image: -webkit-gradient(linear, left bottom, left top, color-stop(0, rgb(43, 194, 83)), color-stop(1, rgb(84, 240, 84))); | |
background-image: -moz-linear-gradient(center bottom, rgb(43, 194, 83) 37%, rgb(84, 240, 84) 69%);*/ | |
-webkit-box-shadow: inset 0 2px 9px rgba(255, 255, 255, 0.3), inset 0 -2px 6px rgba(0, 0, 0, 0.4); | |
-moz-box-shadow: inset 0 2px 9px rgba(255, 255, 255, 0.3), inset 0 -2px 6px rgba(0, 0, 0, 0.4); | |
box-shadow: inset 0 2px 9px rgba(255, 255, 255, 0.3), inset 0 -2px 6px rgba(0, 0, 0, 0.4); | |
position: relative; | |
overflow: hidden; | |
min-height: 10px | |
} | |
.orange > span { | |
background-color: #f1a165; | |
background: rgb(241,161,101); | |
/*background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2YxYTE2NSIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNmMzZkMGEiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); | |
background: -moz-linear-gradient(top, rgba(241,161,101,1) 0%, rgba(243,109,10,1) 100%); | |
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(241,161,101,1)), color-stop(100%,rgba(243,109,10,1))); | |
background: -webkit-linear-gradient(top, rgba(241,161,101,1) 0%,rgba(243,109,10,1) 100%); | |
background: -o-linear-gradient(top, rgba(241,161,101,1) 0%,rgba(243,109,10,1) 100%); | |
background: -ms-linear-gradient(top, rgba(241,161,101,1) 0%,rgba(243,109,10,1) 100%); | |
background: linear-gradient(to bottom, rgba(241,161,101,1) 0%,rgba(243,109,10,1) 100%); | |
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f1a165', endColorstr='#f36d0a',GradientType=0 );*/ | |
} | |
.red > span { | |
background-color: #f0a3a3; | |
/*background-image: -moz-linear-gradient(top, #f0a3a3, #f42323); | |
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0, #f0a3a3), color-stop(1, #f42323)); | |
background-image: -webkit-linear-gradient(#f0a3a3, #f42323);*/ | |
} | |
.progressBar { | |
font-size: 11px; | |
width: 100%; | |
} | |
.progressBar .meter { | |
margin: 0; | |
padding: 1px; | |
} | |
/*.progressBar .meter > span*/ | |
#progressBar { | |
text-align: right; | |
vertical-align: middle; | |
color: white; | |
text-shadow: 0 1px 1px black; | |
word-wrap: normal; | |
white-space: nowrap; | |
text-overflow: ellipsis; | |
} | |
/* end progress bar */ | |
#statusBar { | |
bottom: 0; | |
left: 0; | |
z-index: 12; | |
width: 100%; | |
position: fixed; | |
border: 0; | |
border-top: 1px solid #CACACA; | |
background: rgb(239,239,239); | |
/*background: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiA/Pgo8c3ZnIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjEwMCUiIGhlaWdodD0iMTAwJSIgdmlld0JveD0iMCAwIDEgMSIgcHJlc2VydmVBc3BlY3RSYXRpbz0ibm9uZSI+CiAgPGxpbmVhckdyYWRpZW50IGlkPSJncmFkLXVjZ2ctZ2VuZXJhdGVkIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeDE9IjAlIiB5MT0iMCUiIHgyPSIwJSIgeTI9IjEwMCUiPgogICAgPHN0b3Agb2Zmc2V0PSIwJSIgc3RvcC1jb2xvcj0iI2VmZWZlZiIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjQxJSIgc3RvcC1jb2xvcj0iI2RkZGRkZCIgc3RvcC1vcGFjaXR5PSIxIi8+CiAgICA8c3RvcCBvZmZzZXQ9IjEwMCUiIHN0b3AtY29sb3I9IiNjYWNhY2EiIHN0b3Atb3BhY2l0eT0iMSIvPgogIDwvbGluZWFyR3JhZGllbnQ+CiAgPHJlY3QgeD0iMCIgeT0iMCIgd2lkdGg9IjEiIGhlaWdodD0iMSIgZmlsbD0idXJsKCNncmFkLXVjZ2ctZ2VuZXJhdGVkKSIgLz4KPC9zdmc+); | |
background: -moz-linear-gradient(top, rgba(239,239,239,1) 0%, rgba(221,221,221,1) 41%, rgba(202,202,202,1) 100%); | |
background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgba(239,239,239,1)), color-stop(41%,rgba(221,221,221,1)), color-stop(100%,rgba(202,202,202,1))); | |
background: -webkit-linear-gradient(top, rgba(239,239,239,1) 0%,rgba(221,221,221,1) 41%,rgba(202,202,202,1) 100%); | |
background: -o-linear-gradient(top, rgba(239,239,239,1) 0%,rgba(221,221,221,1) 41%,rgba(202,202,202,1) 100%); | |
background: -ms-linear-gradient(top, rgba(239,239,239,1) 0%,rgba(221,221,221,1) 41%,rgba(202,202,202,1) 100%); | |
background: linear-gradient(to bottom, rgba(239,239,239,1) 0%,rgba(221,221,221,1) 41%,rgba(202,202,202,1) 100%); | |
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#efefef', endColorstr='#cacaca',GradientType=0 );*/ | |
} | |
#statusBar ul { | |
padding: 2px 3px; | |
overflow: hidden; | |
margin: 0; | |
list-style: none; | |
} | |
#statusBar li { | |
display: block; | |
vertical-align: middle; | |
float: left; | |
margin-right: 2px; | |
border: 0; | |
border-right: 1px solid #444; | |
} | |
#statusBar li:last-child { | |
margin-right: 0; | |
border-right: 0; | |
} | |
#layers, | |
#canvas, | |
#svg, | |
canvas, | |
svg { | |
position: relative; | |
width: 100%; | |
height: 100%; | |
} | |
#svg, #canvas { | |
position: absolute; | |
top: 0; | |
left : 0; | |
} | |
#svg { | |
z-index: 1; | |
} | |
#canvas { | |
z-index: 0; | |
} | |
#layers { | |
background: rgba(224, 224, 224, .1); | |
} | |
.axis text { | |
font: 10px sans-serif; | |
fill: #ccc; | |
} | |
.axis line, | |
.axis path { | |
fill: none; | |
stroke: #ccc; | |
shape-rendering: crispEdges; | |
} | |
#ldrCont { | |
z-index: 100; | |
top: 0; | |
left: 0; | |
text-align: center; | |
width: 100%; | |
height: 100%; | |
} | |
#ldrCont > img { | |
display: inline-block; | |
position:relative; | |
top:49%; | |
width: 48px; | |
height: auto; | |
} | |
.lineFiles { | |
fill: none; | |
shape-rendering: crispEdges; | |
stroke-width: 2px; | |
} | |
.lineFiles .M { | |
stroke: rgba(255, 184, 119, .5); | |
} | |
.lineFiles .A { | |
stroke: rgba(165, 236, 110, .5); | |
} | |
.lineFiles .D { | |
stroke: rgba(255, 119, 255, .5); | |
} | |
.cRepo { | |
cursor: pointer; | |
} | |
.cRepo text { | |
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); | |
pointer-events: none; | |
} | |
.cRepo:hover text { | |
text-shadow: 0 1px 2px rgba(255, 255, 255, 1); | |
} | |
.tooltip { | |
color: #f9f9f9; | |
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.5); | |
background: rgba(110, 130, 163, 0.7); | |
border: 1px dotted #8D9DB6; | |
padding: 5px; | |
border-radius: 3px; | |
} | |
#tooltip { | |
z-index: 50; | |
display: none; | |
max-width: 25%; | |
pointer-events: none; | |
} | |
/* http://xbreaker.github.com/plusstrap/base-css.html#buttons */ | |
.btn { | |
display: inline-block; | |
*display: inline; | |
*zoom: 1; | |
padding: 0px 8px; | |
font-weight: bold; | |
margin-bottom: 0; | |
font-size: 11px; | |
line-height: 22px; | |
*line-height: 22px; | |
text-align: center; | |
vertical-align: middle; | |
cursor: default; | |
color: #333333; | |
text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75); | |
background-color: #f3f3f3; | |
background-image: -moz-linear-gradient(top, #f5f5f5, #f1f1f1); | |
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f1f1f1)); | |
background-image: -webkit-linear-gradient(top, #f5f5f5, #f1f1f1); | |
background-image: -o-linear-gradient(top, #f5f5f5, #f1f1f1); | |
background-image: linear-gradient(to bottom, #f5f5f5, #f1f1f1); | |
background-repeat: repeat-x; | |
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff1f1f1', GradientType=0); | |
border-color: #e4e4e4; | |
*background-color: #f1f1f1; | |
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); | |
border: 1px solid rgba(0, 0, 0, 0.1); | |
*border: 0; | |
border-bottom-color: rgba(0, 0, 0, 0.1); | |
-webkit-border-radius: 2px; | |
-moz-border-radius: 2px; | |
border-radius: 2px; | |
*margin-left: .3em; | |
} | |
.btn:not(.active):hover { | |
background-color: #f5f5f5; | |
background-image: -moz-linear-gradient(top, #f9f9f9, #eeeeee); | |
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f9f9f9), to(#eeeeee)); | |
background-image: -webkit-linear-gradient(top, #f9f9f9, #eeeeee); | |
background-image: -o-linear-gradient(top, #f9f9f9, #eeeeee); | |
background-image: linear-gradient(to bottom, #f9f9f9, #eeeeee); | |
background-repeat: repeat-x; | |
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9', endColorstr='#ffeeeeee', GradientType=0); | |
} | |
.btn:hover, | |
.btn:active, | |
.btn.active, | |
.btn.disabled, | |
.btn[disabled] { | |
color: #333333; | |
background-color: #eeeeee; | |
*background-color: #e4e4e4; | |
-webkit-box-shadow: 0 1px 0px #dedede; | |
-moz-box-shadow: 0 1px 0px #dedede; | |
box-shadow: 0 1px 0px #dedede; | |
border-color: #cbcbcb; | |
} | |
.btn:active, | |
.btn.active { | |
background-color: #d8d8d8 \9; | |
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .2); | |
-moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .2); | |
box-shadow: inset 0 1px 2px rgba(0, 0, 0, .2); | |
} | |
.btn:first-child { | |
*margin-left: 0; | |
} | |
.btn:hover { | |
color: #333333; | |
text-decoration: none; | |
background-color: #e6e6e6; | |
*background-color: #d9d9d9; | |
-webkit-transition: background-position 0.1s linear; | |
-moz-transition: background-position 0.1s linear; | |
-o-transition: background-position 0.1s linear; | |
transition: background-position 0.1s linear; | |
} | |
.btn:focus { | |
outline: thin dotted #333; | |
outline: 5px auto -webkit-focus-ring-color; | |
outline-offset: -2px; | |
} | |
.btn.active, | |
.btn:active { | |
background-color: #e6e6e6; | |
background-color: #d9d9d9 \9; | |
background-image: none; | |
outline: 0; | |
} | |
.btn.disabled, | |
.btn[disabled] { | |
cursor: default; | |
background-color: #e6e6e6; | |
background-image: none; | |
opacity: 0.65; | |
filter: alpha(opacity=65); | |
-webkit-box-shadow: none; | |
-moz-box-shadow: none; | |
box-shadow: none; | |
} | |
/** end **/ | |
#controls .btn { | |
padding: 2px 8px; | |
margin: 0; | |
} | |
.row { | |
display: block; | |
max-width: 100%; | |
} | |
#divStat img, | |
.statInfo img { | |
float: left; | |
margin: 0 0 0 0; | |
padding: 1px; | |
background: #fff; | |
box-shadow: 0 1px 2px rgba(0,0,0,0.15); | |
} | |
#divStat ul, | |
.statInfo ul { | |
overflow: hidden; | |
padding: 0; | |
list-style: none; | |
} | |
#divStat li, | |
.statInfo li { | |
color: #ccc; | |
} | |
hr { | |
margin: 5px 0; | |
} | |
#divStat li strong, | |
#divStat li a, | |
.statInfo li strong, | |
.statInfo li a { | |
margin-left: 5px; | |
} | |
#divStat li strong, | |
#divStat h1, | |
.statInfo li strong, | |
.statInfo h1 { | |
color: #f9f9f9; | |
} | |
#curRep .a-icon, | |
#divStat .a-icon, | |
.statInfo .a-icon { | |
text-decoration: none; | |
color: rgba(172, 213, 229, 1); | |
} | |
#divStat a, | |
.statInfo a { | |
color: rgba(172, 213, 229, 1); | |
} | |
#curRep .a-icon:hover, | |
#divStat .a-icon:hover, | |
#divStat a:hover, | |
.statInfo .a-icon:hover, | |
.statInfo a:hover { | |
color: rgba(221, 246, 255, 1); | |
} | |
#curRep { | |
vertical-align: middle; | |
text-align: left; | |
} | |
#curRep .mega-icon { | |
font-size: 24px; | |
width: 24px; | |
height: inherit; | |
position: relative; | |
} | |
#curRep .mini-icon-link:before, | |
#curRep .mega-icon-public-repo:before { | |
position: absolute; | |
top: -16px; | |
} | |
#userInfo, | |
.userInfo { | |
right: -2px; | |
top: -2px; | |
padding: 7px 7px 5px 5px; | |
z-index: 52; | |
} | |
#userInfo ul, | |
.userInfo ul { | |
white-space: nowrap; | |
-webkit-transition: all .4s; | |
-moz-transition: all .4s; | |
-o-transition: all .4s; | |
transition: all .4s; | |
max-width: 0; | |
max-height: 0; | |
} | |
#userInfo img, | |
.userInfo img { | |
-webkit-transition: all .5s ease-in-out .4s; | |
-moz-transition: all .5s ease-in-out .4s; | |
-o-transition: all .5s ease-in-out .4s; | |
transition: all .5s ease-in-out .4s; | |
width : 48px; | |
height : auto; | |
} | |
#userInfo.open img, | |
#userInfo:hover img, | |
.userInfo.open img, | |
.userInfo:hover img { | |
-webkit-transition: all .5s; | |
-moz-transition: all .5s; | |
-o-transition: all .5s; | |
transition: all .5s; | |
margin-right: 10px; | |
width : 96px; | |
height : auto; | |
} | |
#userInfo.open ul, | |
#userInfo:hover ul, | |
.userInfo.open ul, | |
.userInfo:hover ul { | |
-webkit-transition: all .5s ease-in-out .5s; | |
-moz-transition: all .5s ease-in-out .5s; | |
-o-transition: all .5s ease-in-out .5s; | |
transition: all .5s ease-in-out .5s; | |
max-width: 960px; | |
max-height: 1280px; | |
} | |
/** stepbar */ | |
.steps { | |
list-style: none; | |
margin: 0; | |
} | |
.steps > li { | |
display: block; | |
float: left; | |
position: relative; | |
padding: 4px; | |
border: 1px solid white; | |
border-right-style: dotted; | |
border-left-style: dotted; | |
margin-right: 1em; | |
background: #50617F; | |
padding-right: 2px; | |
margin-left: -17px; | |
padding-left: 24px; | |
/*text-align: right;*/ | |
box-shadow: 2px 4px 5px rgba(0, 0, 0, .5); | |
} | |
.steps > li .sub { | |
text-align: left; | |
display: block; | |
overflow: hidden; | |
margin-left: -22px; | |
} | |
.steps > li:first-child .sub { | |
margin-left: 0; | |
} | |
.steps > li .sub { | |
max-height: 0; | |
max-width: 0; | |
-webkit-transition: max-height .7s ease-in-out .2s, max-width .2s ease-in-out .9s; | |
-moz-transition: max-height .7s ease-in-out .2s, max-width .2s ease-in-out .9s; | |
-o-transition: max-height .7s ease-in-out .2s, max-width .2s ease-in-out .9s; | |
transition: max-height .7s ease-in-out .2s, max-width .2s ease-in-out .9s; | |
} | |
.steps > li:hover .sub { | |
max-height: 960px; | |
max-width: 960px; | |
-webkit-transition: max-height .5s ease-in-out .3s, max-width .2s ease-in-out .1s; | |
-moz-transition: max-height .5s ease-in-out .3s, max-width .2s ease-in-out .1s; | |
-o-transition: max-height .5s ease-in-out .3s, max-width .2s ease-in-out .1s; | |
transition: max-height .5s ease-in-out .3s, max-width .2s ease-in-out .1s; | |
} | |
.steps > li:first-child { | |
border-radius: 5px 0 0 5px; | |
border-left: 1px solid #ffffff; | |
margin-left: 0; | |
padding-left: 4px; | |
} | |
.steps > li:hover { | |
border-right-style: solid; | |
border-left-style: solid; | |
} | |
.steps > li:after, | |
.steps > li:before { | |
width: 0; | |
height: 0; | |
content: ""; | |
display: inline-block; | |
position: absolute; | |
} | |
.steps > li:after { | |
border: 1.248em solid transparent; | |
border-left-color: #ffffff; | |
top: -0.05em; | |
right: -2.45em; | |
z-index: 0; | |
} | |
.steps > li:before { | |
border: 1.13em solid transparent; | |
border-left-color: #50617F; | |
top: .02em; | |
right: -2.25em; | |
z-index: 1; | |
} | |
.steps.sfirst > li:not(.first) { | |
border-color: #ccc; | |
background: #858689; | |
} | |
.steps.sfirst > li:not(.first):after { | |
border-left-color: #ccc; | |
} | |
.steps.sfirst > li:not(.first):before { | |
border-left-color: #858689; | |
} | |
.steps.ssecond > li.third { | |
border-color: #ccc; | |
background: #858689; | |
} | |
.steps.ssecond > li.third:after { | |
border-left-color: #ccc; | |
} | |
.steps.ssecond > li.third:before { | |
border-left-color: #858689; | |
} | |
.steps > li > label { | |
vertical-align: middle; | |
} | |
.sub > div { | |
padding: 5px; | |
} | |
.sub blockquote { | |
padding: 3px; | |
margin: 2px 0; | |
background: rgba(255, 252, 196, .6); | |
border-left: 2px solid rgba(255, 252, 196, 1); | |
font-style: italic; | |
color: rgba(255, 252, 196, 1); | |
text-shadow: 0 1px 2px rgba(0, 0, 0, .5); | |
} | |
blockquote.green { | |
/*background: rgba(161, 237, 144, .3); | |
color: rgb(198, 244, 188); | |
border-left: 2px solid rgb(198, 244, 188);*/ | |
background: rgba(198, 245, 188, .6); | |
color: rgb(31, 166, 31); | |
border-left: 2px solid rgb(31, 166, 31); | |
} | |
/** end stepbar */ | |
.barLang circle, | |
.barLang path { | |
} | |
.barLang path { | |
fill: none; | |
stroke-width: 1px; | |
} | |
.barLang text { | |
pointer-events: none; | |
text-shadow : 0 0 3px rgba(0, 0, 0, 1); | |
} | |
.barLang .barSelect { | |
stroke: #000; | |
stroke-opacity: 0; | |
stroke-width: 1px; | |
fill: #f9f9f9; | |
fill-opacity: 0; | |
-webkit-transition: all 1.5s; | |
-moz-transition: all 1.5s; | |
-o-transition: all 1.5s; | |
transition: all 1.5s; | |
} | |
.barLang:hover .barSelect { | |
fill-opacity: .6; | |
stroke-opacity: .6; | |
-webkit-transition: all .5s; | |
-moz-transition: all .5s; | |
-o-transition: all .5s; | |
transition: all .5s; | |
} | |
.field { | |
padding: 3px; | |
} | |
.setting { | |
list-style: none; | |
text-shadow: 0 1px 2px rgba(0, 0, 0, .5); | |
} | |
.setting input { | |
padding: 0; | |
margin: 0; | |
} | |
.setting h1 { | |
color: rgba(0, 0, 0, .8); | |
text-shadow: 0 1px 1px rgba(255, 255, 255, .5); | |
} | |
.setting > li { | |
border: 1px dotted rgba(255, 255, 255, .5); | |
background: rgba(255, 255, 255, .2); | |
} | |
.setting > li .group { | |
list-style: none; | |
vertical-align: middle; | |
} | |
.group > li { | |
display: inline-block; | |
} | |
.com-mess { | |
font-size: 11pt; | |
font-family: Verdana,serif; | |
fill: #ffffff; | |
fill-opacity: .3; | |
} | |
.mono { | |
font-family: monospace; | |
font-size: 10pt; | |
} | |
#visBtnResume .mini-icon-history { | |
position: relative; | |
height: 0; | |
} | |
#visBtnResume .mini-icon-history:before { | |
position: absolute; | |
top: -12px; | |
left: 0; | |
} | |
.gtLeg, .gttLeg { | |
fill : #f9f9f9; | |
text-shadow: 0 1px 2px rgba(0, 0, 0, .5); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* User: ArtZub | |
* Date: 15.01.13 | |
* Time: 1:34 | |
*/ | |
'use strict'; | |
var PIdiv2 = Math.PI / 2, | |
smallRad = PIdiv2 * (1 / 15), | |
TT_PAD = 8 | |
; | |
var colors = { | |
additions : "#ddffdd", | |
deletions : "#ffdddd", | |
changes : "#FFF1DD", | |
center : "#FF6600", | |
stroked : "#f9f9f9", | |
addedFile : "#A5EC6E", | |
modifiedFile : "#FFB877", | |
deletedFile : "#FF77B5", | |
decolor : "#888888" | |
}; | |
function toRgba(color, a) { | |
color = d3.rgb(color); | |
return "rgba(" + [color.r, color.g, color.b, a || 1] + ")"; | |
} | |
var vis = { | |
sC : function(a, b) { | |
return d3.ascending(b.date, a.date); | |
}, | |
mtt : function(d) { | |
if (toolTip) { | |
var e = d3.event; | |
if (arguments.length > 3) | |
e = arguments[3]; | |
toolTip | |
.style("top", e.pageY > h / 2 ? (e.pageY - toolTip.node().clientHeight - TT_PAD) + "px" : (e.pageY + TT_PAD) + "px") | |
.style("left", e.pageX > w / 2 ? (e.pageX - toolTip.node().clientWidth - TT_PAD) + "px" : (e.pageX + TT_PAD) + "px") | |
; | |
} | |
} | |
}; | |
function initGraphics(svg) { | |
vis.layers = (function(data) { | |
var ls = { _data : data }; | |
svg.selectAll("g.layer") | |
.data(data, function(d) {return d.name}) | |
.enter() | |
.append("g") | |
.each(function(d) { | |
ls[d.name] = d3.select(this).attr("class", "layer").attr("width", w).attr("height", h); | |
ls[d.name].getOrder = function() { | |
return d.order; | |
return this; | |
}; | |
ls[d.name].toFront = function() { | |
d.order && | |
vis.layers.ordering(this, 0); | |
return this; | |
}; | |
ls[d.name].hide = function() { | |
ls[d.name].visible = false; | |
this.style("display", "none"); | |
return this; | |
}; | |
ls[d.name].show = function() { | |
ls[d.name].visible = true; | |
this.style("display", null); | |
return this; | |
}; | |
ls[d.name].visible = true; | |
}); | |
return ls; | |
})([ | |
{name : "repo", order : 2}, | |
{name : "stat", order : 1}, | |
{name : "show", order : 0} | |
]); | |
vis.layers.ordering = function(layer, order) { | |
function s(a, b) { | |
return d3.ascending(b.order, a.order); | |
} | |
var _d = (layer instanceof Array || layer instanceof Object ? layer : this[layer]); | |
_d = _d ? (_d instanceof Array ? _d.datum() : _d) : null; | |
if (_d) { | |
this._data.forEach(function(d) { | |
_d != d && d.order >= order && d.order++; | |
}); | |
_d.order = order; | |
svg.selectAll("g.layer").sort(s); | |
} | |
return this; | |
}; | |
vis.resources = { | |
}; | |
vis.inited = true; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment