1var OUTLIER_THRESHOLD = 0.05; 2var MARGIN_SIZE = 0.10; 3 4Heatmap.prototype.calculate = function(data) { 5 this.cleanUpData(data); 6 this.calculateBounds(); 7 this.calculateHeatmap(); 8 9 this.drawTraces = []; 10 for (var i = 0; i < data.length; ++i) 11 this.drawTraces.push(false); 12}; 13 14Heatmap.prototype.cleanUpData = function(data) { 15 // Data, indexed by revision and trace. 16 this.traces = {}; 17 18 for (var bot in data) { 19 var bot_data = data[bot]; 20 for (var run_index = 0; run_index < bot_data.length; ++run_index) { 21 var run_data = bot_data[run_index]; 22 if (run_data == null) 23 continue 24 var stories_data = run_data['user_story_runs']; 25 for (var story_index = 0; story_index < stories_data.length; ++story_index) { 26 var story_data = stories_data[story_index]; 27 var story_name = story_data['user_story']; 28 if (story_name == 'summary') 29 continue 30 31 values = story_data['values']; 32 33 var index = bot_data.length - run_index - 1; 34 if (!this.traces[index]) 35 this.traces[index] = {}; 36 this.traces[index][story_index] = values; 37 } 38 } 39 } 40 41 this.revisions = Object.keys(this.traces).sort(); 42}; 43 44Heatmap.prototype.calculateBounds = function() { 45 var values = []; 46 for (var revision in this.traces) 47 for (var trace in this.traces[revision]) 48 for (var value of this.traces[revision][trace]) 49 values.push(value); 50 51 // Exclude OUTLIER_THRESHOLD% of the points. 52 values.sort(function(a, b) {return a - b}); 53 this.min = percentile(values, OUTLIER_THRESHOLD / 2); 54 this.max = percentile(values, -OUTLIER_THRESHOLD / 2); 55 56 // Ease bounds by adding margins. 57 var margin = (this.max - this.min) * MARGIN_SIZE; 58 this.min -= margin; 59 this.max += margin; 60}; 61 62Heatmap.prototype.calculateHeatmap = function() { 63 this.data = {}; 64 for (var revision in this.traces) { 65 for (var trace in this.traces[revision]) { 66 for (var value of this.traces[revision][trace]) { 67 var bucket = this.findBucket(value); 68 69 if (this.data[revision] == null) 70 this.data[revision] = {}; 71 if (this.data[revision][bucket] == null) 72 this.data[revision][bucket] = []; 73 this.data[revision][bucket].push(trace); 74 } 75 } 76 } 77}; 78 79Heatmap.prototype.findBucket = function(value) { 80 var bucket = Math.floor(mapRange(value, this.min, this.max, 0, this.resolution)); 81 return constrain(bucket, 0, this.resolution - 1); 82}; 83