Commit 1f743d2f authored by Zeynep Cankara's avatar Zeynep Cankara Committed by Commit Bot

[tools][system-analyzer] Change Panel Layout

This CL changes the panel layout by
implementing a grid format. The new
layout displays Map and IC panel side by
side and making it easier to control
the position of panels.

Bug: v8:10644

Change-Id: Ic9b48459dd67741c1c39ed2c350ee7c552f1cc92
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2343081
Commit-Queue: Zeynep Cankara <zcankara@google.com>
Reviewed-by: 's avatarCamillo Bruni <cbruni@chromium.org>
Reviewed-by: 's avatarSathya Gunasekaran  <gsathya@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69361}
parent 64828a54
...@@ -80,6 +80,15 @@ dd { ...@@ -80,6 +80,15 @@ dd {
margin: auto; margin: auto;
overflow-x: scroll; overflow-x: scroll;
} }
button {
cursor: pointer;
}
input,
select,
button {
background-color: var(--surface-color);
color: var(--on-surface-color);
}
.colorbox { .colorbox {
width: 10px; width: 10px;
height: 10px; height: 10px;
......
...@@ -89,6 +89,21 @@ found in the LICENSE file. --> ...@@ -89,6 +89,21 @@ found in the LICENSE file. -->
.slider.round:before { .slider.round:before {
border-radius: 50%; border-radius: 50%;
} }
#container.initial {
display: none;
}
#container.loaded {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(500px, 1fr));
grid-auto-flow: dense;
}
#container.loaded > #timeline-panel {
grid-column: span 2;
}
</style> </style>
<script type="module" > <script type="module" >
import {App} from './index.mjs'; import {App} from './index.mjs';
...@@ -104,7 +119,7 @@ globalThis.app = new App("#log-file-reader", "#map-panel", "#timeline-panel", ...@@ -104,7 +119,7 @@ globalThis.app = new App("#log-file-reader", "#map-panel", "#timeline-panel",
<log-file-reader id="log-file-reader"></log-file-reader> <log-file-reader id="log-file-reader"></log-file-reader>
<br></br> <br></br>
</section> </section>
<div id="container" style="display: none;"> <div id="container" class="initial">
<timeline-panel id="timeline-panel"> <timeline-panel id="timeline-panel">
<timeline-track id="map-track"></timeline-track> <timeline-track id="map-track"></timeline-track>
<timeline-track id="ic-track"></timeline-track> <timeline-track id="ic-track"></timeline-track>
...@@ -121,7 +136,9 @@ globalThis.app = new App("#log-file-reader", "#map-panel", "#timeline-panel", ...@@ -121,7 +136,9 @@ globalThis.app = new App("#log-file-reader", "#map-panel", "#timeline-panel",
</div> </div>
<div id="instructions"> <div id="instructions">
<h2>Instructions</h2> <h2>Instructions</h2>
<p>Unified web interface for analyzing the trace information of the Maps/ICs</p> <p>
Unified web interface for analyzing the trace information of the Maps/ICs
</p>
<ul> <ul>
<li> Visualize Map trees that have gathered</li> <li> Visualize Map trees that have gathered</li>
<li><code> /path/to/d8 --trace-maps $FILE</code></li> <li><code> /path/to/d8 --trace-maps $FILE</code></li>
......
...@@ -3,19 +3,25 @@ ...@@ -3,19 +3,25 @@
// found in the LICENSE file. // found in the LICENSE file.
import CustomIcProcessor from "./ic-processor.mjs"; import CustomIcProcessor from "./ic-processor.mjs";
import {Entry} from "./ic-processor.mjs"; import { Entry } from "./ic-processor.mjs";
import {State} from './app-model.mjs'; import { State } from "./app-model.mjs";
import {MapProcessor, V8Map} from './map-processor.mjs'; import { MapProcessor, V8Map } from "./map-processor.mjs";
import {$} from './helper.mjs'; import { $ } from "./helper.mjs";
import './ic-panel.mjs'; import "./ic-panel.mjs";
import './timeline-panel.mjs'; import "./timeline-panel.mjs";
import './map-panel.mjs'; import "./map-panel.mjs";
import './log-file-reader.mjs'; import "./log-file-reader.mjs";
class App { class App {
#state #state;
#view; #view;
constructor(fileReaderId, mapPanelId, timelinePanelId, constructor(
icPanelId, mapTrackId, icTrackId) { fileReaderId,
mapPanelId,
timelinePanelId,
icPanelId,
mapTrackId,
icTrackId
) {
this.#view = { this.#view = {
logFileReader: $(fileReaderId), logFileReader: $(fileReaderId),
icPanel: $(icPanelId), icPanel: $(icPanelId),
...@@ -23,67 +29,68 @@ class App { ...@@ -23,67 +29,68 @@ class App {
timelinePanel: $(timelinePanelId), timelinePanel: $(timelinePanelId),
mapTrack: $(mapTrackId), mapTrack: $(mapTrackId),
icTrack: $(icTrackId), icTrack: $(icTrackId),
} };
this.#state = new State(); this.#state = new State();
this.toggleSwitch = $('.theme-switch input[type="checkbox"]'); this.toggleSwitch = $('.theme-switch input[type="checkbox"]');
this.toggleSwitch.addEventListener('change', e => this.switchTheme(e)); this.toggleSwitch.addEventListener("change", (e) => this.switchTheme(e));
this.#view.logFileReader.addEventListener('fileuploadstart', this.#view.logFileReader.addEventListener("fileuploadstart", (e) =>
e => this.handleFileUpload(e)); this.handleFileUpload(e)
this.#view.logFileReader.addEventListener('fileuploadend', );
e => this.handleDataUpload(e)); this.#view.logFileReader.addEventListener("fileuploadend", (e) =>
this.handleDataUpload(e)
);
Object.entries(this.#view).forEach(([_, value]) => { Object.entries(this.#view).forEach(([_, value]) => {
value.addEventListener('showentries', value.addEventListener("showentries", (e) => this.handleShowEntries(e));
e => this.handleShowEntries(e)); value.addEventListener("showentrydetail", (e) =>
value.addEventListener('showentrydetail', this.handleShowEntryDetail(e)
e => this.handleShowEntryDetail(e)); );
}); });
this.#view.icPanel.addEventListener( this.#view.icPanel.addEventListener("ictimefilter", (e) =>
'ictimefilter', e => this.handleICTimeFilter(e)); this.handleICTimeFilter(e)
);
} }
handleShowEntries(e){ handleShowEntries(e) {
if(e.entries[0] instanceof V8Map){ if (e.entries[0] instanceof V8Map) {
this.#view.mapPanel.mapEntries = e.entries; this.#view.mapPanel.mapEntries = e.entries;
} }
} }
handleShowEntryDetail(e){ handleShowEntryDetail(e) {
if(e.entry instanceof V8Map){ if (e.entry instanceof V8Map) {
this.selectMapLogEvent(e.entry); this.selectMapLogEvent(e.entry);
} } else if (e.entry instanceof Entry) {
else if(e.entry instanceof Entry){
this.selectICLogEvent(e.entry); this.selectICLogEvent(e.entry);
} } else if (typeof e.entry === "string") {
else if(typeof e.entry === 'string'){
this.selectSourcePositionEvent(e.entry); this.selectSourcePositionEvent(e.entry);
} } else {
else {
console.log("undefined"); console.log("undefined");
} }
} }
handleClickSourcePositions(e){ handleClickSourcePositions(e) {
//TODO(zcankara) Handle source position //TODO(zcankara) Handle source position
console.log("Entry containing source position: ", e.entries); console.log("Entry containing source position: ", e.entries);
} }
selectMapLogEvent(entry){ selectMapLogEvent(entry) {
this.#state.map = entry; this.#state.map = entry;
this.#view.mapTrack.selectedEntry = entry; this.#view.mapTrack.selectedEntry = entry;
this.#view.mapPanel.map = entry; this.#view.mapPanel.map = entry;
} }
selectICLogEvent(entry){ selectICLogEvent(entry) {
console.log("IC Entry selection"); console.log("IC Entry selection");
} }
selectSourcePositionEvent(sourcePositions){ selectSourcePositionEvent(sourcePositions) {
console.log("source positions: ", sourcePositions); console.log("source positions: ", sourcePositions);
} }
handleICTimeFilter(event) { handleICTimeFilter(event) {
this.#state.timeSelection.start = event.detail.startTime; this.#state.timeSelection.start = event.detail.startTime;
this.#state.timeSelection.end = event.detail.endTime; this.#state.timeSelection.end = event.detail.endTime;
this.#view.icTrack.data.selectTimeRange(this.#state.timeSelection.start, this.#view.icTrack.data.selectTimeRange(
this.#state.timeSelection.end); this.#state.timeSelection.start,
this.#state.timeSelection.end
);
this.#view.icPanel.filteredEntries = this.#view.icTrack.data.selection; this.#view.icPanel.filteredEntries = this.#view.icTrack.data.selection;
} }
handleFileUpload(e){ handleFileUpload(e) {
//TODO(zcankara) Set a state on the document.body. Exe: .loading, .loaded $("#container").className = "initial";
$('#container').style.display = 'none';
} }
// Map event log processing // Map event log processing
handleLoadTextMapProcessor(text) { handleLoadTextMapProcessor(text) {
...@@ -102,15 +109,15 @@ class App { ...@@ -102,15 +109,15 @@ class App {
this.#view.icTrack.data = this.#state.icTimeline; this.#view.icTrack.data = this.#state.icTimeline;
this.#view.icPanel.filteredEntries = this.#view.icTrack.data.all; this.#view.icPanel.filteredEntries = this.#view.icTrack.data.all;
this.#view.icPanel.count.innerHTML = this.#view.icTrack.data.all.length; this.#view.icPanel.count.innerHTML = this.#view.icTrack.data.all.length;
} };
reader.readAsText(fileData.file); reader.readAsText(fileData.file);
this.#view.icPanel.initGroupKeySelect(); this.#view.icPanel.initGroupKeySelect();
} }
// call when a new file uploaded // call when a new file uploaded
handleDataUpload(e) { handleDataUpload(e) {
if(!e.detail) return; if (!e.detail) return;
$('#container').style.display = 'block'; $("#container").className = "loaded";
// instantiate the app logic // instantiate the app logic
let fileData = e.detail; let fileData = e.detail;
try { try {
...@@ -128,19 +135,19 @@ class App { ...@@ -128,19 +135,19 @@ class App {
this.fileLoaded = true; this.fileLoaded = true;
} }
refreshTimelineTrackView(){ refreshTimelineTrackView() {
this.#view.mapTrack.data = this.#state.mapTimeline; this.#view.mapTrack.data = this.#state.mapTimeline;
this.#view.icTrack.data = this.#state.icTimeline; this.#view.icTrack.data = this.#state.icTimeline;
} }
switchTheme(event) { switchTheme(event) {
document.documentElement.dataset.theme = document.documentElement.dataset.theme = event.target.checked
event.target.checked ? 'light' : 'dark'; ? "light"
if(this.fileLoaded) { : "dark";
if (this.fileLoaded) {
this.refreshTimelineTrackView(); this.refreshTimelineTrackView();
} }
} }
} }
export { App };
export {App};
<!-- Copyright 2020 the V8 project authors. All rights reserved. <!-- Copyright 2020 the V8 project authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. --> found in the LICENSE file. -->
<head> <head>
<link href="./index.css" rel="stylesheet"> <link href="./index.css" rel="stylesheet">
</head> </head>
<style> <style>
#mapDetails { #mapDetails {
font-family: monospace;
white-space: pre;
overflow-x: scroll; overflow-x: scroll;
} overflow-y: scroll;
height: 100px;
}
</style> </style>
<div id="container"> <div class="panel">
<div class="panel">
<h4>Map Details</h4> <h4>Map Details</h4>
<section id="mapDetails"></section> <section id="mapDetails"></section>
</div>
</div> </div>
<!-- Copyright 2020 the V8 project authors. All rights reserved. <!-- Copyright 2020 the V8 project authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. --> found in the LICENSE file. -->
<head> <head>
<link href="./index.css" rel="stylesheet"> <link href="./index.css" rel="stylesheet">
</head> </head>
<style> <style>
#transitionView {
#transitionView {
overflow-x: scroll; overflow-x: scroll;
white-space: nowrap; white-space: nowrap;
min-height: 50px; min-height: 50px;
...@@ -14,8 +14,9 @@ found in the LICENSE file. --> ...@@ -14,8 +14,9 @@ found in the LICENSE file. -->
padding: 50px 0 0 0; padding: 50px 0 0 0;
margin-top: -25px; margin-top: -25px;
width: 100%; width: 100%;
} }
.map {
.map {
width: 20px; width: 20px;
height: 20px; height: 20px;
display: inline-block; display: inline-block;
...@@ -32,55 +33,55 @@ found in the LICENSE file. --> ...@@ -32,55 +33,55 @@ found in the LICENSE file. -->
position: relative; position: relative;
z-index: 2; z-index: 2;
cursor: pointer; cursor: pointer;
} }
.map.selected { .map.selected {
border-color: var(--map-background-color); border-color: var(--map-background-color);
} }
.transitions { .transitions {
display: inline-block; display: inline-block;
margin-left: -15px; margin-left: -15px;
} }
.transition { .transition {
min-height: 55px; min-height: 55px;
margin: 0 0 -2px 2px; margin: 0 0 -2px 2px;
} }
/* gray out deprecated transitions */ /* gray out deprecated transitions */
.deprecated > .transitionEdge, .deprecated>.transitionEdge,
.deprecated > .map { .deprecated>.map {
opacity: 0.5; opacity: 0.5;
} }
.deprecated > .transition { .deprecated>.transition {
border-color: rgba(0, 0, 0, 0.5); border-color: rgba(0, 0, 0, 0.5);
} }
/* Show a border for all but the first transition */ /* Show a border for all but the first transition */
.transition:nth-of-type(2), .transition:nth-of-type(2),
.transition:nth-last-of-type(n+2) { .transition:nth-last-of-type(n+2) {
border-left: 2px solid; border-left: 2px solid;
margin-left: 0px; margin-left: 0px;
} }
/* special case for 2 transitions */ /* special case for 2 transitions */
.transition:nth-last-of-type(1) { .transition:nth-last-of-type(1) {
border-left: none; border-left: none;
} }
/* topmost transitions are not related */ /* topmost transitions are not related */
#transitionView > .transition { #transitionView>.transition {
border-left: none; border-left: none;
} }
/* topmost transition edge needs initial offset to be aligned */ /* topmost transition edge needs initial offset to be aligned */
#transitionView > .transition > .transitionEdge { #transitionView>.transition>.transitionEdge {
margin-left: 13px; margin-left: 13px;
} }
.transitionEdge { .transitionEdge {
height: 2px; height: 2px;
width: 80px; width: 80px;
display: inline-block; display: inline-block;
...@@ -88,9 +89,9 @@ found in the LICENSE file. --> ...@@ -88,9 +89,9 @@ found in the LICENSE file. -->
background-color: var(--map-background-color); background-color: var(--map-background-color);
vertical-align: top; vertical-align: top;
padding-left: 15px; padding-left: 15px;
} }
.transitionLabel { .transitionLabel {
color: var(--on-surface-color); color: var(--on-surface-color);
transform: rotate(-15deg); transform: rotate(-15deg);
transform-origin: top left; transform-origin: top left;
...@@ -99,9 +100,9 @@ found in the LICENSE file. --> ...@@ -99,9 +100,9 @@ found in the LICENSE file. -->
white-space: normal; white-space: normal;
word-break: break-all; word-break: break-all;
background-color: var(--surface-color); background-color: var(--surface-color);
} }
.showSubtransitions { .showSubtransitions {
width: 0; width: 0;
height: 0; height: 0;
border-left: 6px solid transparent; border-left: 6px solid transparent;
...@@ -109,15 +110,15 @@ found in the LICENSE file. --> ...@@ -109,15 +110,15 @@ found in the LICENSE file. -->
border-top: 10px solid var(--map-background-color); border-top: 10px solid var(--map-background-color);
cursor: zoom-in; cursor: zoom-in;
margin: 4px 0 0 4px; margin: 4px 0 0 4px;
} }
.showSubtransitions.opened { .showSubtransitions.opened {
border-top: none; border-top: none;
border-bottom: 10px solid var(--map-background-color); border-bottom: 10px solid var(--map-background-color);
cursor: zoom-out; cursor: zoom-out;
} }
#tooltip { #tooltip {
position: absolute; position: absolute;
width: 10px; width: 10px;
height: 10px; height: 10px;
...@@ -125,18 +126,18 @@ found in the LICENSE file. --> ...@@ -125,18 +126,18 @@ found in the LICENSE file. -->
pointer-events: none; pointer-events: none;
z-index: 100; z-index: 100;
display: none; display: none;
} }
#title { #title {
padding-bottom: 20px; padding-bottom: 10px;
} }
</style> </style>
<div id="container"> <div class="panel">
<div class="panel"> <div id="title">
<div id="title"><h4>Transitions</h4></div> <h4>Transitions</h4>
</div>
<section id="transitionView"></section> <section id="transitionView"></section>
<div id="tooltip"> <div id="tooltip">
<div id="tooltipContents"></div> <div id="tooltipContents"></div>
</div> </div>
</div>
</div> </div>
...@@ -2,47 +2,53 @@ ...@@ -2,47 +2,53 @@
Use of this source code is governed by a BSD-style license that can be Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. --> found in the LICENSE file. -->
<style> <style>
@import "./index.css"; @import "./index.css";
#stats {
#stats {
display: flex; display: flex;
height: 250px; height: 250px;
background-color: var(--surface-color); background-color: var(--surface-color);
padding: 10px 10px 10px 10px ; padding: 10px 10px 10px 10px;
margin: auto; margin: auto;
} }
#stats table {
#stats table {
flex: 1; flex: 1;
padding-right: 50px; padding-right: 50px;
max-height: 250px; max-height: 250px;
display: inline-block; display: inline-block;
overflow-y: scroll; overflow-y: scroll;
} }
#stats table td {
#stats table td {
cursor: pointer; cursor: pointer;
} }
#stats .transitionTable {
#stats .transitionTable {
overflow-y: scroll; overflow-y: scroll;
} }
#stats .transitionTable tr {
#stats .transitionTable tr {
max-width: 200px; max-width: 200px;
} }
#stats .transitionType {
#stats .transitionType {
text-align: right; text-align: right;
max-width: 380px; max-width: 380px;
} }
#stats .transitionType tr td:nth-child(2) {
#stats .transitionType tr td:nth-child(2) {
text-align: left; text-align: left;
} }
#stats table thead td {
#stats table thead td {
border-bottom: 1px var(--on-surface-color) dotted; border-bottom: 1px var(--on-surface-color) dotted;
} }
</style> </style>
<div id="container"> <div class="panel">
<div class="panel">
<h2>Stats Panel</h2> <h2>Stats Panel</h2>
<h3>Stats</h3> <h3>Stats</h3>
<section id="stats"> <section id="stats">
</section> </section>
</div>
</div> </div>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment