diff --git a/app/assets/images/content/latency_gauge_back.png b/app/assets/images/content/latency_gauge_back.png new file mode 100644 index 000000000..2a615bd31 Binary files /dev/null and b/app/assets/images/content/latency_gauge_back.png differ diff --git a/app/assets/images/content/latency_gauge_needle.png b/app/assets/images/content/latency_gauge_needle.png new file mode 100644 index 000000000..df076e4f7 Binary files /dev/null and b/app/assets/images/content/latency_gauge_needle.png differ diff --git a/app/assets/javascripts/fakeJamClient.js b/app/assets/javascripts/fakeJamClient.js index 87da8e17b..febd15733 100644 --- a/app/assets/javascripts/fakeJamClient.js +++ b/app/assets/javascripts/fakeJamClient.js @@ -115,8 +115,8 @@ } function FTUEStartLatency() { function cb() { - // Change 10 to modify latency MS results - eval(latencyCallback + "(10)"); + // Change 4192 to modify latency MS results (in microseconds) + eval(latencyCallback + "(4192)"); } context.setTimeout(cb, 1000); } diff --git a/app/assets/javascripts/ftue.js b/app/assets/javascripts/ftue.js index c5dedebe0..052f49dac 100644 --- a/app/assets/javascripts/ftue.js +++ b/app/assets/javascripts/ftue.js @@ -90,11 +90,6 @@ function updateGauge() { var latencyMS = context.JK.FtueWizard.latencyMS; logger.debug("Latency Value: " + latencyMS); - // TODO - update the gauge visually, and the message according to - // returned value. - // IF gauge is in green (<= 10ms), hide the help/run test again buttons - // IF gauge is in yellow (> 10ms, <= 20ms), keep help/run test again. - // IF gauge is in red (>20ms, switch to fail text) if (latencyMS > 20) { $('#ftue-latency-congrats').hide(); $('#ftue-latency-fail').show(); @@ -106,10 +101,66 @@ $('[layout-wizard-step="6"] .btnHelp').hide(); $('[layout-wizard-step="6"] .btnRepeat').hide(); } - // TODO - update the gauge + setNeedleValue(latencyMS); } } + // Function to calculate an absolute value and an absolute value range into + // a number of degrees on a circualar "speedometer" gauge. The 0 degrees value + // points straight up to the middle of the real-world value range. + // Arguments: + // value: The real-world value (e.g. 20 milliseconds) + // minValue: The real-world minimum value (e.g. 0 milliseconds) + // maxValue: The real-world maximum value (e.g. 40 milliseconds) + // degreesUsed: The number of degrees used to represent the full real-world + // range. 360 would be the entire circle. 270 would be 3/4ths + // of the circle. The unused gap will be at the bottom of the + // gauge. + // (e.g. 300) + function degreesFromRange(value, minValue, maxValue, degreesUsed) { + if (value > maxValue) { value = maxValue; } + if (value < minValue) { value = minValue; } + var range = maxValue-minValue; + var floatVal = value/range; + var degrees = Math.round(floatVal * degreesUsed); + degrees -= Math.round(degreesUsed/2); + if (degrees < 0) { + degrees += 360; + } + return degrees; + } + + // Given a number of MS, and assuming the gauge has a range from + // 0 to 40 ms. Update the gauge to the proper value. + function setNeedleValue(ms) { + var deg = degreesFromRange(ms, 0, 40, 300); + + // Supporting Firefix, Chrome, Safari, Opera and IE9+. + // Should we need to support < IE9, this will need more work + // to compute the matrix transformations in those browsers - + // and I don't believe they support transparent PNG graphic + // rotation, so we'll have to change the needle itself. + var css = { + //"behavior":"url(-ms-transform.htc)", + /* Firefox */ + "-moz-transform":"rotate(" + deg + "deg)", + /* Safari and Chrome */ + "-webkit-transform":"rotate(" + deg + "deg)", + /* Opera */ + "-o-transform":"rotate(" + deg + "deg)", + /* IE9 */ + "-ms-transform":"rotate(" + deg + "deg)" + /* IE6,IE7 */ + //"filter": "progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', M11=0.7071067811865476, M12=-0.7071067811865475, M21=0.7071067811865475, M22=0.7071067811865476)", + /* IE8 */ + //"-ms-filter": '"progid:DXImageTransform.Microsoft.Matrix(SizingMethod=\'auto expand\', M11=0.7071067811865476, M12=-0.7071067811865475, M21=0.7071067811865475, M22=0.7071067811865476)"' + }; + + $('#ftue-latency-numerical').html(ms); + $('#ftue-latency-needle').css(css); + + } + function testLatency() { // we'll just register for call back right here and unregister in the callback. context.JK.FtueWizard.latencyTimeout = true; @@ -285,9 +336,14 @@ // Expose publics this.initialize = initialize; + // Expose degreesFromRange outside for testing + this._degreesFromRange = degreesFromRange; + return this; }; + + // Common VU updater taking a dbValue (-80 to 20) and a CSS selector for the VU. context.JK.ftueVUCallback = function(dbValue, selector) { // Convert DB into a value from 0.0 - 1.0 diff --git a/app/assets/stylesheets/client/ftue.css.scss b/app/assets/stylesheets/client/ftue.css.scss index 2a2635e5f..46a4d216f 100644 --- a/app/assets/stylesheets/client/ftue.css.scss +++ b/app/assets/stylesheets/client/ftue.css.scss @@ -4,6 +4,38 @@ @charset "UTF-8"; /* Jonathon's FTUE overrides */ +#ftue-latency-needle { + position:absolute; + width: 6px; + height: 220px; + top:50%; + left:50%; + overflow:visible; + margin: -106px -3px 0px 0px; + padding: 0px 0px 0px 0px; +} +#ftue-latency-numerical { + position:absolute; + width: 150px; + height: 32px; + top: 228px; + left: 50%; + margin: -73px; + text-align:center; + font-size: 1.8em; + font-weight: bold; +} +#ftue-latency-label { + position:absolute; + width: 150px; + height: 32px; + top: 250px; + left: 50%; + margin: -73px; + text-align:center; + font-size: 0.9em; +} + div.dialog.ftue { min-width: 800px; max-width: 800px; diff --git a/app/views/clients/_ftue.html.erb b/app/views/clients/_ftue.html.erb index 75fde0d81..f75fedf9a 100644 --- a/app/views/clients/_ftue.html.erb +++ b/app/views/clients/_ftue.html.erb @@ -213,15 +213,21 @@