Skip to content

Commit 8c610b4

Browse files
authored
Merge pull request #100 from Pradhyumna02/move-download-calculations-client
[US1114284] Move download calculations to client
2 parents 68e58f1 + f807ce8 commit 8c610b4

File tree

6 files changed

+168
-43
lines changed

6 files changed

+168
-43
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "speed-testjs",
3-
"version": "1.0.25",
3+
"version": "1.0.26",
44
"description": "measure internet bandwidth",
55
"main": "index.js",
66
"author": "Maulan Byron",

public/examples/download/downloadApp.js

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242
var urls = [];
4343
var ports = [5020, 5021, 5022, 5023, 5024, 5025];
4444
var monitorInterval = 100;
45+
var sliceStartValue = 0.3;
46+
var sliceEndValue = 0.9;
4547

4648
function initTest() {
4749
function addEvent(el, ev, fn) {
@@ -226,28 +228,9 @@
226228
updateValue([currentTest, '-', version].join(''), finalValue);
227229
}
228230

229-
function calculateStatsonError(result) {
230-
//set test value to 0
231-
option.series[0].data[0].value = 0;
232-
//updat test status to complete
233-
option.series[0].data[0].name = 'Test Failed';
234-
//set accessiblity aria-disabled state.
235-
//This will also effect the visual look by corresponding css
236-
startTestButton.setAttribute('aria-disabled', false);
237-
//update button text to communicate current state of test as In Progress
238-
startTestButton.innerHTML = 'Start Test';
239-
//enable start button
240-
startTestButton.disabled = false;
241-
//hide current test value in chart
242-
option.series[0].detail.show = false;
243-
//update gauge
244-
myChart.setOption(option, true);
245-
}
246-
247231
function downloadHttpOnComplete(result) {
248-
249-
var calculateMeanStats = new window.calculateStats('http://' + testPlan.baseUrlIPv4 + '/calculator', result, calculateStatsonComplete, calculateStatsonError);
250-
calculateMeanStats.performCalculations();
232+
var calculateMeanStats = new window.statisticalCalculator(result, false, sliceStartValue, sliceEndValue, calculateStatsonComplete);
233+
calculateMeanStats.getResults();
251234
}
252235

253236
function downloadHttpOnProgress(result) {

public/examples/download/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ <h1 class="logo"></h1>
6060
<script src="lib/downloadHttpConcurrentProgress.js"></script>
6161
<script src="lib/downloadProbeTest.js"></script>
6262
<script src="uilib/echarts.min.js"></script>
63-
63+
<script src="lib/statisticalCalculator.js"></script>
6464
<script src="examples/download/downloadApp.js"></script>
6565
</body>
6666

public/index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ <h1 class="logo"></h1>
8383
<script src="lib/uploadHttpConcurrent.js"></script>
8484
<script src="lib/uploadProbeTest.js"></script>
8585
<script src="lib/uploadHttpConcurrentProgress.js"></script>
86+
<script src="lib/statisticalCalculator.js"></script>
8687
<script src="uilib/echarts.min.js"></script>
8788
<script src="speed-testJS.js"></script>
8889
</body>
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/*
2+
* *
3+
* Copyright 2014 Comcast Cable Communications Management, LLC
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
* /
17+
*/
18+
19+
(function () {
20+
'use strict';
21+
22+
/**
23+
* Performs statistical calculations.
24+
* @param data - array of values used for computation.
25+
* @param iqrFilter - boolean to either perform iqrFiltering or slicing.
26+
* @param start - slicing start value
27+
* @param end - slicing end value.
28+
* @param callbackComplete - callback function for test suite for complete event.
29+
*/
30+
function statisticalCalculator(data, iqrFilter, start, end, callbackComplete) {
31+
this.data = data;
32+
this.isIqrFilter = iqrFilter;
33+
//start is the value used for slicing the slowest data with given percentage.
34+
this.start = start;
35+
//end is the value used for slicing the fastest data with given percentage.
36+
this.end = end;
37+
this.clientCallbackComplete = callbackComplete;
38+
}
39+
40+
/**
41+
* This function is used to do the calculations either with IQRFiltering or go with Slicing
42+
*/
43+
statisticalCalculator.prototype.getResults = function () {
44+
this.data = this.data.sort(this.numericComparator);
45+
var dataset = (this.isIqrFilter) ? this.interQuartileRange(data) : this.slicing(this.data, this.start, this.end);
46+
var peakValue = dataset[dataset.length - 1];
47+
var mean = this.meanCalculator(dataset);
48+
49+
var results = {
50+
stats: mean,
51+
peakValue: peakValue
52+
};
53+
this.clientCallbackComplete(results);
54+
};
55+
56+
/**
57+
* Calculate the interquartile range of an array of data points
58+
*
59+
* https://en.wikipedia.org/wiki/Interquartile_range
60+
* In descriptive statistics, the interquartile range (IQR), also called
61+
* the midspread or middle fifty, or technically H-spread, is a measure of
62+
* statistical dispersion, being equal to the difference between the upper and
63+
* lower quartiles,[1][2] IQR = Q3 − Q1. In other words, the IQR is the 1st quartile subtracted from the 3rd quartile
64+
* The interquartile range is often used to find outliers in data. Outliers are observations
65+
* that fall below Q1 - 1.5(IQR) or above Q3 + 1.5(IQR)
66+
*/
67+
statisticalCalculator.prototype.interQuartileRange = function (a) {
68+
var length = a.length,
69+
dataSetWithOutliersRemoved = [],
70+
isEven = (a.length) % 2,
71+
iqr,
72+
i,
73+
fQMedian,
74+
tQMedian,
75+
n;
76+
77+
if (isEven === 0) {
78+
n = a.length;
79+
fQMedian = this.medianCalculator(a.slice(0, (a.length) / 2));
80+
tQMedian = this.medianCalculator(a.slice((a.length) / 2, n));
81+
iqr = tQMedian - fQMedian;
82+
83+
} else {
84+
n = a.length - 1;
85+
a.splice((n / 2), 1);
86+
87+
fQMedian = this.medianCalculator(a.slice(0, (a.length) / 2));
88+
tQMedian = this.medianCalculator(a.slice(((a.length) / 2) + 1, n + 1));
89+
iqr = tQMedian - fQMedian;
90+
}
91+
var lowerOutliers = fQMedian - (1.5 * iqr);
92+
var upperOutliers = tQMedian + (1.5 * iqr);
93+
94+
for (i = 0; i < length; i++) {
95+
96+
if (a[i] > lowerOutliers && a[i] < upperOutliers) {
97+
dataSetWithOutliersRemoved.push(a[i]);
98+
}
99+
}
100+
101+
return dataSetWithOutliersRemoved;
102+
};
103+
104+
/**
105+
* Simple JavaScript comparator to help with sorting.
106+
* @param a
107+
* @param b
108+
* @returns {number}
109+
* @constructor
110+
*/
111+
statisticalCalculator.prototype.numericComparator = function (a, b) {
112+
return (a - b);
113+
};
114+
115+
/**
116+
* Calculates the Median.
117+
* @param a
118+
* @returns {number}
119+
*/
120+
statisticalCalculator.prototype.medianCalculator = function (a) {
121+
var n = a.length - 1;
122+
var median = ((a[Math.floor(n / 2)] + a[Math.ceil(n / 2)]) / 2);
123+
return median;
124+
};
125+
126+
/**
127+
* Calculates the sum and mean of an array
128+
* @param arr
129+
* @returns {{sum: *, mean: number}}
130+
*/
131+
statisticalCalculator.prototype.meanCalculator = function (arr) {
132+
var sum = arr.reduce(function (a, b) {
133+
return a + b;
134+
}, 0);
135+
var mean = sum / arr.length;
136+
return {
137+
sum: sum,
138+
mean: mean
139+
};
140+
};
141+
142+
/**
143+
* Function takes in array slices the top 30% and bottom 10% of data
144+
* @param a
145+
* @returns {*}
146+
*/
147+
statisticalCalculator.prototype.slicing = function (a, start, end) {
148+
var dataLength = a.length;
149+
var start = Math.round(dataLength * start);
150+
var end = Math.round(dataLength * end);
151+
var sliceData = a.slice(start, end);
152+
return sliceData;
153+
};
154+
155+
window.statisticalCalculator = statisticalCalculator;
156+
157+
})();

public/speed-testJS.js

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@
5252
var uploadUrls = [];
5353
var uploadMonitorInterval = 200;
5454
var isMicrosoftBrowser = false;
55+
var sliceStartValue = 0.3;
56+
var sliceEndValue = 0.9;
5557

5658
function initTest() {
5759
function addEvent(el, ev, fn) {
@@ -368,28 +370,10 @@
368370
updateValue([currentTest, '-', version].join(''), finalValue);
369371
}
370372

371-
function calculateStatsonError(result) {
372-
//set test value to 0
373-
option.series[0].data[0].value = 0;
374-
//updat test status to complete
375-
option.series[0].data[0].name = 'Test Failed';
376-
//set accessiblity aria-disabled state.
377-
//This will also effect the visual look by corresponding css
378-
startTestButton.setAttribute('aria-disabled', false);
379-
//update button text to communicate current state of test as In Progress
380-
startTestButton.innerHTML = 'Start Test';
381-
//enable start button
382-
startTestButton.disabled = false;
383-
//hide current test value in chart
384-
option.series[0].detail.show = false;
385-
//update gauge
386-
myChart.setOption(option, true);
387-
}
388-
389373
function downloadHttpOnComplete(result) {
390374

391-
var calculateMeanStats = new window.calculateStats('http://' + testPlan.baseUrlIPv4 + '/calculator', result, calculateStatsonComplete, calculateStatsonError);
392-
calculateMeanStats.performCalculations();
375+
var calculateMeanStats = new window.statisticalCalculator(result, false, sliceStartValue, sliceEndValue, calculateStatsonComplete);
376+
calculateMeanStats.getResults();
393377
}
394378

395379
function downloadHttpOnProgress(result) {

0 commit comments

Comments
 (0)