| OLD | NEW |
| 1 // Copyright 2017 the V8 project authors. All rights reserved. | 1 // Copyright 2017 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 "use strict" | 5 "use strict" |
| 6 | 6 |
| 7 function $(id) { | 7 function $(id) { |
| 8 return document.getElementById(id); | 8 return document.getElementById(id); |
| 9 } | 9 } |
| 10 | 10 |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 146 setFile(file) { | 146 setFile(file) { |
| 147 if (file != main.currentState.file) { | 147 if (file != main.currentState.file) { |
| 148 main.currentState = Object.assign({}, main.currentState); | 148 main.currentState = Object.assign({}, main.currentState); |
| 149 main.currentState.file = file; | 149 main.currentState.file = file; |
| 150 main.delayRender(); | 150 main.delayRender(); |
| 151 } | 151 } |
| 152 }, | 152 }, |
| 153 | 153 |
| 154 onResize() { | 154 onResize() { |
| 155 main.setTimeLineDimensions( | 155 main.setTimeLineDimensions( |
| 156 window.innerWidth - 20, window.innerHeight / 8); | 156 window.innerWidth - 20, window.innerHeight / 5); |
| 157 }, | 157 }, |
| 158 | 158 |
| 159 onLoad() { | 159 onLoad() { |
| 160 function loadHandler(evt) { | 160 function loadHandler(evt) { |
| 161 let f = evt.target.files[0]; | 161 let f = evt.target.files[0]; |
| 162 if (f) { | 162 if (f) { |
| 163 let reader = new FileReader(); | 163 let reader = new FileReader(); |
| 164 reader.onload = function(event) { | 164 reader.onload = function(event) { |
| 165 let profData = JSON.parse(event.target.result); | 165 let profData = JSON.parse(event.target.result); |
| 166 main.setViewInterval(0, Infinity); | 166 main.setViewInterval(0, Infinity); |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 this.legend = $("timeline-legend"); | 621 this.legend = $("timeline-legend"); |
| 622 | 622 |
| 623 this.canvas.onmousedown = this.onMouseDown.bind(this); | 623 this.canvas.onmousedown = this.onMouseDown.bind(this); |
| 624 this.canvas.onmouseup = this.onMouseUp.bind(this); | 624 this.canvas.onmouseup = this.onMouseUp.bind(this); |
| 625 this.canvas.onmousemove = this.onMouseMove.bind(this); | 625 this.canvas.onmousemove = this.onMouseMove.bind(this); |
| 626 | 626 |
| 627 this.selectionStart = null; | 627 this.selectionStart = null; |
| 628 this.selectionEnd = null; | 628 this.selectionEnd = null; |
| 629 this.selecting = false; | 629 this.selecting = false; |
| 630 | 630 |
| 631 this.fontSize = 12; |
| 632 this.imageOffset = this.fontSize * 1.2; |
| 633 |
| 631 this.currentState = null; | 634 this.currentState = null; |
| 632 } | 635 } |
| 633 | 636 |
| 634 onMouseDown(e) { | 637 onMouseDown(e) { |
| 635 this.selectionStart = | 638 this.selectionStart = |
| 636 e.clientX - this.canvas.getBoundingClientRect().left; | 639 e.clientX - this.canvas.getBoundingClientRect().left; |
| 637 this.selectionEnd = this.selectionStart + 1; | 640 this.selectionEnd = this.selectionStart + 1; |
| 638 this.selecting = true; | 641 this.selecting = true; |
| 639 } | 642 } |
| 640 | 643 |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 677 } | 680 } |
| 678 | 681 |
| 679 main.setViewInterval(start, end); | 682 main.setViewInterval(start, end); |
| 680 } | 683 } |
| 681 } | 684 } |
| 682 this.selecting = false; | 685 this.selecting = false; |
| 683 } | 686 } |
| 684 | 687 |
| 685 drawSelection() { | 688 drawSelection() { |
| 686 let ctx = this.canvas.getContext("2d"); | 689 let ctx = this.canvas.getContext("2d"); |
| 687 ctx.drawImage(this.buffer, 0, 0); | |
| 688 | 690 |
| 691 // Draw the timeline image. |
| 692 ctx.drawImage(this.buffer, 0, this.imageOffset); |
| 693 |
| 694 // Draw the current interval highlight. |
| 695 let left; |
| 696 let right; |
| 689 if (this.selectionStart !== null && this.selectionEnd !== null) { | 697 if (this.selectionStart !== null && this.selectionEnd !== null) { |
| 690 ctx.fillStyle = "rgba(0, 0, 0, 0.3)"; | 698 ctx.fillStyle = "rgba(0, 0, 0, 0.3)"; |
| 691 let left = Math.min(this.selectionStart, this.selectionEnd); | 699 left = Math.min(this.selectionStart, this.selectionEnd); |
| 692 let right = Math.max(this.selectionStart, this.selectionEnd); | 700 right = Math.max(this.selectionStart, this.selectionEnd); |
| 693 ctx.fillRect(0, 0, left, this.buffer.height); | 701 ctx.fillRect(0, this.imageOffset, left, this.buffer.height); |
| 694 ctx.fillRect(right, 0, this.buffer.width - right, this.buffer.height); | 702 ctx.fillRect(right, this.imageOffset, this.buffer.width - right, |
| 703 this.buffer.height); |
| 704 } else { |
| 705 left = 0; |
| 706 right = this.buffer.width; |
| 707 } |
| 708 |
| 709 // Draw the scale text. |
| 710 let file = this.currentState.file; |
| 711 ctx.fillStyle = "white"; |
| 712 ctx.fillRect(0, 0, this.canvas.width, this.imageOffset); |
| 713 if (file && file.ticks.length > 0) { |
| 714 let firstTime = file.ticks[0].tm; |
| 715 let lastTime = file.ticks[file.ticks.length - 1].tm; |
| 716 |
| 717 let leftTime = |
| 718 firstTime + left / this.canvas.width * (lastTime - firstTime); |
| 719 let rightTime = |
| 720 firstTime + right / this.canvas.width * (lastTime - firstTime); |
| 721 |
| 722 let leftText = (leftTime / 1000000).toFixed(3) + "s"; |
| 723 let rightText = (rightTime / 1000000).toFixed(3) + "s"; |
| 724 |
| 725 ctx.textBaseline = 'top'; |
| 726 ctx.font = this.fontSize + "px Arial"; |
| 727 ctx.fillStyle = "black"; |
| 728 |
| 729 let leftWidth = ctx.measureText(leftText).width; |
| 730 let rightWidth = ctx.measureText(rightText).width; |
| 731 |
| 732 let leftStart = left - leftWidth / 2; |
| 733 let rightStart = right - rightWidth / 2; |
| 734 |
| 735 if (leftStart < 0) leftStart = 0; |
| 736 if (rightStart + rightWidth > this.canvas.width) { |
| 737 rightStart = this.canvas.width - rightWidth; |
| 738 } |
| 739 if (leftStart + leftWidth > rightStart) { |
| 740 if (leftStart > this.canvas.width - (rightStart - rightWidth)) { |
| 741 rightStart = leftStart + leftWidth; |
| 742 |
| 743 } else { |
| 744 leftStart = rightStart - leftWidth; |
| 745 } |
| 746 } |
| 747 |
| 748 ctx.fillText(leftText, leftStart, 0); |
| 749 ctx.fillText(rightText, rightStart, 0); |
| 695 } | 750 } |
| 696 } | 751 } |
| 697 | 752 |
| 698 | |
| 699 render(newState) { | 753 render(newState) { |
| 700 let oldState = this.currentState; | 754 let oldState = this.currentState; |
| 701 | 755 |
| 702 if (!newState.file) { | 756 if (!newState.file) { |
| 703 this.element.style.display = "none"; | 757 this.element.style.display = "none"; |
| 704 return; | 758 return; |
| 705 } | 759 } |
| 706 | 760 |
| 707 this.currentState = newState; | 761 this.currentState = newState; |
| 708 if (oldState) { | 762 if (oldState) { |
| 709 if (newState.timeLine.width === oldState.timeLine.width && | 763 if (newState.timeLine.width === oldState.timeLine.width && |
| 710 newState.timeLine.height === oldState.timeLine.height && | 764 newState.timeLine.height === oldState.timeLine.height && |
| 711 newState.file === oldState.file && | 765 newState.file === oldState.file && |
| 712 newState.start === oldState.start && | 766 newState.start === oldState.start && |
| 713 newState.end === oldState.end) { | 767 newState.end === oldState.end) { |
| 714 // No change, nothing to do. | 768 // No change, nothing to do. |
| 715 return; | 769 return; |
| 716 } | 770 } |
| 717 } | 771 } |
| 718 | 772 |
| 719 this.element.style.display = "inherit"; | 773 this.element.style.display = "inherit"; |
| 720 | 774 |
| 721 // Make sure the canvas has the right dimensions. | 775 // Make sure the canvas has the right dimensions. |
| 722 let width = this.currentState.timeLine.width; | 776 let width = this.currentState.timeLine.width; |
| 777 let height = this.currentState.timeLine.height; |
| 723 this.canvas.width = width; | 778 this.canvas.width = width; |
| 724 this.canvas.height = this.currentState.timeLine.height; | 779 this.canvas.height = height; |
| 780 |
| 781 // Make space for the selection text. |
| 782 height -= this.imageOffset; |
| 725 | 783 |
| 726 let file = this.currentState.file; | 784 let file = this.currentState.file; |
| 727 if (!file) return; | 785 if (!file) return; |
| 728 | 786 |
| 729 let firstTime = file.ticks[0].tm; | 787 let firstTime = file.ticks[0].tm; |
| 730 let lastTime = file.ticks[file.ticks.length - 1].tm; | 788 let lastTime = file.ticks[file.ticks.length - 1].tm; |
| 731 let start = Math.max(this.currentState.start, firstTime); | 789 let start = Math.max(this.currentState.start, firstTime); |
| 732 let end = Math.min(this.currentState.end, lastTime); | 790 let end = Math.min(this.currentState.end, lastTime); |
| 733 | 791 |
| 734 this.selectionStart = (start - firstTime) / (lastTime - firstTime) * width; | 792 this.selectionStart = (start - firstTime) / (lastTime - firstTime) * width; |
| 735 this.selectionEnd = (end - firstTime) / (lastTime - firstTime) * width; | 793 this.selectionEnd = (end - firstTime) / (lastTime - firstTime) * width; |
| 736 | 794 |
| 737 let tickCount = file.ticks.length; | 795 let tickCount = file.ticks.length; |
| 738 | 796 |
| 739 let minBucketPixels = 10; | 797 let minBucketPixels = 10; |
| 740 let minBucketSamples = 30; | 798 let minBucketSamples = 30; |
| 741 let bucketCount = Math.min(width / minBucketPixels, | 799 let bucketCount = Math.min(width / minBucketPixels, |
| 742 tickCount / minBucketSamples); | 800 tickCount / minBucketSamples); |
| 743 | 801 |
| 744 let stackProcessor = new CategorySampler(file, bucketCount); | 802 let stackProcessor = new CategorySampler(file, bucketCount); |
| 745 generateTree(file, 0, Infinity, stackProcessor); | 803 generateTree(file, 0, Infinity, stackProcessor); |
| 746 | 804 |
| 747 let buffer = document.createElement("canvas"); | 805 let buffer = document.createElement("canvas"); |
| 748 | 806 |
| 749 buffer.width = this.canvas.width; | 807 buffer.width = width; |
| 750 buffer.height = this.canvas.height; | 808 buffer.height = height; |
| 751 | 809 |
| 752 // Calculate the bar heights for each bucket. | 810 // Calculate the bar heights for each bucket. |
| 753 let graphHeight = buffer.height; | 811 let graphHeight = height; |
| 754 let buckets = stackProcessor.buckets; | 812 let buckets = stackProcessor.buckets; |
| 755 let bucketsGraph = []; | 813 let bucketsGraph = []; |
| 756 for (let i = 0; i < buckets.length; i++) { | 814 for (let i = 0; i < buckets.length; i++) { |
| 757 let sum = 0; | 815 let sum = 0; |
| 758 let bucketData = []; | 816 let bucketData = []; |
| 759 let total = buckets[i].total; | 817 let total = buckets[i].total; |
| 760 for (let j = 0; j < bucketDescriptors.length; j++) { | 818 for (let j = 0; j < bucketDescriptors.length; j++) { |
| 761 let desc = bucketDescriptors[j]; | 819 let desc = bucketDescriptors[j]; |
| 762 for (let k = 0; k < desc.kinds.length; k++) { | 820 for (let k = 0; k < desc.kinds.length; k++) { |
| 763 sum += buckets[i][desc.kinds[k]]; | 821 sum += buckets[i][desc.kinds[k]]; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 818 | 876 |
| 819 class HelpView { | 877 class HelpView { |
| 820 constructor() { | 878 constructor() { |
| 821 this.element = $("help"); | 879 this.element = $("help"); |
| 822 } | 880 } |
| 823 | 881 |
| 824 render(newState) { | 882 render(newState) { |
| 825 this.element.style.display = newState.file ? "none" : "inherit"; | 883 this.element.style.display = newState.file ? "none" : "inherit"; |
| 826 } | 884 } |
| 827 } | 885 } |
| OLD | NEW |