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 {
margin: auto;
overflow-x: scroll;
}
button {
cursor: pointer;
}
input,
select,
button {
background-color: var(--surface-color);
color: var(--on-surface-color);
}
.colorbox {
width: 10px;
height: 10px;
......
......@@ -89,6 +89,21 @@ found in the LICENSE file. -->
.slider.round:before {
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>
<script type="module" >
import {App} from './index.mjs';
......@@ -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>
<br></br>
</section>
<div id="container" style="display: none;">
<div id="container" class="initial">
<timeline-panel id="timeline-panel">
<timeline-track id="map-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",
</div>
<div id="instructions">
<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>
<li> Visualize Map trees that have gathered</li>
<li><code> /path/to/d8 --trace-maps $FILE</code></li>
......
......@@ -3,19 +3,25 @@
// found in the LICENSE file.
import CustomIcProcessor from "./ic-processor.mjs";
import {Entry} from "./ic-processor.mjs";
import {State} from './app-model.mjs';
import {MapProcessor, V8Map} from './map-processor.mjs';
import {$} from './helper.mjs';
import './ic-panel.mjs';
import './timeline-panel.mjs';
import './map-panel.mjs';
import './log-file-reader.mjs';
import { Entry } from "./ic-processor.mjs";
import { State } from "./app-model.mjs";
import { MapProcessor, V8Map } from "./map-processor.mjs";
import { $ } from "./helper.mjs";
import "./ic-panel.mjs";
import "./timeline-panel.mjs";
import "./map-panel.mjs";
import "./log-file-reader.mjs";
class App {
#state
#state;
#view;
constructor(fileReaderId, mapPanelId, timelinePanelId,
icPanelId, mapTrackId, icTrackId) {
constructor(
fileReaderId,
mapPanelId,
timelinePanelId,
icPanelId,
mapTrackId,
icTrackId
) {
this.#view = {
logFileReader: $(fileReaderId),
icPanel: $(icPanelId),
......@@ -23,67 +29,68 @@ class App {
timelinePanel: $(timelinePanelId),
mapTrack: $(mapTrackId),
icTrack: $(icTrackId),
}
};
this.#state = new State();
this.toggleSwitch = $('.theme-switch input[type="checkbox"]');
this.toggleSwitch.addEventListener('change', e => this.switchTheme(e));
this.#view.logFileReader.addEventListener('fileuploadstart',
e => this.handleFileUpload(e));
this.#view.logFileReader.addEventListener('fileuploadend',
e => this.handleDataUpload(e));
this.toggleSwitch.addEventListener("change", (e) => this.switchTheme(e));
this.#view.logFileReader.addEventListener("fileuploadstart", (e) =>
this.handleFileUpload(e)
);
this.#view.logFileReader.addEventListener("fileuploadend", (e) =>
this.handleDataUpload(e)
);
Object.entries(this.#view).forEach(([_, value]) => {
value.addEventListener('showentries',
e => this.handleShowEntries(e));
value.addEventListener('showentrydetail',
e => this.handleShowEntryDetail(e));
value.addEventListener("showentries", (e) => this.handleShowEntries(e));
value.addEventListener("showentrydetail", (e) =>
this.handleShowEntryDetail(e)
);
});
this.#view.icPanel.addEventListener(
'ictimefilter', e => this.handleICTimeFilter(e));
this.#view.icPanel.addEventListener("ictimefilter", (e) =>
this.handleICTimeFilter(e)
);
}
handleShowEntries(e){
if(e.entries[0] instanceof V8Map){
handleShowEntries(e) {
if (e.entries[0] instanceof V8Map) {
this.#view.mapPanel.mapEntries = e.entries;
}
}
handleShowEntryDetail(e){
if(e.entry instanceof V8Map){
handleShowEntryDetail(e) {
if (e.entry instanceof V8Map) {
this.selectMapLogEvent(e.entry);
}
else if(e.entry instanceof Entry){
} else if (e.entry instanceof Entry) {
this.selectICLogEvent(e.entry);
}
else if(typeof e.entry === 'string'){
} else if (typeof e.entry === "string") {
this.selectSourcePositionEvent(e.entry);
}
else {
} else {
console.log("undefined");
}
}
handleClickSourcePositions(e){
handleClickSourcePositions(e) {
//TODO(zcankara) Handle source position
console.log("Entry containing source position: ", e.entries);
}
selectMapLogEvent(entry){
selectMapLogEvent(entry) {
this.#state.map = entry;
this.#view.mapTrack.selectedEntry = entry;
this.#view.mapPanel.map = entry;
}
selectICLogEvent(entry){
selectICLogEvent(entry) {
console.log("IC Entry selection");
}
selectSourcePositionEvent(sourcePositions){
selectSourcePositionEvent(sourcePositions) {
console.log("source positions: ", sourcePositions);
}
handleICTimeFilter(event) {
this.#state.timeSelection.start = event.detail.startTime;
this.#state.timeSelection.end = event.detail.endTime;
this.#view.icTrack.data.selectTimeRange(this.#state.timeSelection.start,
this.#state.timeSelection.end);
this.#view.icTrack.data.selectTimeRange(
this.#state.timeSelection.start,
this.#state.timeSelection.end
);
this.#view.icPanel.filteredEntries = this.#view.icTrack.data.selection;
}
handleFileUpload(e){
//TODO(zcankara) Set a state on the document.body. Exe: .loading, .loaded
$('#container').style.display = 'none';
handleFileUpload(e) {
$("#container").className = "initial";
}
// Map event log processing
handleLoadTextMapProcessor(text) {
......@@ -102,15 +109,15 @@ class App {
this.#view.icTrack.data = this.#state.icTimeline;
this.#view.icPanel.filteredEntries = this.#view.icTrack.data.all;
this.#view.icPanel.count.innerHTML = this.#view.icTrack.data.all.length;
}
};
reader.readAsText(fileData.file);
this.#view.icPanel.initGroupKeySelect();
}
// call when a new file uploaded
handleDataUpload(e) {
if(!e.detail) return;
$('#container').style.display = 'block';
if (!e.detail) return;
$("#container").className = "loaded";
// instantiate the app logic
let fileData = e.detail;
try {
......@@ -128,19 +135,19 @@ class App {
this.fileLoaded = true;
}
refreshTimelineTrackView(){
refreshTimelineTrackView() {
this.#view.mapTrack.data = this.#state.mapTimeline;
this.#view.icTrack.data = this.#state.icTimeline;
}
switchTheme(event) {
document.documentElement.dataset.theme =
event.target.checked ? 'light' : 'dark';
if(this.fileLoaded) {
document.documentElement.dataset.theme = event.target.checked
? "light"
: "dark";
if (this.fileLoaded) {
this.refreshTimelineTrackView();
}
}
}
export {App};
export { App };
<!-- Copyright 2020 the V8 project authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<head>
<link href="./index.css" rel="stylesheet">
</head>
<style>
#mapDetails {
font-family: monospace;
white-space: pre;
overflow-x: scroll;
}
#mapDetails {
overflow-x: scroll;
overflow-y: scroll;
height: 100px;
}
</style>
<div id="container">
<div class="panel">
<h4>Map Details</h4>
<section id="mapDetails"></section>
</div>
<div class="panel">
<h4>Map Details</h4>
<section id="mapDetails"></section>
</div>
<!-- Copyright 2020 the V8 project authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<head>
<link href="./index.css" rel="stylesheet">
</head>
<style>
#transitionView {
overflow-x: scroll;
white-space: nowrap;
min-height: 50px;
max-height: 200px;
padding: 50px 0 0 0;
margin-top: -25px;
width: 100%;
}
.map {
width: 20px;
height: 20px;
display: inline-block;
border-radius: 50%;
background-color: var(--map-background-color);
border: 4px solid var(--surface-color);
font-size: 10px;
text-align: center;
line-height: 18px;
color: var(--on-surface-color);
vertical-align: top;
margin-top: -13px;
/* raise z-index */
position: relative;
z-index: 2;
cursor: pointer;
}
.map.selected {
#transitionView {
overflow-x: scroll;
white-space: nowrap;
min-height: 50px;
max-height: 200px;
padding: 50px 0 0 0;
margin-top: -25px;
width: 100%;
}
.map {
width: 20px;
height: 20px;
display: inline-block;
border-radius: 50%;
background-color: var(--map-background-color);
border: 4px solid var(--surface-color);
font-size: 10px;
text-align: center;
line-height: 18px;
color: var(--on-surface-color);
vertical-align: top;
margin-top: -13px;
/* raise z-index */
position: relative;
z-index: 2;
cursor: pointer;
}
.map.selected {
border-color: var(--map-background-color);
}
}
.transitions {
.transitions {
display: inline-block;
margin-left: -15px;
}
.transition {
min-height: 55px;
margin: 0 0 -2px 2px;
}
/* gray out deprecated transitions */
.deprecated > .transitionEdge,
.deprecated > .map {
opacity: 0.5;
}
.deprecated > .transition {
border-color: rgba(0, 0, 0, 0.5);
}
/* Show a border for all but the first transition */
.transition:nth-of-type(2),
.transition:nth-last-of-type(n+2) {
border-left: 2px solid;
margin-left: 0px;
}
/* special case for 2 transitions */
.transition:nth-last-of-type(1) {
border-left: none;
}
/* topmost transitions are not related */
#transitionView > .transition {
border-left: none;
}
/* topmost transition edge needs initial offset to be aligned */
#transitionView > .transition > .transitionEdge {
margin-left: 13px;
}
.transitionEdge {
height: 2px;
width: 80px;
display: inline-block;
margin: 0 0 2px 0;
background-color: var(--map-background-color);
vertical-align: top;
padding-left: 15px;
}
.transitionLabel {
color: var(--on-surface-color);
transform: rotate(-15deg);
transform-origin: top left;
margin-top: -10px;
font-size: 10px;
white-space: normal;
word-break: break-all;
background-color: var(--surface-color);
}
.showSubtransitions {
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 10px solid var(--map-background-color);
cursor: zoom-in;
margin: 4px 0 0 4px;
}
.showSubtransitions.opened {
border-top: none;
border-bottom: 10px solid var(--map-background-color);
cursor: zoom-out;
}
#tooltip {
position: absolute;
width: 10px;
height: 10px;
background-color: var(--red);
pointer-events: none;
z-index: 100;
display: none;
}
#title {
padding-bottom: 20px;
}
}
.transition {
min-height: 55px;
margin: 0 0 -2px 2px;
}
/* gray out deprecated transitions */
.deprecated>.transitionEdge,
.deprecated>.map {
opacity: 0.5;
}
.deprecated>.transition {
border-color: rgba(0, 0, 0, 0.5);
}
/* Show a border for all but the first transition */
.transition:nth-of-type(2),
.transition:nth-last-of-type(n+2) {
border-left: 2px solid;
margin-left: 0px;
}
/* special case for 2 transitions */
.transition:nth-last-of-type(1) {
border-left: none;
}
/* topmost transitions are not related */
#transitionView>.transition {
border-left: none;
}
/* topmost transition edge needs initial offset to be aligned */
#transitionView>.transition>.transitionEdge {
margin-left: 13px;
}
.transitionEdge {
height: 2px;
width: 80px;
display: inline-block;
margin: 0 0 2px 0;
background-color: var(--map-background-color);
vertical-align: top;
padding-left: 15px;
}
.transitionLabel {
color: var(--on-surface-color);
transform: rotate(-15deg);
transform-origin: top left;
margin-top: -10px;
font-size: 10px;
white-space: normal;
word-break: break-all;
background-color: var(--surface-color);
}
.showSubtransitions {
width: 0;
height: 0;
border-left: 6px solid transparent;
border-right: 6px solid transparent;
border-top: 10px solid var(--map-background-color);
cursor: zoom-in;
margin: 4px 0 0 4px;
}
.showSubtransitions.opened {
border-top: none;
border-bottom: 10px solid var(--map-background-color);
cursor: zoom-out;
}
#tooltip {
position: absolute;
width: 10px;
height: 10px;
background-color: var(--red);
pointer-events: none;
z-index: 100;
display: none;
}
#title {
padding-bottom: 10px;
}
</style>
<div id="container">
<div class="panel">
<div id="title"><h4>Transitions</h4></div>
<div class="panel">
<div id="title">
<h4>Transitions</h4>
</div>
<section id="transitionView"></section>
<div id="tooltip">
<div id="tooltipContents"></div>
</div>
</div>
</div>
......@@ -2,47 +2,53 @@
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file. -->
<style>
@import "./index.css";
#stats {
display: flex;
height: 250px;
background-color: var(--surface-color);
padding: 10px 10px 10px 10px ;
margin: auto;
}
#stats table {
flex: 1;
padding-right: 50px;
max-height: 250px;
display: inline-block;
overflow-y: scroll;
}
#stats table td {
cursor: pointer;
}
#stats .transitionTable {
overflow-y: scroll;
}
#stats .transitionTable tr {
max-width: 200px;
}
#stats .transitionType {
text-align: right;
max-width: 380px;
}
#stats .transitionType tr td:nth-child(2) {
text-align: left;
}
#stats table thead td {
border-bottom: 1px var(--on-surface-color) dotted;
}
@import "./index.css";
#stats {
display: flex;
height: 250px;
background-color: var(--surface-color);
padding: 10px 10px 10px 10px;
margin: auto;
}
#stats table {
flex: 1;
padding-right: 50px;
max-height: 250px;
display: inline-block;
overflow-y: scroll;
}
#stats table td {
cursor: pointer;
}
#stats .transitionTable {
overflow-y: scroll;
}
#stats .transitionTable tr {
max-width: 200px;
}
#stats .transitionType {
text-align: right;
max-width: 380px;
}
#stats .transitionType tr td:nth-child(2) {
text-align: left;
}
#stats table thead td {
border-bottom: 1px var(--on-surface-color) dotted;
}
</style>
<div id="container">
<div class="panel">
<h2>Stats Panel</h2>
<h3>Stats</h3>
<section id="stats">
</section>
</div>
<div class="panel">
<h2>Stats Panel</h2>
<h3>Stats</h3>
<section id="stats">
</section>
</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