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 |