From fcc5a85a76994b2bd78ed58f1c96f8ed36bbecf7 Mon Sep 17 00:00:00 2001 From: Hauke Klement Date: Tue, 17 Feb 2015 14:07:48 +0100 Subject: [PATCH] added dynamic container pool graph to administrator dashboard --- app/assets/javascripts/dashboard.js | 80 ++++++++++++++++++++++-- app/helpers/application_helper.rb | 2 +- app/views/admin/dashboard/show.html.slim | 9 ++- config/locales/de.yml | 2 + config/locales/en.yml | 2 + 5 files changed, 88 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/dashboard.js b/app/assets/javascripts/dashboard.js index 1e1437c9..dd6cdf25 100644 --- a/app/assets/javascripts/dashboard.js +++ b/app/assets/javascripts/dashboard.js @@ -1,16 +1,85 @@ $(function() { + var CHART_START = window.vis ? vis.moment().add(-1, 'minute') : undefined; var DEFAULT_REFRESH_INTERVAL = 5000; - var refreshData = function() { + var dataset = undefined; + var graph = undefined; + var groups = undefined; + + var buildChartGroups = function() { + return _.map($('tbody tr[data-id]'), function(element) { + return { + content: $('td.name', element).text(), + id: $(element).data('id'), + visible: false + }; + }); + }; + + var initializeChart = function() { + dataset = new vis.DataSet(); + groups = new vis.DataSet(buildChartGroups()); + graph = new vis.Graph2d(document.getElementById('graph'), dataset, groups, { + dataAxis: { + customRange: { + left: { + min: 0 + } + }, + showMinorLabels: false + }, + drawPoints: { + style: 'circle' + }, + end: vis.moment(), + legend: true, + shaded: true, + start: CHART_START + }); + }; + + var refreshChart = function() { + var now = vis.moment(); + var window = graph.getWindow(); + var interval = window.end - window.start; + graph.setWindow(now - interval, now); + }; + + var refreshData = function(callback) { var jqxhr = $.ajax({ dataType: 'json', method: 'GET' }); - jqxhr.done(updateView); + jqxhr.done(function(response) { + (callback || _.noop)(response); + setGroupVisibility(response); + updateChartData(response); + updateTable(response); + requestAnimationFrame(refreshChart); + }); + }; + + var setGroupVisibility = function(response) { + _.each(response.docker, function(data) { + groups.update({ + id: data.id, + visible: data.pool_size > 0 + }); + }); + }; + + var updateChartData = function(response) { + _.each(response.docker, function(data) { + dataset.add({ + group: data.id, + x: vis.moment(), + y: data.quantity + }); + }); }; var updateProgressBar = function(progress_bar, data) { - var percentage = Math.round(data.quantity / data.pool_size * 100); + var percentage = Math.min(Math.round(data.quantity / data.pool_size * 100), 100); progress_bar.attr({ 'aria-valuemax': data.pool_size, 'aria-valuenow': data.quantity, @@ -19,7 +88,7 @@ $(function() { progress_bar.html(data.quantity); }; - var updateView = function(response) { + var updateTable = function(response) { _.each(response.docker, function(data) { var row = $('tbody tr[data-id=' + data.id + ']'); $('.pool-size', row).html(data.pool_size); @@ -28,7 +97,8 @@ $(function() { }); }; - if ($.isController('dashboard')) { + if ($.isController('dashboard') && $('#graph').isPresent()) { + initializeChart(); refreshData(); var refresh_interval = location.search.match(/interval=(\d+)/) ? parseInt(RegExp.$1) : DEFAULT_REFRESH_INTERVAL; setInterval(refreshData, refresh_interval); diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 411a6760..7051ff0b 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -34,7 +34,7 @@ module ApplicationHelper def progress_bar(value) content_tag(:div, class: 'progress') do - content_tag(:div, "#{value}%", :'aria-valuemax' => 100, :'aria-valuemin' => 0, :'aria-valuenow' => value, class: 'progress-bar', role: 'progressbar', style: "width: #{value}%;") + content_tag(:div, "#{value}%", :'aria-valuemax' => 100, :'aria-valuemin' => 0, :'aria-valuenow' => value, class: 'progress-bar', role: 'progressbar', style: "width: #{[value, 100].min}%;") end end diff --git a/app/views/admin/dashboard/show.html.slim b/app/views/admin/dashboard/show.html.slim index b1ee33a8..122fac63 100644 --- a/app/views/admin/dashboard/show.html.slim +++ b/app/views/admin/dashboard/show.html.slim @@ -1,8 +1,13 @@ +- content_for :head do + = javascript_include_tag('//cdnjs.cloudflare.com/ajax/libs/vis/3.10.0/vis.min.js') + = stylesheet_link_tag('//cdnjs.cloudflare.com/ajax/libs/vis/3.10.0/vis.min.css') + h1 = t('breadcrumbs.dashboard.show') h2 Docker - if DockerContainerPool.config[:active] + h3 = t('.current') .table-responsive table.table thead @@ -13,8 +18,10 @@ h2 Docker tbody - ExecutionEnvironment.order(:name).each do |execution_environment| tr data-id=execution_environment.id - td = link_to(execution_environment, execution_environment) + td.name = link_to(execution_environment, execution_environment) td.pool-size td.quantity = progress_bar(0) + h3 = t('.history') + #graph - else p = t('.inactive') diff --git a/config/locales/de.yml b/config/locales/de.yml index 65f9b8db..452c27e5 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml @@ -126,6 +126,8 @@ de: admin: dashboard: show: + current: Aktuelle Verfügbarkeit + history: Verfügbarkeitsverlauf inactive: Der Container-Pool ist nicht aktiv. quantity: Verfügbare Container application: diff --git a/config/locales/en.yml b/config/locales/en.yml index c57c01e3..354c8b78 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -126,6 +126,8 @@ en: admin: dashboard: show: + current: Current Availability + history: Availability History inactive: Container pooling is not enabled. quantity: Available Containers application: