| OLD | NEW |
| 1 /** | 1 /** |
| 2 * Copyright (c) 2014 The Chromium Authors. All rights reserved. | 2 * Copyright (c) 2014 The Chromium Authors. All rights reserved. |
| 3 * Use of this source code is governed by a BSD-style license that can be | 3 * Use of this source code is governed by a BSD-style license that can be |
| 4 * found in the LICENSE file */ | 4 * found in the LICENSE file */ |
| 5 /** Provides the logic behind the performance visualization webpage. */ | 5 /** Provides the logic behind the performance visualization webpage. */ |
| 6 | 6 |
| 7 function assert(cond, msg) { | 7 function assert_(cond, msg) { |
| 8 if(!cond) { | 8 if(!cond) { |
| 9 throw msg || "Assertion failed"; | 9 throw msg || "Assertion failed"; |
| 10 } | 10 } |
| 11 } | 11 } |
| 12 | 12 |
| 13 | 13 |
| 14 function last(ary) { | 14 function last(ary) { |
| 15 return ary[ary.length - 1]; | 15 return ary[ary.length - 1]; |
| 16 } | 16 } |
| 17 | 17 |
| (...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 /* Unordered data structure with O(1) add, remove, and index.*/ | 155 /* Unordered data structure with O(1) add, remove, and index.*/ |
| 156 // Benchmarked remarkably well against vector.splice()/push() | 156 // Benchmarked remarkably well against vector.splice()/push() |
| 157 function Vector() { | 157 function Vector() { |
| 158 var data = []; | 158 var data = []; |
| 159 var firstEmpty = 0; | 159 var firstEmpty = 0; |
| 160 if(arguments) { | 160 if(arguments) { |
| 161 data = Array.prototype.map.call(arguments, id); | 161 data = Array.prototype.map.call(arguments, id); |
| 162 firstEmpty = data.length; | 162 firstEmpty = data.length; |
| 163 } | 163 } |
| 164 this.get = function(idx) { | 164 this.get = function(idx) { |
| 165 assert(idx < firstEmpty); | 165 assert_(idx < firstEmpty); |
| 166 return data[idx]; | 166 return data[idx]; |
| 167 }, | 167 }, |
| 168 this.push = function(elem) { | 168 this.push = function(elem) { |
| 169 data[firstEmpty] = elem; | 169 data[firstEmpty] = elem; |
| 170 firstEmpty++; | 170 firstEmpty++; |
| 171 }; | 171 }; |
| 172 this.pop = function(idx) { | 172 this.pop = function(idx) { |
| 173 assert(idx < firstEmpty && firstEmpty > 0); | 173 assert_(idx < firstEmpty && firstEmpty > 0); |
| 174 var result = data[idx]; | 174 var result = data[idx]; |
| 175 data[idx] = data[firstEmpty - 1]; | 175 data[idx] = data[firstEmpty - 1]; |
| 176 data[firstEmpty - 1] = null; | 176 data[firstEmpty - 1] = null; |
| 177 firstEmpty--; | 177 firstEmpty--; |
| 178 return result; | 178 return result; |
| 179 }; | 179 }; |
| 180 this.all = function() { | 180 this.all = function() { |
| 181 return data.slice(0, firstEmpty); | 181 return data.slice(0, firstEmpty); |
| 182 }; | 182 }; |
| 183 this.remove = function(elem) { | 183 this.remove = function(elem) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 256 var legend = (function() { | 256 var legend = (function() { |
| 257 var internalLegend = []; | 257 var internalLegend = []; |
| 258 var externalLegend = []; | 258 var externalLegend = []; |
| 259 // Each legend marker has two values, a key and a color | 259 // Each legend marker has two values, a key and a color |
| 260 // The external legend also has a pointer to its DOM element called elem. | 260 // The external legend also has a pointer to its DOM element called elem. |
| 261 var legendBody = null; | 261 var legendBody = null; |
| 262 | 262 |
| 263 function addToDOM(e) { | 263 function addToDOM(e) { |
| 264 console.log('addToDOM called'); | 264 console.log('addToDOM called'); |
| 265 // console.log(e); | 265 // console.log(e); |
| 266 assert(e.key && e.color); | 266 assert_(e.key && e.color); |
| 267 assert(legendBody); | 267 assert_(legendBody); |
| 268 var container = document.createElement('tr'); | 268 var container = document.createElement('tr'); |
| 269 var checkContainer = document.createElement('td'); | 269 var checkContainer = document.createElement('td'); |
| 270 var checkbox = document.createElement('input'); | 270 var checkbox = document.createElement('input'); |
| 271 checkbox.type = 'checkbox'; | 271 checkbox.type = 'checkbox'; |
| 272 checkbox.checked = true; | 272 checkbox.checked = true; |
| 273 checkbox.id = e.key; | 273 checkbox.id = e.key; |
| 274 var outerColor = document.createElement('div'); | 274 var outerColor = document.createElement('div'); |
| 275 outerColor.classList.add('legend-box-outer'); | 275 outerColor.classList.add('legend-box-outer'); |
| 276 var innerColor = document.createElement('div'); | 276 var innerColor = document.createElement('div'); |
| 277 innerColor.classList.add('legend-box-inner'); | 277 innerColor.classList.add('legend-box-inner'); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 291 checkContainer.appendChild(text); | 291 checkContainer.appendChild(text); |
| 292 | 292 |
| 293 linkContainer.appendChild(link); | 293 linkContainer.appendChild(link); |
| 294 outerColor.appendChild(innerColor); | 294 outerColor.appendChild(innerColor); |
| 295 | 295 |
| 296 legendBody.appendChild(container); | 296 legendBody.appendChild(container); |
| 297 return {key: e.key, color: e.color, elem: container}; | 297 return {key: e.key, color: e.color, elem: container}; |
| 298 } | 298 } |
| 299 | 299 |
| 300 function rawAdd(key, color) { | 300 function rawAdd(key, color) { |
| 301 assert(getComponent(internalLegend, 'key').indexOf(key) == -1); | 301 assert_(getComponent(internalLegend, 'key').indexOf(key) == -1); |
| 302 | 302 |
| 303 var newPair = {key:key, color:color}; | 303 var newPair = {key:key, color:color}; |
| 304 internalLegend.push(newPair); | 304 internalLegend.push(newPair); |
| 305 externalLegend.push(addToDOM(newPair)); | 305 externalLegend.push(addToDOM(newPair)); |
| 306 } | 306 } |
| 307 return { | 307 return { |
| 308 /** Updates the colors for the elements.*/ | 308 /** Updates the colors for the elements.*/ |
| 309 updateColors: function(plotRef) { | 309 updateColors: function(plotRef) { |
| 310 var dataRef = plotRef.getData(); | 310 var dataRef = plotRef.getData(); |
| 311 internalLegend.forEach(function(legendMarker) { | 311 internalLegend.forEach(function(legendMarker) { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 335 } | 335 } |
| 336 } | 336 } |
| 337 }); | 337 }); |
| 338 if(synced && color_synced) { | 338 if(synced && color_synced) { |
| 339 console.log('legend.refresh: legends synced'); | 339 console.log('legend.refresh: legends synced'); |
| 340 return; | 340 return; |
| 341 } else if(synced && !color_synced) { | 341 } else if(synced && !color_synced) { |
| 342 console.log('legend.refresh: fixing colors'); | 342 console.log('legend.refresh: fixing colors'); |
| 343 // Fix the colors | 343 // Fix the colors |
| 344 $$('tr', legendBody).forEach(function(e, idx) { | 344 $$('tr', legendBody).forEach(function(e, idx) { |
| 345 assert($$$('input', e).id == internalLegend[idx].key); | 345 assert_($$$('input', e).id == internalLegend[idx].key); |
| 346 | 346 |
| 347 $$$('.legend-box-inner', e).style. | 347 $$$('.legend-box-inner', e).style. |
| 348 border = '5px solid ' + internalLegend[idx].color; | 348 border = '5px solid ' + internalLegend[idx].color; |
| 349 }); | 349 }); |
| 350 } else { | 350 } else { |
| 351 killChildren($$$('#legend table tbody')); | 351 killChildren($$$('#legend table tbody')); |
| 352 externalLegend = []; | 352 externalLegend = []; |
| 353 // Regenerate a new legend | 353 // Regenerate a new legend |
| 354 var _this = this; | 354 var _this = this; |
| 355 internalLegend.forEach(function(e) { | 355 internalLegend.forEach(function(e) { |
| 356 externalLegend.push(addToDOM(e, _this)); | 356 externalLegend.push(addToDOM(e, _this)); |
| 357 }); | 357 }); |
| 358 } | 358 } |
| 359 }, | 359 }, |
| 360 remove: function(key) { | 360 remove: function(key) { |
| 361 var children = []; | 361 var children = []; |
| 362 externalLegend.forEach(function(e, idx) { | 362 externalLegend.forEach(function(e, idx) { |
| 363 if(e.key == key) { | 363 if(e.key == key) { |
| 364 children.push(e.elem); | 364 children.push(e.elem); |
| 365 } | 365 } |
| 366 }); | 366 }); |
| 367 children.forEach(function(c) { | 367 children.forEach(function(c) { |
| 368 assert(c.parentNode); | 368 assert_(c.parentNode); |
| 369 c.parentNode.removeChild(c); | 369 c.parentNode.removeChild(c); |
| 370 }); | 370 }); |
| 371 internalLegend = internalLegend.filter(function(e) { | 371 internalLegend = internalLegend.filter(function(e) { |
| 372 return e.key != key; | 372 return e.key != key; |
| 373 }); | 373 }); |
| 374 externalLegend = externalLegend.filter(function(e) { | 374 externalLegend = externalLegend.filter(function(e) { |
| 375 return e.key != key; | 375 return e.key != key; |
| 376 }); | 376 }); |
| 377 }, | 377 }, |
| 378 /* Sets up the private variables, and a few of the relevant UI controls.*/ | 378 /* Sets up the private variables, and a few of the relevant UI controls.*/ |
| 379 init: function(showHandler, hideHandler, drawHandler) { | 379 init: function(showHandler, hideHandler, drawHandler) { |
| 380 console.log('Initializing legend'); | 380 console.log('Initializing legend'); |
| 381 assert(showHandler && hideHandler); | 381 assert_(showHandler && hideHandler); |
| 382 legendBody = $$$('#legend table tbody'); | 382 legendBody = $$$('#legend table tbody'); |
| 383 var _this = this; | 383 var _this = this; |
| 384 $$$('#nuke-plot').addEventListener('click', function(e) { | 384 $$$('#nuke-plot').addEventListener('click', function(e) { |
| 385 internalLegend.forEach(function(keypair) { | 385 internalLegend.forEach(function(keypair) { |
| 386 plotData.hide(keypair.key); | 386 plotData.hide(keypair.key); |
| 387 }); | 387 }); |
| 388 killChildren($$$('#legend table tbody')); | 388 killChildren($$$('#legend table tbody')); |
| 389 internalLegend = []; | 389 internalLegend = []; |
| 390 externalLegend = []; | 390 externalLegend = []; |
| 391 drawHandler(); | 391 drawHandler(); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 440 var jsonRequest = (function() { | 440 var jsonRequest = (function() { |
| 441 var waitingHandlers = []; | 441 var waitingHandlers = []; |
| 442 var freshFiles = []; | 442 var freshFiles = []; |
| 443 | 443 |
| 444 function makeRequest(uri, callback) { | 444 function makeRequest(uri, callback) { |
| 445 var ref = {uri: uri, callbacks: [callback]}; | 445 var ref = {uri: uri, callbacks: [callback]}; |
| 446 waitingHandlers.push(ref); | 446 waitingHandlers.push(ref); |
| 447 | 447 |
| 448 var removeSelf = function() { | 448 var removeSelf = function() { |
| 449 var idx = waitingHandlers.indexOf(ref); | 449 var idx = waitingHandlers.indexOf(ref); |
| 450 assert(idx != -1); | 450 assert_(idx != -1); |
| 451 waitingHandlers.splice(idx, 1); | 451 waitingHandlers.splice(idx, 1); |
| 452 }; | 452 }; |
| 453 | 453 |
| 454 loadJSON(ref.uri, function(data) { | 454 loadJSON(ref.uri, function(data) { |
| 455 console.log('jsonRequest: ' + ref.uri + ' received'); | 455 console.log('jsonRequest: ' + ref.uri + ' received'); |
| 456 var freshIdx = getComponent(freshFiles, 'uri').indexOf(uri); | 456 var freshIdx = getComponent(freshFiles, 'uri').indexOf(uri); |
| 457 if(freshIdx == -1) { | 457 if(freshIdx == -1) { |
| 458 freshFiles.push({uri: uri, time: Date.now(), data: data}); | 458 freshFiles.push({uri: uri, time: Date.now(), data: data}); |
| 459 } else { | 459 } else { |
| 460 freshFiles[freshIdx].data = data; | 460 freshFiles[freshIdx].data = data; |
| 461 freshFiles[freshIdx].time = Date.now(); | 461 freshFiles[freshIdx].time = Date.now(); |
| 462 } | 462 } |
| 463 ref.callbacks.forEach(function(callback) { | 463 ref.callbacks.forEach(function(callback) { |
| 464 assert(callback); | 464 assert_(callback); |
| 465 callback(data, true); | 465 callback(data, true); |
| 466 }); | 466 }); |
| 467 removeSelf(); | 467 removeSelf(); |
| 468 }, function() { | 468 }, function() { |
| 469 ref.callbacks.forEach(function(callback) { | 469 ref.callbacks.forEach(function(callback) { |
| 470 assert(callback); | 470 assert_(callback); |
| 471 callback(data, false); | 471 callback(data, false); |
| 472 }); | 472 }); |
| 473 removeSelf(); | 473 removeSelf(); |
| 474 }); | 474 }); |
| 475 } | 475 } |
| 476 return { | 476 return { |
| 477 askFor: function(uri, callback) { | 477 askFor: function(uri, callback) { |
| 478 var idx = getComponent(waitingHandlers, 'uri').indexOf(uri); | 478 var idx = getComponent(waitingHandlers, 'uri').indexOf(uri); |
| 479 var freshIdx = getComponent(freshFiles, 'uri').indexOf(uri); | 479 var freshIdx = getComponent(freshFiles, 'uri').indexOf(uri); |
| 480 if(idx != -1) { | 480 if(idx != -1) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 for(var key in data[scale]) { | 546 for(var key in data[scale]) { |
| 547 if(data[scale].hasOwnProperty(key)) { | 547 if(data[scale].hasOwnProperty(key)) { |
| 548 result.push(parseInt(key)); | 548 result.push(parseInt(key)); |
| 549 } | 549 } |
| 550 } | 550 } |
| 551 return result; | 551 return result; |
| 552 } | 552 } |
| 553 | 553 |
| 554 /* Adds a set of data to the trace.*/ | 554 /* Adds a set of data to the trace.*/ |
| 555 this.add = function(newData, tileId, scale) { | 555 this.add = function(newData, tileId, scale) { |
| 556 assert(newData.length > 0); | 556 assert_(newData.length > 0); |
| 557 if(!data[scale]) { | 557 if(!data[scale]) { |
| 558 data[scale] = []; | 558 data[scale] = []; |
| 559 } | 559 } |
| 560 if(!data[scale][tileId] || (newData.length >= data[scale][tileId].length)) { | 560 if(!data[scale][tileId] || (newData.length >= data[scale][tileId].length)) { |
| 561 data[scale][tileId] = newData.slice(); // FUTURE: If too slow, replace wi
th | 561 data[scale][tileId] = newData.slice(); // FUTURE: If too slow, replace wi
th |
| 562 // shallow copy | 562 // shallow copy |
| 563 } | 563 } |
| 564 }; | 564 }; |
| 565 | 565 |
| 566 this.get = function(tileId, scale) { | 566 this.get = function(tileId, scale) { |
| 567 return (data[scale] && data[scale][tileId]) || []; | 567 return (data[scale] && data[scale][tileId]) || []; |
| 568 }; | 568 }; |
| 569 | 569 |
| 570 this.getRange = function(start, end, scale) { | 570 this.getRange = function(start, end, scale) { |
| 571 // FUTURE: Add support for downsampling on scale mismatch | 571 // FUTURE: Add support for downsampling on scale mismatch |
| 572 assert(start <= end); | 572 assert_(start <= end); |
| 573 var results = []; | 573 var results = []; |
| 574 var tiles = data[scale]; | 574 var tiles = data[scale]; |
| 575 getTiles(scale).forEach(function(tileIdx) { | 575 getTiles(scale).forEach(function(tileIdx) { |
| 576 if(tiles[tileIdx][0][0] <= end && last(tiles[tileIdx])[0] >= start) { | 576 if(tiles[tileIdx][0][0] <= end && last(tiles[tileIdx])[0] >= start) { |
| 577 var result = []; | 577 var result = []; |
| 578 var i = 0; | 578 var i = 0; |
| 579 while(tiles[tileIdx][i][0] < start) { | 579 while(tiles[tileIdx][i][0] < start) { |
| 580 assert(i < tiles[tileIdx].length); | 580 assert_(i < tiles[tileIdx].length); |
| 581 i++; | 581 i++; |
| 582 } | 582 } |
| 583 if(i > 0) { | 583 if(i > 0) { |
| 584 // Add one just before the range if possible | 584 // Add one just before the range if possible |
| 585 i--; | 585 i--; |
| 586 } | 586 } |
| 587 while(i < tiles[tileIdx].length && tiles[tileIdx][i][0] <= end) { | 587 while(i < tiles[tileIdx].length && tiles[tileIdx][i][0] <= end) { |
| 588 result.push(tiles[tileIdx][i]); | 588 result.push(tiles[tileIdx][i]); |
| 589 i++; | 589 i++; |
| 590 } | 590 } |
| (...skipping 20 matching lines...) Expand all Loading... |
| 611 | 611 |
| 612 var traceDict = (function() { | 612 var traceDict = (function() { |
| 613 var cache = new PagedDictionary(); | 613 var cache = new PagedDictionary(); |
| 614 // A dictionary of keys to Trace objects | 614 // A dictionary of keys to Trace objects |
| 615 | 615 |
| 616 function loadData(data, tileId, dataset, scale) { | 616 function loadData(data, tileId, dataset, scale) { |
| 617 console.log('traceDict: loadData called. tileId = ' + tileId + | 617 console.log('traceDict: loadData called. tileId = ' + tileId + |
| 618 ', scale = ' + scale); | 618 ', scale = ' + scale); |
| 619 // Look for the key in the data, and store that. If no key specified, store | 619 // Look for the key in the data, and store that. If no key specified, store |
| 620 // as much data as possible. | 620 // as much data as possible. |
| 621 assert(data['traces'] && data['commits']); | 621 assert_(data['traces'] && data['commits']); |
| 622 | 622 |
| 623 var commitAry = getComponent(data['commits'], 'commit_time'); | 623 var commitAry = getComponent(data['commits'], 'commit_time'); |
| 624 data['traces'].forEach(function(trace) { | 624 data['traces'].forEach(function(trace) { |
| 625 var newKey = schema.makeLegendKey(trace); | 625 var newKey = schema.makeLegendKey(trace); |
| 626 var processedData = []; | 626 var processedData = []; |
| 627 for(var i = 0; i < trace['values'].length; i++) { | 627 for(var i = 0; i < trace['values'].length; i++) { |
| 628 if(trace['values'][i] < 1e+99) { | 628 if(trace['values'][i] < 1e+99) { |
| 629 processedData.push([commitAry[i], trace['values'][i]]); | 629 processedData.push([commitAry[i], trace['values'][i]]); |
| 630 } | 630 } |
| 631 } | 631 } |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 if(dataDict.has(scale) && dataDict.get(scale).has(timestamp)) { | 747 if(dataDict.has(scale) && dataDict.get(scale).has(timestamp)) { |
| 748 return dataDict.get(scale).get(timestamp); | 748 return dataDict.get(scale).get(timestamp); |
| 749 } else if(callback) { | 749 } else if(callback) { |
| 750 callbacks.push({lookup: timestamp, scale: scale, callback: callback}); | 750 callbacks.push({lookup: timestamp, scale: scale, callback: callback}); |
| 751 return null; | 751 return null; |
| 752 } | 752 } |
| 753 }, | 753 }, |
| 754 /* Call the callback with the hash for the given timestamp.*/ | 754 /* Call the callback with the hash for the given timestamp.*/ |
| 755 timestampToHash: function(timestamp, scale, callback) { | 755 timestampToHash: function(timestamp, scale, callback) { |
| 756 var res = this.getAssociatedData(timestamp, scale, function(res) { | 756 var res = this.getAssociatedData(timestamp, scale, function(res) { |
| 757 assert(res && res.hash); | 757 assert_(res && res.hash); |
| 758 callback(res.hash); | 758 callback(res.hash); |
| 759 }); | 759 }); |
| 760 return res && res.hash; | 760 return res && res.hash; |
| 761 }, | 761 }, |
| 762 /* Updates the dictionaries with the JSON data.*/ | 762 /* Updates the dictionaries with the JSON data.*/ |
| 763 update: function(data, isManifest) { | 763 update: function(data, isManifest) { |
| 764 console.log('commitDict.update called: isManifest=' + isManifest); | 764 console.log('commitDict.update called: isManifest=' + isManifest); |
| 765 console.log(data); | 765 console.log(data); |
| 766 // Load new data, then see if any of the callbacks are now valid | 766 // Load new data, then see if any of the callbacks are now valid |
| 767 if(isManifest) { | 767 if(isManifest) { |
| 768 // it's a manifest JSON | 768 // it's a manifest JSON |
| 769 // FUTURE | 769 // FUTURE |
| 770 assert(false, "Unimplemented"); | 770 assert_(false, "Unimplemented"); |
| 771 } else { | 771 } else { |
| 772 // it's a tile JSON | 772 // it's a tile JSON |
| 773 // FUTURE: Remove hack when the JSON has the right format | 773 // FUTURE: Remove hack when the JSON has the right format |
| 774 data['scale'] = data['scale'] || 0; | 774 data['scale'] = data['scale'] || 0; |
| 775 | 775 |
| 776 assert(data && data['commits']); // FUTURE: add: && data['scale']); | 776 assert_(data && data['commits']); // FUTURE: add: && data['scale']); |
| 777 var commits = data['commits']; | 777 var commits = data['commits']; |
| 778 var scale = 0; // FUTURE: Replace with: parseInt(data['scale']); | 778 var scale = 0; // FUTURE: Replace with: parseInt(data['scale']); |
| 779 commits.forEach(function(commit) { | 779 commits.forEach(function(commit) { |
| 780 assert(commit['commit_time']); | 780 assert_(commit['commit_time']); |
| 781 if(!dataDict.has(scale)) { | 781 if(!dataDict.has(scale)) { |
| 782 dataDict.add(scale, new PagedDictionary()); | 782 dataDict.add(scale, new PagedDictionary()); |
| 783 } | 783 } |
| 784 if(!dataDict.get(scale).has(commit['commit_time'])) { | 784 if(!dataDict.get(scale).has(commit['commit_time'])) { |
| 785 dataDict.get(scale).add(parseInt(commit['commit_time']), commit); | 785 dataDict.get(scale).add(parseInt(commit['commit_time']), commit); |
| 786 } | 786 } |
| 787 }); | 787 }); |
| 788 } | 788 } |
| 789 iterateAndPopCallback(function(entry) { | 789 iterateAndPopCallback(function(entry) { |
| 790 assert(entry.callback); | 790 assert_(entry.callback); |
| 791 if(callbackObject.hasOwnProperty('lookup')) { // Then it's a timestamp l
ook up | 791 if(callbackObject.hasOwnProperty('lookup')) { // Then it's a timestamp l
ook up |
| 792 var res = getAssociatedData(entry.timestamp, entry.scale, null); | 792 var res = getAssociatedData(entry.timestamp, entry.scale, null); |
| 793 if(res != null) { | 793 if(res != null) { |
| 794 entry.callback(res); | 794 entry.callback(res); |
| 795 } | 795 } |
| 796 return res != null; // Remove the entry if the get was successful | 796 return res != null; // Remove the entry if the get was successful |
| 797 } | 797 } |
| 798 return false; | 798 return false; |
| 799 }); | 799 }); |
| 800 }, | 800 }, |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 obj[fieldName] = value; | 872 obj[fieldName] = value; |
| 873 } | 873 } |
| 874 } | 874 } |
| 875 var checkSetAttr = function(node, fieldName, value) { | 875 var checkSetAttr = function(node, fieldName, value) { |
| 876 if(node.getAttribute(fieldName) != value) { | 876 if(node.getAttribute(fieldName) != value) { |
| 877 node.setAttribute(fieldName, value); | 877 node.setAttribute(fieldName, value); |
| 878 } | 878 } |
| 879 } | 879 } |
| 880 var specialCases = ['children', 'text', 'attributes', 'style']; | 880 var specialCases = ['children', 'text', 'attributes', 'style']; |
| 881 for(var i = 0; i < model.length; i++) { | 881 for(var i = 0; i < model.length; i++) { |
| 882 assert(model[i].nodeType); | 882 assert_(model[i].nodeType); |
| 883 if(i >= root.children.length || | 883 if(i >= root.children.length || |
| 884 root.children[i].nodeName != model[i].nodeType.toUpperCase()) { | 884 root.children[i].nodeName != model[i].nodeType.toUpperCase()) { |
| 885 root.appendChild(document.createElement(model[i].nodeType)); | 885 root.appendChild(document.createElement(model[i].nodeType)); |
| 886 } | 886 } |
| 887 var curChild = root.children[i]; | 887 var curChild = root.children[i]; |
| 888 for(var name in model[i]) { | 888 for(var name in model[i]) { |
| 889 if(model[i].hasOwnProperty(name) && specialCases.indexOf(name) == -1) { | 889 if(model[i].hasOwnProperty(name) && specialCases.indexOf(name) == -1) { |
| 890 checkSet(curChild, name, model[i][name]); | 890 checkSet(curChild, name, model[i][name]); |
| 891 } | 891 } |
| 892 } | 892 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 921 options[partName].push(selectedOption.value); | 921 options[partName].push(selectedOption.value); |
| 922 }); | 922 }); |
| 923 }); | 923 }); |
| 924 options['dataset'] = currentDataset; | 924 options['dataset'] = currentDataset; |
| 925 return options; | 925 return options; |
| 926 } | 926 } |
| 927 | 927 |
| 928 return { | 928 return { |
| 929 /* Returns a string given the key elements in trace.*/ | 929 /* Returns a string given the key elements in trace.*/ |
| 930 makeLegendKey: function(trace, dataset) { | 930 makeLegendKey: function(trace, dataset) { |
| 931 assert(trace['params']); | 931 assert_(trace['params']); |
| 932 if(!dataset) { | 932 if(!dataset) { |
| 933 assert(trace['params']['dataset']); | 933 assert_(trace['params']['dataset']); |
| 934 dataset = trace['params']['dataset']; | 934 dataset = trace['params']['dataset']; |
| 935 } else if(!trace['params']['dataset']) { | 935 } else if(!trace['params']['dataset']) { |
| 936 trace['params']['dataset'] = dataset; | 936 trace['params']['dataset'] = dataset; |
| 937 } | 937 } |
| 938 assert(validKeyParts[dataset]); | 938 assert_(validKeyParts[dataset]); |
| 939 return validKeyParts[dataset].map(function(part) { | 939 return validKeyParts[dataset].map(function(part) { |
| 940 return trace['params'][part] || ''; | 940 return trace['params'][part] || ''; |
| 941 }).join(KEY_DELIMITER); | 941 }).join(KEY_DELIMITER); |
| 942 }, | 942 }, |
| 943 /* Updates the schema given data in the JSON input.*/ | 943 /* Updates the schema given data in the JSON input.*/ |
| 944 update: function(data, datasetName) { | 944 update: function(data, datasetName) { |
| 945 console.log('schema.update called: datasetName=' + datasetName); | 945 console.log('schema.update called: datasetName=' + datasetName); |
| 946 console.log(data); | 946 console.log(data); |
| 947 assert(data['param_set']); | 947 assert_(data['param_set']); |
| 948 // Update internal structure | 948 // Update internal structure |
| 949 if(!schemaDict.has(datasetName)) { | 949 if(!schemaDict.has(datasetName)) { |
| 950 schemaDict.add(datasetName, new PagedDictionary()); | 950 schemaDict.add(datasetName, new PagedDictionary()); |
| 951 } | 951 } |
| 952 var keys = []; | 952 var keys = []; |
| 953 for(var key in data['param_set']) { | 953 for(var key in data['param_set']) { |
| 954 if(data['param_set'].hasOwnProperty(key) && | 954 if(data['param_set'].hasOwnProperty(key) && |
| 955 validKeyParts[datasetName].indexOf(key) != -1) { | 955 validKeyParts[datasetName].indexOf(key) != -1) { |
| 956 keys.push(key); | 956 keys.push(key); |
| 957 } | 957 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 977 }, this); | 977 }, this); |
| 978 } | 978 } |
| 979 this.updateDOM(); | 979 this.updateDOM(); |
| 980 }, | 980 }, |
| 981 /* Given the input options, returns the ones that define real traces and | 981 /* Given the input options, returns the ones that define real traces and |
| 982 * their number. | 982 * their number. |
| 983 * options is a dictionary keyed with the key part name and has the | 983 * options is a dictionary keyed with the key part name and has the |
| 984 * selected values as its value.*/ | 984 * selected values as its value.*/ |
| 985 getValidOptions: function(options, dataset) { | 985 getValidOptions: function(options, dataset) { |
| 986 // FUTURE: Replace with tree if not performing well enough | 986 // FUTURE: Replace with tree if not performing well enough |
| 987 assert(validKeyParts[dataset]); | 987 assert_(validKeyParts[dataset]); |
| 988 var mapOptions = function(key) { | 988 var mapOptions = function(key) { |
| 989 // Return the split string if it's valid, false otherwise. | 989 // Return the split string if it's valid, false otherwise. |
| 990 var parts = key.split(KEY_DELIMITER); | 990 var parts = key.split(KEY_DELIMITER); |
| 991 return key.split(KEY_DELIMITER).every(function(part, idx) { | 991 return key.split(KEY_DELIMITER).every(function(part, idx) { |
| 992 return !options[validKeyParts[dataset][idx]] || | 992 return !options[validKeyParts[dataset][idx]] || |
| 993 options[validKeyParts[dataset][idx]].indexOf(part) != -1; | 993 options[validKeyParts[dataset][idx]].indexOf(part) != -1; |
| 994 }) && parts; | 994 }) && parts; |
| 995 }; | 995 }; |
| 996 var validLines = lineList.map(mapOptions); | 996 var validLines = lineList.map(mapOptions); |
| 997 var optionDicts = {}; | 997 var optionDicts = {}; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1013 tmpOptions.push(k); | 1013 tmpOptions.push(k); |
| 1014 } | 1014 } |
| 1015 } | 1015 } |
| 1016 optionDicts[validKeyParts[i]] = tmpOptions; | 1016 optionDicts[validKeyParts[i]] = tmpOptions; |
| 1017 } | 1017 } |
| 1018 return [optionDicts, count]; | 1018 return [optionDicts, count]; |
| 1019 }, | 1019 }, |
| 1020 /* Returns a list of valid lines given the selected options.*/ | 1020 /* Returns a list of valid lines given the selected options.*/ |
| 1021 getValidLines: function(options, dataset) { | 1021 getValidLines: function(options, dataset) { |
| 1022 // FUTURE: Replace with tree if not performing well enough | 1022 // FUTURE: Replace with tree if not performing well enough |
| 1023 assert(validKeyParts[dataset]); | 1023 assert_(validKeyParts[dataset]); |
| 1024 var mapOptions = function(key) { | 1024 var mapOptions = function(key) { |
| 1025 // Return the split string if it's valid, false otherwise. | 1025 // Return the split string if it's valid, false otherwise. |
| 1026 var parts = key.split(KEY_DELIMITER); | 1026 var parts = key.split(KEY_DELIMITER); |
| 1027 return parts.every(function(part, idx) { | 1027 return parts.every(function(part, idx) { |
| 1028 return !options[validKeyParts[dataset][idx]] || | 1028 return !options[validKeyParts[dataset][idx]] || |
| 1029 options[validKeyParts[dataset][idx]].indexOf(part) != -1; | 1029 options[validKeyParts[dataset][idx]].indexOf(part) != -1; |
| 1030 }) && key; | 1030 }) && key; |
| 1031 }; | 1031 }; |
| 1032 var validLines = lineList.map(mapOptions); | 1032 var validLines = lineList.map(mapOptions); |
| 1033 // console.log(validLines); | 1033 // console.log(validLines); |
| 1034 return validLines.filter(id); | 1034 return validLines.filter(id); |
| 1035 }, | 1035 }, |
| 1036 /* Updates the selection boxes to match the ones currently in the schema.*/ | 1036 /* Updates the selection boxes to match the ones currently in the schema.*/ |
| 1037 updateDOM: function() { | 1037 updateDOM: function() { |
| 1038 assert(currentDataset); | 1038 assert_(currentDataset); |
| 1039 console.log('schema.updateDOM: start'); | 1039 console.log('schema.updateDOM: start'); |
| 1040 if(!schemaDict.has(currentDataset)) { | 1040 if(!schemaDict.has(currentDataset)) { |
| 1041 console.log('schema.updateDOM: Schema for selected dataset not ' + | 1041 console.log('schema.updateDOM: Schema for selected dataset not ' + |
| 1042 'currently loaded; sending request.'); | 1042 'currently loaded; sending request.'); |
| 1043 var _this = this; | 1043 var _this = this; |
| 1044 jsonRequest.askForTile(0, -1, currentDataset, {'get_params_data': true}, | 1044 jsonRequest.askForTile(0, -1, currentDataset, {'get_params_data': true}, |
| 1045 function(data, success) { | 1045 function(data, success) { |
| 1046 if(success) { | 1046 if(success) { |
| 1047 console.log('schema.updateDOM: received data.'); | 1047 console.log('schema.updateDOM: received data.'); |
| 1048 _this.update(data, currentDataset); | 1048 _this.update(data, currentDataset); |
| 1049 } | 1049 } |
| 1050 }); | 1050 }); |
| 1051 return; | 1051 return; |
| 1052 } | 1052 } |
| 1053 assert($$$('#line-table')); | 1053 assert_($$$('#line-table')); |
| 1054 var inputRoot; | 1054 var inputRoot; |
| 1055 if($$$('#' + currentDataset + '-set')) { | 1055 if($$$('#' + currentDataset + '-set')) { |
| 1056 inputRoot = $$$('#' + currentDataset + '-set'); | 1056 inputRoot = $$$('#' + currentDataset + '-set'); |
| 1057 assert(inputRoot.parentElement == $$$('#line-table')); | 1057 assert_(inputRoot.parentElement == $$$('#line-table')); |
| 1058 } else { | 1058 } else { |
| 1059 inputRoot = document.createElement('tr'); | 1059 inputRoot = document.createElement('tr'); |
| 1060 inputRoot.id = currentDataset + '-set'; | 1060 inputRoot.id = currentDataset + '-set'; |
| 1061 } | 1061 } |
| 1062 var curDict = schemaDict.get(currentDataset); | 1062 var curDict = schemaDict.get(currentDataset); |
| 1063 curDict.index().forEach(function(part) { | 1063 curDict.index().forEach(function(part) { |
| 1064 curDict.get(part).sort(); | 1064 curDict.get(part).sort(); |
| 1065 }); | 1065 }); |
| 1066 var getWidth = function(part) { | 1066 var getWidth = function(part) { |
| 1067 var longestLine = Math.max.apply(null, | 1067 var longestLine = Math.max.apply(null, |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 // console.log(e); | 1182 // console.log(e); |
| 1183 var inputId = e.target.id.slice(0,-'-input'.length); | 1183 var inputId = e.target.id.slice(0,-'-input'.length); |
| 1184 console.log('called for ' + e.target.id); | 1184 console.log('called for ' + e.target.id); |
| 1185 if(e.target.nodeName == 'INPUT') { | 1185 if(e.target.nodeName == 'INPUT') { |
| 1186 if(!currentDataset) { | 1186 if(!currentDataset) { |
| 1187 console.log('line-table.input: no schema currently loaded. Ignoring.
'); | 1187 console.log('line-table.input: no schema currently loaded. Ignoring.
'); |
| 1188 return; | 1188 return; |
| 1189 } | 1189 } |
| 1190 var query = e.target.value; | 1190 var query = e.target.value; |
| 1191 var dataset = schemaDict.get(currentDataset).get(inputId); | 1191 var dataset = schemaDict.get(currentDataset).get(inputId); |
| 1192 assert(dataset != null); | 1192 assert_(dataset != null); |
| 1193 var results = dataset.filter(function(candidate) { | 1193 var results = dataset.filter(function(candidate) { |
| 1194 return candidate.indexOf(query) != -1; | 1194 return candidate.indexOf(query) != -1; |
| 1195 }); // FUTURE: If this is too slow, swap with binary search | 1195 }); // FUTURE: If this is too slow, swap with binary search |
| 1196 if (results.length < 1) { | 1196 if (results.length < 1) { |
| 1197 matchLengths = dataset.map(function(candidate) { | 1197 matchLengths = dataset.map(function(candidate) { |
| 1198 var maxMatch = 0; | 1198 var maxMatch = 0; |
| 1199 for(var start = 0; start < candidate.length; start++) { | 1199 for(var start = 0; start < candidate.length; start++) { |
| 1200 var i = 0; | 1200 var i = 0; |
| 1201 for (; start + i < candidate.length && i < query.length; i++) { | 1201 for (; start + i < candidate.length && i < query.length; i++) { |
| 1202 if (candidate[start + i] != query[i]) { | 1202 if (candidate[start + i] != query[i]) { |
| (...skipping 416 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1619 document.body.addEventListener('click', function(e) { | 1619 document.body.addEventListener('click', function(e) { |
| 1620 if(!$(e.target).parents().is('#note,#chart')) { | 1620 if(!$(e.target).parents().is('#note,#chart')) { |
| 1621 $('#note').hide(); | 1621 $('#note').hide(); |
| 1622 } | 1622 } |
| 1623 }); | 1623 }); |
| 1624 | 1624 |
| 1625 | 1625 |
| 1626 $('#note').hide(); | 1626 $('#note').hide(); |
| 1627 $('#notification').hide(); | 1627 $('#notification').hide(); |
| 1628 }); | 1628 }); |
| OLD | NEW |