From 37c55bcbf8fc2431ba77565711a4075930834b68 Mon Sep 17 00:00:00 2001 From: Scott Schneider Date: Thu, 12 Dec 2013 10:52:45 -0800 Subject: [PATCH 1/6] Add dashboard API paths --- vmware-host-pooler-api | 62 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) diff --git a/vmware-host-pooler-api b/vmware-host-pooler-api index 0b50845..de9cda2 100755 --- a/vmware-host-pooler-api +++ b/vmware-host-pooler-api @@ -1,6 +1,9 @@ #!/usr/bin/ruby +require 'rubygems' + require 'json' +require 'open-uri' require 'redis' require 'sinatra' require 'yaml' @@ -25,7 +28,64 @@ $redis = Redis.new # Sinatra! get '/' do - puts '' + erb :dashboard +end + +get '/dashboard/stats/vcloud/numbers' do + result = Hash.new + result['pending'] = 0 + result['ready'] = 0 + result['running'] = 0 + result['completed'] = 0 + + config[:pools].each do |pool| + result['pending'] += $redis.scard( 'vmware_host_pool__pending__' + pool['name'] ) + result['ready'] += $redis.scard( 'vmware_host_pool__ready__' + pool['name'] ) + result['running'] += $redis.scard( 'vmware_host_pool__running__' + pool['name'] ) + result['completed'] += $redis.scard( 'vmware_host_pool__completed__' + pool['name'] ) + end + + content_type :json + JSON.pretty_generate( result ) +end + +get '/dashboard/stats/vcloud/pool' do + result = Hash.new + + config[:pools].each do |pool| + result[pool['name']] ||= Hash.new + result[pool['name']]['size'] = pool['size'] + result[pool['name']]['ready'] = $redis.scard( 'vmware_host_pool__ready__' + pool['name'] ) + end + + if ( params[:history] ) + history ||= Hash.new + + buffer = open( 'http://'+config[:config]['graphite']+'/render?target=vcloud.ready.*&from=-1hour&format=json' ).read + history = JSON.parse( buffer ) + + history.each do |pool| + if pool['target'] =~ /.*\.(.*)$/ + pool['name'] = $1 + pool['last'] = result[pool['name']]['size'] + result[pool['name']]['history'] ||= Array.new + + pool['datapoints'].each do |metric| + 8.times do |n| + if ( metric[0] ) + pool['last'] = metric[0].to_i + result[pool['name']]['history'].push( metric[0].to_i ) + else + result[pool['name']]['history'].push( pool['last'] ) + end + end + end + end + end + end + + content_type :json + JSON.pretty_generate( result ) end get '/status' do From 7e3169bc701836fdc8f57dd1d2d089fe106c3068 Mon Sep 17 00:00:00 2001 From: Scott Schneider Date: Thu, 12 Dec 2013 11:12:13 -0800 Subject: [PATCH 2/6] Add dashboard (initial) --- public/dashboard.css | 138 ++++++++++++++++++++++ public/img/logo.jpg | Bin 0 -> 12559 bytes public/img/spinner.svg | 38 ++++++ public/lib/stats-vcloud-numbers.js | 183 +++++++++++++++++++++++++++++ public/lib/stats-vcloud-pool.js | 166 ++++++++++++++++++++++++++ views/dashboard.erb | 21 ++++ views/layout.erb | 29 +++++ 7 files changed, 575 insertions(+) create mode 100644 public/dashboard.css create mode 100644 public/img/logo.jpg create mode 100644 public/img/spinner.svg create mode 100644 public/lib/stats-vcloud-numbers.js create mode 100644 public/lib/stats-vcloud-pool.js create mode 100644 views/dashboard.erb create mode 100644 views/layout.erb diff --git a/public/dashboard.css b/public/dashboard.css new file mode 100644 index 0000000..7cea080 --- /dev/null +++ b/public/dashboard.css @@ -0,0 +1,138 @@ +body, +#content { + margin-top: 20px; + width: 960px; + margin-left: auto; + margin-right: auto; +} + +#header { + border-bottom: solid 1px #888; + margin-bottom: 20px; +} + +#header .logo, +#header .text { + margin-left: 30px; + margin-bottom: 5px; + display: inline-block; +} + +#header .text { + float: right; + position: relative; + right: 30px; + top: 100px; + font: 50px 'PT Sans' sans-serif; + letter-spacing: -0.05em; + color: #444; +} + +.label { + text-transform: uppercase; + text-indent: 25px; + font: 12px 'PT Sans' sans-serif; + font-weight: bold; + line-height: 20px; + color: #888; + border-bottom: solid 1px #888; +} + +.spinner { + background-image: url( '/img/spinner.svg' ); + width: 15px; + height: 15px; + background-size: contain; + opacity: .7; + float: left; + margin-right: 5px; + -webkit-animation:rotate 1.5s infinite steps( 12 ); + -moz-animation:rotate 1.5s infinite steps( 12 ); + -ms-animation:rotate 1.5s infinite steps( 12 ); + -o-animation:rotate 1.5s infinite steps( 12 ); + animation:rotate 1.5s infinite steps( 12 ); +} +@keyframes 'rotate' { + from { + -webkit-transform: rotate( 0deg ); + -moz-transform: rotate( 0deg ); + -o-transform: rotate( 0deg ); + -ms-transform: rotate( 0deg ); + transform: rotate( 0deg ); + } + to { + -webkit-transform: rotate( 360deg ); + -moz-transform: rotate( 360deg ); + -o-transform: rotate( 360deg ); + -ms-transform: rotate( 360deg ); + transform: rotate( 360deg ); + } +} +@-moz-keyframes rotate { + from { + -moz-transform: rotate( 0deg ); + transform: rotate( 0deg ); + } + to { + -moz-transform: rotate( 360deg ); + transform: rotate( 360deg ); + } +} +@-webkit-keyframes 'rotate' { + from { + -webkit-transform: rotate( 0deg ); + transform: rotate( 0deg ); + } + to { + -webkit-transform: rotate( 360deg ); + transform: rotate( 360deg ); + } +} +@-ms-keyframes 'rotate' { + from { + -ms-transform: rotate( 0deg ); + transform: rotate( 0deg ); + } + to { + -ms-transform: rotate( 360deg ); + transform: rotate( 360deg ); + } +} +@-o-keyframes 'rotate' { + from { + -o-transform: rotate( 0deg ); + transform: rotate( 0deg ); + } + to { + -o-transform: rotate( 360deg ); + transform: rotate( 360deg ); + } +} + +.module { + margin-top: 5px; + margin-left: 25px; + font: 13px 'PT Sans' sans-serif; + line-height: 20px; + color: #888; +} + +.line { + fill: none; +} + +.area { + stroke-width: 0; +} + +.axis path, +.axis line { + fill: none; + stroke: #fff; + shape-rendering: crispEdges; +} + +.tick { + fill: none; + stroke: #eee; +} diff --git a/public/img/logo.jpg b/public/img/logo.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5f4b0867cc72bf1d129afac2f920da5bf82a075e GIT binary patch literal 12559 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 literal 0 HcmV?d00001 diff --git a/public/img/spinner.svg b/public/img/spinner.svg new file mode 100644 index 0000000..52de3bc --- /dev/null +++ b/public/img/spinner.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/public/lib/stats-vcloud-numbers.js b/public/lib/stats-vcloud-numbers.js new file mode 100644 index 0000000..c08d390 --- /dev/null +++ b/public/lib/stats-vcloud-numbers.js @@ -0,0 +1,183 @@ +var numbers_url = '/dashboard/stats/vcloud/numbers'; +var numbers_width = 130; +var numbers_height = 45; + +var stats_vcloud_numbers__data = {}; +var stats_vcloud_numbers__svg = {}; + +d3.json( numbers_url, + + function( stats_vcloud_numbers__data ) { + + ( function tick() { + setTimeout( function() { + var stats_vcloud_numbers__data__live = ( function() { + var stats_vcloud_numbers__data__live = null; + + $.ajax( { + 'url': numbers_url, + 'async': false, + 'global': false, + 'dataType': 'json', + 'success': function( data ) { + stats_vcloud_numbers__data__live = data; + } + } ); + + return stats_vcloud_numbers__data__live; + } )(); + + $( '#stats-vcloud-numbers' ).empty(); + + stats_vcloud_numbers__svg[ 'ready' ] = d3.select( '#stats-vcloud-numbers' ) + .append( 'svg' ) + .style( 'margin', '10 25 0 0' ) + .style( 'padding', '0 0 20 0' ) + .attr( 'width', numbers_width ) + .attr( 'height', numbers_height ); + + stats_vcloud_numbers__svg[ 'ready' ] + .append( 'text' ) + .text( + ( 'ready and waiting' ) + ) + .attr( { + 'x': '5', + 'y': numbers_height + 6, + 'font-face': 'PT Sans sans-serif', + 'font-size': '12px', + 'font-weight': 'bold', + 'fill': '#888' + } ); + + stats_vcloud_numbers__svg[ 'ready' ] + .append( 'text' ) + .text( + ( stats_vcloud_numbers__data__live[ 'ready' ] ) + ) + .attr( { + 'x': '0', + 'y': '36', + 'font-face': 'PT Sans sans-serif', + 'font-weight': 'bold', + 'font-size': '50px', + 'letter-spacing': '-0.05em', + 'fill': '#444' + } ); + + stats_vcloud_numbers__svg[ 'pending' ] = d3.select( '#stats-vcloud-numbers' ) + .append( 'svg' ) + .style( 'margin', '10 25 0 0' ) + .style( 'padding', '0 0 20 0' ) + .attr( 'width', numbers_width ) + .attr( 'height', numbers_height ); + + stats_vcloud_numbers__svg[ 'pending' ] + .append( 'text' ) + .text( + ( 'being built' ) + ) + .attr( { + 'x': '5', + 'y': numbers_height + 6, + 'font-face': 'PT Sans sans-serif', + 'font-size': '12px', + 'font-weight': 'bold', + 'fill': '#888' + } ); + + stats_vcloud_numbers__svg[ 'pending' ] + .append( 'text' ) + .text( + ( stats_vcloud_numbers__data__live[ 'pending' ] ) + ) + .attr( { + 'x': '0', + 'y': '36', + 'font-face': 'PT Sans sans-serif', + 'font-weight': 'bold', + 'font-size': '50px', + 'letter-spacing': '-0.05em', + 'fill': '#444' + } ); + + stats_vcloud_numbers__svg[ 'running' ] = d3.select( '#stats-vcloud-numbers' ) + .append( 'svg' ) + .style( 'margin', '10 25 0 0' ) + .style( 'padding', '0 0 20 0' ) + .attr( 'width', numbers_width ) + .attr( 'height', numbers_height ); + + stats_vcloud_numbers__svg[ 'running' ] + .append( 'text' ) + .text( + ( 'running tests' ) + ) + .attr( { + 'x': '5', + 'y': numbers_height + 6, + 'font-face': 'PT Sans sans-serif', + 'font-size': '12px', + 'font-weight': 'bold', + 'fill': '#888' + } ); + + stats_vcloud_numbers__svg[ 'running' ] + .append( 'text' ) + .text( + ( stats_vcloud_numbers__data__live[ 'running' ] ) + ) + .attr( { + 'x': '0', + 'y': '36', + 'font-face': 'PT Sans sans-serif', + 'font-weight': 'bold', + 'font-size': '50px', + 'letter-spacing': '-0.05em', + 'fill': '#444' + } ); + + stats_vcloud_numbers__svg[ 'completed' ] = d3.select( '#stats-vcloud-numbers' ) + .append( 'svg' ) + .style( 'margin', '10 25 0 0' ) + .style( 'padding', '0 0 20 0' ) + .attr( 'width', numbers_width ) + .attr( 'height', numbers_height ); + + stats_vcloud_numbers__svg[ 'completed' ] + .append( 'text' ) + .text( + ( 'waiting to die' ) + ) + .attr( { + 'x': '5', + 'y': numbers_height + 6, + 'font-face': 'PT Sans sans-serif', + 'font-size': '12px', + 'font-weight': 'bold', + 'fill': '#888' + } ); + + stats_vcloud_numbers__svg[ 'completed' ] + .append( 'text' ) + .text( + ( stats_vcloud_numbers__data__live[ 'completed' ] ) + ) + .attr( { + 'x': '0', + 'y': '36', + 'font-face': 'PT Sans sans-serif', + 'font-weight': 'bold', + 'font-size': '50px', + 'letter-spacing': '-0.05em', + 'fill': '#444' + } ); + + tick(); + }, 5000 ); + } )(); + + } + +); + diff --git a/public/lib/stats-vcloud-pool.js b/public/lib/stats-vcloud-pool.js new file mode 100644 index 0000000..077cda1 --- /dev/null +++ b/public/lib/stats-vcloud-pool.js @@ -0,0 +1,166 @@ +var pool_url = '/dashboard/stats/vcloud/pool'; +var pool_width = 130; +var pool_height = 70; + +var stats_vcloud_pool__data = {}; +var stats_vcloud_pool__svg = {}; + +d3.json( pool_url+'?history=1', + + function( stats_vcloud_pool__data ) { + + var stats_vcloud_pool__data__keys = []; + + for ( var key in stats_vcloud_pool__data ) { + stats_vcloud_pool__data__keys.push( key ); + } + + stats_vcloud_pool__data__keys.sort().map( + function( pool ) { + stats_vcloud_pool__data[ pool ][ 'r' ] = stats_vcloud_pool__data[ pool ][ 'history' ]; + } + ); + + ( function tick() { + setTimeout( function() { + var stats_vcloud_pool__data__live = ( function() { + var stats_vcloud_pool__data__live = null; + + $.ajax( { + 'url': pool_url, + 'async': false, + 'global': false, + 'dataType': 'json', + 'success': function( data ) { + stats_vcloud_pool__data__live = data; + } + } ); + + return stats_vcloud_pool__data__live; + } )(); + + $( '#stats-vcloud-pool' ).empty(); + + stats_vcloud_pool__data__keys.sort().map( + function( pool ) { + var x = d3.scale.linear().domain( [ 0, 500 ] ).range( [ 0, pool_width ] ); + var y = d3.scale.linear().domain( [ parseInt( stats_vcloud_pool__data__live[ pool ][ 'size' ] ), 0 ] ).range( [ 0, pool_height ] ); + + var area = d3.svg.area() + .interpolate( 'basis' ) + .x( function( d, i ) { return x( i ); } ) + .y0( pool_height ) + .y1( function( d ) { return y( d ); } ); + + var path = d3.svg.line() + .interpolate( 'basis' ) + .x( function( d, i ) { return x( i ); } ) + .y( function( d ) { return y( d ); } ); + + stats_vcloud_pool__data[ pool ][ 'r' ].push( parseInt( stats_vcloud_pool__data__live[ pool ][ 'ready' ] ) ); + + var pool_current = stats_vcloud_pool__data[ pool ][ 'r' ].slice( -1 )[ 0 ]; + var pool_size = stats_vcloud_pool__data[ pool ][ 'size' ] + var pool_pct = Math.floor( ( pool_current / pool_size ) * 100 ); + + var statuscolor = '#78a830'; + if ( pool_pct < 50 ) { statuscolor = '#f0a800'; } + if ( pool_pct < 25 ) { statuscolor = '#d84830'; } + + stats_vcloud_pool__svg[ pool ] = d3.select( '#stats-vcloud-pool' ) + .append( 'svg' ) + .style( 'margin', '15 25 0 0' ) + .style( 'padding', '0 0 20 0' ) + .attr( 'width', pool_width ) + .attr( 'height', pool_height ); + + stats_vcloud_pool__svg[ pool ] + .append( 'g' ) + .attr( 'class', 'x tick' ) + .attr( 'transform', 'translate( 0,' + pool_height + ')' ) + .call( + d3.svg.axis() + .scale( x ) + .ticks( 4 ) + .tickSize( -pool_height ) + .outerTickSize( 0 ) + .tickFormat( '' ) + .tickSubdivide( true ) + .orient( 'bottom' ) + ); + + stats_vcloud_pool__svg[ pool ] + .append( 'text' ) + .text( + ( pool ) + ) + .attr( { + 'x': '5', + 'y': pool_height + 15, + 'font-face': 'PT Sans sans-serif', + 'font-weight': 'bold', + 'font-size': '12px', + 'fill': '#888' + } ); + + stats_vcloud_pool__svg[ pool ] + .append( 'text' ) + .text( + ( pool_pct + '%' ) + ) + .attr( { + 'x': '5', + 'y': pool_height - 5, + 'font-face': 'PT Sans sans-serif', + 'font-weight': 'bold', + 'font-size': '12px', + 'letter-spacing': '-0.05em', + 'fill': '#888' + } ); + + stats_vcloud_pool__svg[ pool ] + .append( 'text' ) + .text( + ( '( ' ) + + ( pool_current ) + + ( '/' ) + + ( pool_size ) + + ( ' )' ) + ) + .attr( { + 'x': 40, + 'y': pool_height - 5, + 'font-face': 'PT Sans sans-serif', + 'font-size': '12px', + 'letter-spacing': '-0.05em', + 'fill': '#888' + } ); + + stats_vcloud_pool__svg[ pool ] + .append( 'path' ) + .attr( 'class', 'area' ) + .attr( 'fill', statuscolor ) + .attr( 'opacity', '0.25' ) + .attr( 'd', area( stats_vcloud_pool__data[ pool ][ 'r' ] ) ); + + stats_vcloud_pool__svg[ pool ] + .append( 'path' ) + .attr( 'class', 'line' ) + .attr( 'stroke', statuscolor ) + .attr( 'stroke-width', '1' ) + .attr( 'd', path( stats_vcloud_pool__data[ pool ][ 'r' ] ) ); + + if ( stats_vcloud_pool__data[ pool ][ 'r' ].length > 500 ) { + stats_vcloud_pool__data[ pool ][ 'r' ].shift(); + } + } + ) + + tick(); + }, 5000 ); + } )(); + + } + +); + diff --git a/views/dashboard.erb b/views/dashboard.erb new file mode 100644 index 0000000..8d8b58b --- /dev/null +++ b/views/dashboard.erb @@ -0,0 +1,21 @@ + + +
the numbers
+ +
+
Loading data... +
+ + + +
+ + + +
vCloud pool status
+ +
+
Loading data... +
+ + diff --git a/views/layout.erb b/views/layout.erb new file mode 100644 index 0000000..9bfe15f --- /dev/null +++ b/views/layout.erb @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + +
+ + + +<%= yield %> + +
+ + + + From b26410464383c3f254d776c572e6e7e78699d5a7 Mon Sep 17 00:00:00 2001 From: Scott Schneider Date: Thu, 12 Dec 2013 11:22:52 -0800 Subject: [PATCH 3/6] Pool stats should still work without graphite --- vmware-host-pooler-api | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/vmware-host-pooler-api b/vmware-host-pooler-api index de9cda2..200f84b 100755 --- a/vmware-host-pooler-api +++ b/vmware-host-pooler-api @@ -59,28 +59,35 @@ get '/dashboard/stats/vcloud/pool' do end if ( params[:history] ) - history ||= Hash.new + if ( config[:config]['graphite'] ) + history ||= Hash.new - buffer = open( 'http://'+config[:config]['graphite']+'/render?target=vcloud.ready.*&from=-1hour&format=json' ).read - history = JSON.parse( buffer ) + buffer = open( 'http://'+config[:config]['graphite']+'/render?target=vcloud.ready.*&from=-1hour&format=json' ).read + history = JSON.parse( buffer ) - history.each do |pool| - if pool['target'] =~ /.*\.(.*)$/ - pool['name'] = $1 - pool['last'] = result[pool['name']]['size'] - result[pool['name']]['history'] ||= Array.new + history.each do |pool| + if pool['target'] =~ /.*\.(.*)$/ + pool['name'] = $1 + pool['last'] = result[pool['name']]['size'] + result[pool['name']]['history'] ||= Array.new - pool['datapoints'].each do |metric| - 8.times do |n| - if ( metric[0] ) - pool['last'] = metric[0].to_i - result[pool['name']]['history'].push( metric[0].to_i ) - else - result[pool['name']]['history'].push( pool['last'] ) + pool['datapoints'].each do |metric| + 8.times do |n| + if ( metric[0] ) + pool['last'] = metric[0].to_i + result[pool['name']]['history'].push( metric[0].to_i ) + else + result[pool['name']]['history'].push( pool['last'] ) + end end end end end + else + config[:pools].each do |pool| + result[pool['name']] ||= Hash.new + result[pool['name']]['history'] = [ $redis.scard( 'vmware_host_pool__ready__' + pool['name'] ) ] + end end end From 607fa53a2701dbf5d69eaac693d725f86c1cd99f Mon Sep 17 00:00:00 2001 From: Scott Schneider Date: Fri, 13 Dec 2013 16:31:35 -0800 Subject: [PATCH 4/6] Fixups for Firefox --- public/dashboard.css | 7 ++-- public/lib/stats-vcloud-numbers.js | 58 +++++++++++++++--------------- public/lib/stats-vcloud-pool.js | 22 ++++++------ 3 files changed, 43 insertions(+), 44 deletions(-) diff --git a/public/dashboard.css b/public/dashboard.css index 7cea080..7983918 100644 --- a/public/dashboard.css +++ b/public/dashboard.css @@ -22,8 +22,7 @@ body, float: right; position: relative; right: 30px; - top: 100px; - font: 50px 'PT Sans' sans-serif; + font: 50px 'PT Sans', sans-serif; letter-spacing: -0.05em; color: #444; } @@ -31,7 +30,7 @@ body, .label { text-transform: uppercase; text-indent: 25px; - font: 12px 'PT Sans' sans-serif; + font: 12px 'PT Sans', sans-serif; font-weight: bold; line-height: 20px; color: #888; @@ -112,7 +111,7 @@ body, .module { margin-top: 5px; margin-left: 25px; - font: 13px 'PT Sans' sans-serif; + font: 13px 'PT Sans', sans-serif; line-height: 20px; color: #888; } diff --git a/public/lib/stats-vcloud-numbers.js b/public/lib/stats-vcloud-numbers.js index c08d390..d308a56 100644 --- a/public/lib/stats-vcloud-numbers.js +++ b/public/lib/stats-vcloud-numbers.js @@ -1,6 +1,6 @@ var numbers_url = '/dashboard/stats/vcloud/numbers'; var numbers_width = 130; -var numbers_height = 45; +var numbers_height = 50; var stats_vcloud_numbers__data = {}; var stats_vcloud_numbers__svg = {}; @@ -31,10 +31,10 @@ d3.json( numbers_url, stats_vcloud_numbers__svg[ 'ready' ] = d3.select( '#stats-vcloud-numbers' ) .append( 'svg' ) - .style( 'margin', '10 25 0 0' ) - .style( 'padding', '0 0 20 0' ) - .attr( 'width', numbers_width ) - .attr( 'height', numbers_height ); + .style( 'margin', '10px 25px 0px 0px' ) + .style( 'padding', '0px 0px 20px 0px' ) + .attr( 'width', numbers_width + 'px' ) + .attr( 'height', numbers_height + 'px' ); stats_vcloud_numbers__svg[ 'ready' ] .append( 'text' ) @@ -43,8 +43,8 @@ d3.json( numbers_url, ) .attr( { 'x': '5', - 'y': numbers_height + 6, - 'font-face': 'PT Sans sans-serif', + 'y': numbers_height, + 'font-face': '\'PT Sans\', sans-serif', 'font-size': '12px', 'font-weight': 'bold', 'fill': '#888' @@ -58,7 +58,7 @@ d3.json( numbers_url, .attr( { 'x': '0', 'y': '36', - 'font-face': 'PT Sans sans-serif', + 'font-face': '\'PT Sans\', sans-serif', 'font-weight': 'bold', 'font-size': '50px', 'letter-spacing': '-0.05em', @@ -67,10 +67,10 @@ d3.json( numbers_url, stats_vcloud_numbers__svg[ 'pending' ] = d3.select( '#stats-vcloud-numbers' ) .append( 'svg' ) - .style( 'margin', '10 25 0 0' ) - .style( 'padding', '0 0 20 0' ) - .attr( 'width', numbers_width ) - .attr( 'height', numbers_height ); + .style( 'margin', '10px 25px 0px 0px' ) + .style( 'padding', '0px 0px 20px 0px' ) + .attr( 'width', numbers_width + 'px' ) + .attr( 'height', numbers_height + 'px' ); stats_vcloud_numbers__svg[ 'pending' ] .append( 'text' ) @@ -79,8 +79,8 @@ d3.json( numbers_url, ) .attr( { 'x': '5', - 'y': numbers_height + 6, - 'font-face': 'PT Sans sans-serif', + 'y': numbers_height, + 'font-face': '\'PT Sans\', sans-serif', 'font-size': '12px', 'font-weight': 'bold', 'fill': '#888' @@ -94,7 +94,7 @@ d3.json( numbers_url, .attr( { 'x': '0', 'y': '36', - 'font-face': 'PT Sans sans-serif', + 'font-face': '\'PT Sans\', sans-serif', 'font-weight': 'bold', 'font-size': '50px', 'letter-spacing': '-0.05em', @@ -103,10 +103,10 @@ d3.json( numbers_url, stats_vcloud_numbers__svg[ 'running' ] = d3.select( '#stats-vcloud-numbers' ) .append( 'svg' ) - .style( 'margin', '10 25 0 0' ) - .style( 'padding', '0 0 20 0' ) - .attr( 'width', numbers_width ) - .attr( 'height', numbers_height ); + .style( 'margin', '10px 25px 0px 0px' ) + .style( 'padding', '0px 0px 20px 0px' ) + .attr( 'width', numbers_width + 'px' ) + .attr( 'height', numbers_height + 'px' ); stats_vcloud_numbers__svg[ 'running' ] .append( 'text' ) @@ -115,8 +115,8 @@ d3.json( numbers_url, ) .attr( { 'x': '5', - 'y': numbers_height + 6, - 'font-face': 'PT Sans sans-serif', + 'y': numbers_height, + 'font-face': '\'PT Sans\', sans-serif', 'font-size': '12px', 'font-weight': 'bold', 'fill': '#888' @@ -130,7 +130,7 @@ d3.json( numbers_url, .attr( { 'x': '0', 'y': '36', - 'font-face': 'PT Sans sans-serif', + 'font-face': '\'PT Sans\', sans-serif', 'font-weight': 'bold', 'font-size': '50px', 'letter-spacing': '-0.05em', @@ -139,10 +139,10 @@ d3.json( numbers_url, stats_vcloud_numbers__svg[ 'completed' ] = d3.select( '#stats-vcloud-numbers' ) .append( 'svg' ) - .style( 'margin', '10 25 0 0' ) - .style( 'padding', '0 0 20 0' ) - .attr( 'width', numbers_width ) - .attr( 'height', numbers_height ); + .style( 'margin', '10px 25px 0px 0px' ) + .style( 'padding', '0px 0px 20px 0px' ) + .attr( 'width', numbers_width + 'px' ) + .attr( 'height', numbers_height + 'px' ); stats_vcloud_numbers__svg[ 'completed' ] .append( 'text' ) @@ -151,8 +151,8 @@ d3.json( numbers_url, ) .attr( { 'x': '5', - 'y': numbers_height + 6, - 'font-face': 'PT Sans sans-serif', + 'y': numbers_height, + 'font-face': '\'PT Sans\', sans-serif', 'font-size': '12px', 'font-weight': 'bold', 'fill': '#888' @@ -166,7 +166,7 @@ d3.json( numbers_url, .attr( { 'x': '0', 'y': '36', - 'font-face': 'PT Sans sans-serif', + 'font-face': '\'PT Sans\', sans-serif', 'font-weight': 'bold', 'font-size': '50px', 'letter-spacing': '-0.05em', diff --git a/public/lib/stats-vcloud-pool.js b/public/lib/stats-vcloud-pool.js index 077cda1..fb7a2d6 100644 --- a/public/lib/stats-vcloud-pool.js +++ b/public/lib/stats-vcloud-pool.js @@ -1,6 +1,6 @@ var pool_url = '/dashboard/stats/vcloud/pool'; var pool_width = 130; -var pool_height = 70; +var pool_height = 85; var stats_vcloud_pool__data = {}; var stats_vcloud_pool__svg = {}; @@ -49,7 +49,7 @@ d3.json( pool_url+'?history=1', var area = d3.svg.area() .interpolate( 'basis' ) .x( function( d, i ) { return x( i ); } ) - .y0( pool_height ) + .y0( pool_height - 15 ) .y1( function( d ) { return y( d ); } ); var path = d3.svg.line() @@ -69,15 +69,15 @@ d3.json( pool_url+'?history=1', stats_vcloud_pool__svg[ pool ] = d3.select( '#stats-vcloud-pool' ) .append( 'svg' ) - .style( 'margin', '15 25 0 0' ) - .style( 'padding', '0 0 20 0' ) + .style( 'margin', '15px 25px 0px 0px' ) + .style( 'padding', '0px 0px 20px 0px' ) .attr( 'width', pool_width ) .attr( 'height', pool_height ); stats_vcloud_pool__svg[ pool ] .append( 'g' ) .attr( 'class', 'x tick' ) - .attr( 'transform', 'translate( 0,' + pool_height + ')' ) + .attr( 'transform', 'translate( 0,' + ( pool_height - 15 ) + ')' ) .call( d3.svg.axis() .scale( x ) @@ -96,8 +96,8 @@ d3.json( pool_url+'?history=1', ) .attr( { 'x': '5', - 'y': pool_height + 15, - 'font-face': 'PT Sans sans-serif', + 'y': pool_height - 2, + 'font-face': '\'PT Sans\', sans-serif', 'font-weight': 'bold', 'font-size': '12px', 'fill': '#888' @@ -110,8 +110,8 @@ d3.json( pool_url+'?history=1', ) .attr( { 'x': '5', - 'y': pool_height - 5, - 'font-face': 'PT Sans sans-serif', + 'y': pool_height - 20, + 'font-face': '\'PT Sans\', sans-serif', 'font-weight': 'bold', 'font-size': '12px', 'letter-spacing': '-0.05em', @@ -129,8 +129,8 @@ d3.json( pool_url+'?history=1', ) .attr( { 'x': 40, - 'y': pool_height - 5, - 'font-face': 'PT Sans sans-serif', + 'y': pool_height - 20, + 'font-face': '\'PT Sans\', sans-serif', 'font-size': '12px', 'letter-spacing': '-0.05em', 'fill': '#888' From ac3e9f960209f3d98e335dfa1ec909ffd1eeb3de Mon Sep 17 00:00:00 2001 From: Scott Schneider Date: Tue, 17 Dec 2013 10:44:50 -0800 Subject: [PATCH 5/6] Fix graph's y range --- public/lib/stats-vcloud-pool.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/lib/stats-vcloud-pool.js b/public/lib/stats-vcloud-pool.js index fb7a2d6..d5c47cb 100644 --- a/public/lib/stats-vcloud-pool.js +++ b/public/lib/stats-vcloud-pool.js @@ -44,7 +44,7 @@ d3.json( pool_url+'?history=1', stats_vcloud_pool__data__keys.sort().map( function( pool ) { var x = d3.scale.linear().domain( [ 0, 500 ] ).range( [ 0, pool_width ] ); - var y = d3.scale.linear().domain( [ parseInt( stats_vcloud_pool__data__live[ pool ][ 'size' ] ), 0 ] ).range( [ 0, pool_height ] ); + var y = d3.scale.linear().domain( [ parseInt( stats_vcloud_pool__data__live[ pool ][ 'size' ] ), 0 ] ).range( [ 0, pool_height - 15 ] ); var area = d3.svg.area() .interpolate( 'basis' ) From 0720c8bb91f8db337bd5495786c2a09fd09a83eb Mon Sep 17 00:00:00 2001 From: Scott Schneider Date: Wed, 18 Dec 2013 11:05:28 -0800 Subject: [PATCH 6/6] Align text --- public/dashboard.css | 1 + 1 file changed, 1 insertion(+) diff --git a/public/dashboard.css b/public/dashboard.css index 7983918..12fc3fc 100644 --- a/public/dashboard.css +++ b/public/dashboard.css @@ -22,6 +22,7 @@ body, float: right; position: relative; right: 30px; + top: 100px; font: 50px 'PT Sans', sans-serif; letter-spacing: -0.05em; color: #444;