chunk progress bar replaced with canvas implementation, global download graph also added

This commit is contained in:
Hamza Zia 2012-08-05 02:37:25 +08:00
parent 88d3b394d1
commit 04823ecfd1
3 changed files with 1227 additions and 47 deletions

View File

@ -35,6 +35,10 @@
float: right; float: right;
margin-bottom: 5px; margin-bottom: 5px;
} }
.stat_graph {
margin-top: 25px;
height: 220px;
}
.active_settings { .active_settings {
text-align: center; text-align: center;
margin-bottom: 3px; margin-bottom: 3px;
@ -103,13 +107,7 @@
<div class="bar" style="width: {{percentage}}%;"></div> <div class="bar" style="width: {{percentage}}%;"></div>
</div> </div>
<div class="span11 more_info collapse"> <div class="span11 more_info collapse">
<div class="span11 active_chunks"> <canvas class="span10 progress chunk-canvas"></canvas>
{{#chunks}}
<div class="progress progress-chunk progress-striped" style="width:{{width}}%;">
<div class="bar" style="width: {{progress}}%;"></div>
</div>
{{/chunks}}
</div>
<b class="span2 label active_settings">Status: <span class="tmp_status">{{status}}</span></b> <b class="span2 label active_settings">Status: <span class="tmp_status">{{status}}</span></b>
<b class="span2 label active_settings">GID: <span class="tmp_gid">{{gid}}</span></b> <b class="span2 label active_settings">GID: <span class="tmp_gid">{{gid}}</span></b>
<b class="span2 label active_settings">Dir: <span class="tmp_dir">{{dir}}</span></b> <b class="span2 label active_settings">Dir: <span class="tmp_dir">{{dir}}</span></b>
@ -509,6 +507,8 @@
<h5 class="span3 badge" style="text-align: center; margin: 5px;">Total Active Downloads: <span class="stat_numActive"></span></h5> <h5 class="span3 badge" style="text-align: center; margin: 5px;">Total Active Downloads: <span class="stat_numActive"></span></h5>
<h5 class="span3 badge" style="text-align: center; margin: 5px;">Total Waiting Downloads: <span class="stat_numWaiting"></span></h5> <h5 class="span3 badge" style="text-align: center; margin: 5px;">Total Waiting Downloads: <span class="stat_numWaiting"></span></h5>
<h5 class="span3 badge" style="text-align: center; margin: 5px;">Total Stopped Downloads: <span class="stat_numStopped"></span></h5> <h5 class="span3 badge" style="text-align: center; margin: 5px;">Total Stopped Downloads: <span class="stat_numStopped"></span></h5>
<div class="span5 stat_graph">
</div>
</p> </p>
</div> </div>
<div class="modal-footer"> <div class="modal-footer">

1157
js/; Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
var graphSize = 15; var graphSize = 15;
var graphData = []; var graphData = [];
var globalGraphData = null;
var modals = { var modals = {
err_connect: undefined, err_connect: undefined,
change_conf: undefined, change_conf: undefined,
@ -204,6 +205,26 @@ $(function() {
web_sock_init(); web_sock_init();
update_ui(); update_ui();
globalGraphData = {
downSpeed: [],
upSpeed: [],
add: function(arr, val) {
if (arr.length == graphSize) {
arr.shift();
}
arr.push([((new Date - this.start)/1000).toFixed(0), val]);
},
addDown: function(val) {
this.add(this.downSpeed, val);
return this;
},
addUp: function(val) {
this.add(this.upSpeed, val);
return this;
},
plot: createGraph('.stat_graph'),
start: new Date()
};
$('#newDownload').click(function() { $('#newDownload').click(function() {
$('#newDownload_url').val(""); $('#newDownload_url').val("");
$('.download_urls').html(""); $('.download_urls').html("");
@ -426,25 +447,25 @@ function getChunksFromHex(bitfield, numOfPieces) {
var chunks = [], len = 0, numPieces = parseInt(numOfPieces); var chunks = [], len = 0, numPieces = parseInt(numOfPieces);
var totalDownloaded = 0; var totalDownloaded = 0;
if (numPieces > 1) { if (numPieces > 1) {
var chunk_width = 95 / numPieces; var chunk_ratio = 1 / numPieces;
var piecesProcessed = 0; var piecesProcessed = 0;
for (var i = 0; i < bitfield.length; i++) { for (var i = 0; i < bitfield.length; i++) {
var hex = parseInt(bitfield[i], 16); var hex = parseInt(bitfield[i], 16);
for (var j = 1; j <= 4; j++) { for (var j = 1; j <= 4; j++) {
var bit = hex & (1 << (4 - j)); var bit = hex & (1 << (4 - j));
if (bit) totalDownloaded++; if (bit) totalDownloaded++;
var prog = bit ? 100 : 0; var prog = !!bit;
if (len >= 1 && chunks[len - 1].progress == prog) { if (len >= 1 && chunks[len - 1].show == prog) {
chunks[len - 1].width += chunk_width; chunks[len - 1].ratio += chunk_ratio;
} }
else { else {
chunks.push({ chunks.push({
width: chunk_width, ratio: chunk_ratio,
progress: prog show: prog
}); });
len++; len++;
} }
piecesProcessed ++; piecesProcessed++;
if (piecesProcessed == numPieces) if (piecesProcessed == numPieces)
return chunks; return chunks;
} }
@ -495,36 +516,21 @@ function updateDownloadTemplates(elem, ctx) {
if (!chunks || !chunks.length) { if (!chunks || !chunks.length) {
return; return;
} }
var partialParent = elem.find(".active_chunks"); var canvas = elem.find(".chunk-canvas")[0];
var diff = partialParent.children().length - chunks.length; if (!canvas) {
if (diff > 0) { console.log("cant find canvas!!!", elem);
partialParent.children().slice(0, diff).remove(); return;
/*
diff = (partialParent.children().length - chunks.length);
if (diff != 0) {
console.log(diff);
console.log("diff error in deleting!!!");
return;
}
*/
} }
else if (diff < 0){ var ctx = canvas.getContext('2d');
diff = (-1) * diff; ctx.fillStyle = "#149BDF";
var html = '<div class="progress progress-striped progress-chunk" style="width:' var x = 0,
+ chunks[0].width + '%;"><div class="bar" style="width: 0%;"></div></div>'; width = canvas.width,
partialParent.append((new Array(diff + 1)).join(html)); height = canvas.height;
/* chunks.forEach(function(c) {
diff = (partialParent.children().length - chunks.length); var dx = c.ratio * width;
if (diff != 0) { if (c.show)
console.log(diff); ctx.fillRect(x, 0, dx, height);
console.log("diff error in appending!!!"); x += dx;
return;
}
*/
}
partialParent.children().each(function(index, node) {
$(node).css({width: chunks[index].width.toString() + "%" });
$(node).children().css({width: chunks[index].progress.toString() + "%" });
}); });
} }
function deleteDownloadTemplates(top_elem, data) { function deleteDownloadTemplates(top_elem, data) {
@ -576,7 +582,6 @@ function updateGraph(gid) {
if (graphData[i].gid == gid) { if (graphData[i].gid == gid) {
var moreInfo = $(elem).find(".more_info"); var moreInfo = $(elem).find(".more_info");
if (moreInfo.hasClass("in")) { if (moreInfo.hasClass("in")) {
window.data = graphData[i];
graphData[i].plot.setData([{ graphData[i].plot.setData([{
label: "Download Speed", label: "Download Speed",
data: graphData[i].downSpeed, data: graphData[i].downSpeed,
@ -594,8 +599,8 @@ function updateGraph(gid) {
} }
} }
} }
function createGraph(gid) { function createGraph(selector) {
return $.plot('[data-gid=' + gid + '] .active_graph', [{ return $.plot(selector, [{
label: "Download Speed", label: "Download Speed",
data: [], data: [],
color: "#ff0000", color: "#ff0000",
@ -649,7 +654,7 @@ function updateGraphData(data) {
this.add(this.upSpeed, val); this.add(this.upSpeed, val);
return this; return this;
}, },
plot: that.createGraph(gid), plot: that.createGraph('[data-gid=' + gid + '] .active_graph'),
start: new Date() start: new Date()
} }
})().addDown(downSpeed).addUp(upSpeed)); })().addDown(downSpeed).addUp(upSpeed));
@ -1009,11 +1014,29 @@ function updateDownloads() {
} }
function updateGlobalStatistics(data) { function updateGlobalStatistics(data) {
globalGraphData.addDown(parseFloat(data.downloadSpeed));
globalGraphData.addUp(parseFloat(data.uploadSpeed));
data.downloadSpeed = changeLength(data.downloadSpeed, "B/s"); data.downloadSpeed = changeLength(data.downloadSpeed, "B/s");
data.uploadSpeed = changeLength(data.uploadSpeed, "B/s"); data.uploadSpeed = changeLength(data.uploadSpeed, "B/s");
for(var i in data) { for(var i in data) {
$('.stat_' + i).text(data[i]); $('.stat_' + i).text(data[i]);
} }
if (globalGraphData) {
globalGraphData.plot.setData([{
label: "Download Speed",
data: globalGraphData.downSpeed,
color: "#ff0000",
lines: { show: true }
}, {
label: "Upload Speed",
data: globalGraphData.upSpeed,
color: "#00ff00",
lines: { show: true }
}]);
globalGraphData.plot.setupGrid();
globalGraphData.plot.draw();
}
} }
function custom_global_statistics() { function custom_global_statistics() {
var tmpl = $('#global_statistics_template').text(); var tmpl = $('#global_statistics_template').text();