mirror of
https://github.com/react/react-native-devtools-frontend.git
synced 2026-10-11 06:04:55 +08:00
Add timing types to TimelineOverviewCalculator
This CL updates the TimelineOverviewCalculator by moving it into its own file, and changing its types from `number` to the `MilliSeconds` type. This is important because the trace engine works primarily in microseconds, so if we just use the `number` type we could easily get into a confusing world where we are passing round numbers in different units. Bug: 1464206 Change-Id: I439c120c83950c2ca2cfa0c892b9f9065359dba7 Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/4777912 Reviewed-by: Nancy Li <nancyly@chromium.org> Commit-Queue: Jack Franklin <jacktfranklin@chromium.org>
This commit is contained in:
committed by
Devtools-frontend LUCI CQ
parent
76dc7d12fe
commit
5d07f613bd
@@ -2030,6 +2030,7 @@ grd_files_debug_sources = [
|
||||
"front_end/ui/legacy/components/perf_ui/OverviewGrid.js",
|
||||
"front_end/ui/legacy/components/perf_ui/PieChart.js",
|
||||
"front_end/ui/legacy/components/perf_ui/TimelineGrid.js",
|
||||
"front_end/ui/legacy/components/perf_ui/TimelineOverviewCalculator.js",
|
||||
"front_end/ui/legacy/components/perf_ui/TimelineOverviewPane.js",
|
||||
"front_end/ui/legacy/components/perf_ui/chartViewport.css.legacy.js",
|
||||
"front_end/ui/legacy/components/perf_ui/filmStripView.css.legacy.js",
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
|
||||
import type * as Common from '../../core/common/common.js';
|
||||
import * as SDK from '../../core/sdk/sdk.js';
|
||||
import * as TraceEngine from '../../models/trace/trace.js';
|
||||
import * as Coordinator from '../../ui/components/render_coordinator/render_coordinator.js';
|
||||
import * as PerfUI from '../../ui/legacy/components/perf_ui/perf_ui.js';
|
||||
import * as ThemeSupport from '../../ui/legacy/theme_support/theme_support.js';
|
||||
import * as Coordinator from '../../ui/components/render_coordinator/render_coordinator.js';
|
||||
|
||||
import {NetworkLogView} from './NetworkLogView.js';
|
||||
import {NetworkTimeBoundary} from './NetworkTimeCalculator.js';
|
||||
@@ -102,8 +103,8 @@ export class NetworkOverview extends PerfUI.TimelineOverviewPane.TimelineOvervie
|
||||
this.onResize();
|
||||
}
|
||||
|
||||
override calculator(): PerfUI.TimelineOverviewPane.TimelineOverviewCalculator {
|
||||
return super.calculator() as PerfUI.TimelineOverviewPane.TimelineOverviewCalculator;
|
||||
override calculator(): PerfUI.TimelineOverviewCalculator.TimelineOverviewCalculator {
|
||||
return super.calculator() as PerfUI.TimelineOverviewCalculator.TimelineOverviewCalculator;
|
||||
}
|
||||
|
||||
override onResize(): void {
|
||||
@@ -147,7 +148,10 @@ export class NetworkOverview extends PerfUI.TimelineOverviewPane.TimelineOvervie
|
||||
this.span *= 1.25;
|
||||
}
|
||||
|
||||
calculator.setBounds(calculator.minimumBoundary(), calculator.minimumBoundary() + this.span);
|
||||
calculator.setBounds(
|
||||
calculator.minimumBoundary(),
|
||||
TraceEngine.Types.Timing.MilliSeconds(calculator.minimumBoundary() + this.span));
|
||||
|
||||
this.lastBoundary = new NetworkTimeBoundary(calculator.minimumBoundary(), calculator.maximumBoundary());
|
||||
}
|
||||
|
||||
@@ -172,8 +176,8 @@ export class NetworkOverview extends PerfUI.TimelineOverviewPane.TimelineOvervie
|
||||
if (endTime === Number.MAX_VALUE) {
|
||||
endTime = calculator.maximumBoundary();
|
||||
}
|
||||
const startX = calculator.computePosition(startTime);
|
||||
const endX = calculator.computePosition(endTime) + 1;
|
||||
const startX = calculator.computePosition(TraceEngine.Types.Timing.MilliSeconds(startTime));
|
||||
const endX = calculator.computePosition(TraceEngine.Types.Timing.MilliSeconds(endTime)) + 1;
|
||||
context.fillRect(startX, y, endX - startX, _bandHeight);
|
||||
context.strokeRect(startX, y, endX - startX, _bandHeight);
|
||||
}
|
||||
@@ -232,8 +236,10 @@ export class NetworkOverview extends PerfUI.TimelineOverviewPane.TimelineOvervie
|
||||
|
||||
context.fillStyle = ThemeSupport.ThemeSupport.instance().getComputedValue('--legacy-selection-bg-color');
|
||||
|
||||
const start = timeRanges[0].start * 1000;
|
||||
const end = timeRanges[0].end * 1000;
|
||||
// The network overview works in seconds, but the calcululator deals in
|
||||
// milliseconds, hence the multiplication by 1000.
|
||||
const start = TraceEngine.Types.Timing.MilliSeconds(timeRanges[0].start * 1000);
|
||||
const end = TraceEngine.Types.Timing.MilliSeconds(timeRanges[0].end * 1000);
|
||||
context.fillRect(
|
||||
calculator.computePosition(start) - borderSize, y - size / 2 - borderSize,
|
||||
calculator.computePosition(end) - calculator.computePosition(start) + 1 + 2 * borderSize, size * borderSize);
|
||||
@@ -246,8 +252,8 @@ export class NetworkOverview extends PerfUI.TimelineOverviewPane.TimelineOvervie
|
||||
ThemeSupport.ThemeSupport.instance().getComputedValue(RequestTimeRangeNameToColor[type]);
|
||||
context.lineWidth = size;
|
||||
|
||||
const start = timeRanges[j].start * 1000;
|
||||
const end = timeRanges[j].end * 1000;
|
||||
const start = TraceEngine.Types.Timing.MilliSeconds(timeRanges[j].start * 1000);
|
||||
const end = TraceEngine.Types.Timing.MilliSeconds(timeRanges[j].end * 1000);
|
||||
context.moveTo(calculator.computePosition(start) - 0, y);
|
||||
context.lineTo(calculator.computePosition(end) + 1, y);
|
||||
context.stroke();
|
||||
@@ -260,7 +266,9 @@ export class NetworkOverview extends PerfUI.TimelineOverviewPane.TimelineOvervie
|
||||
context.beginPath();
|
||||
context.strokeStyle = ThemeSupport.ThemeSupport.instance().getComputedValue(NetworkLogView.getDCLEventColor());
|
||||
for (let i = this.domContentLoadedEvents.length - 1; i >= 0; --i) {
|
||||
const x = Math.round(calculator.computePosition(this.domContentLoadedEvents[i])) + 0.5;
|
||||
const position =
|
||||
calculator.computePosition(TraceEngine.Types.Timing.MilliSeconds(this.domContentLoadedEvents[i]));
|
||||
const x = Math.round(position) + 0.5;
|
||||
context.moveTo(x, 0);
|
||||
context.lineTo(x, height);
|
||||
}
|
||||
@@ -269,7 +277,8 @@ export class NetworkOverview extends PerfUI.TimelineOverviewPane.TimelineOvervie
|
||||
context.beginPath();
|
||||
context.strokeStyle = ThemeSupport.ThemeSupport.instance().getComputedValue(NetworkLogView.getLoadEventColor());
|
||||
for (let i = this.loadEvents.length - 1; i >= 0; --i) {
|
||||
const x = Math.round(calculator.computePosition(this.loadEvents[i])) + 0.5;
|
||||
const position = calculator.computePosition(TraceEngine.Types.Timing.MilliSeconds(this.loadEvents[i]));
|
||||
const x = Math.round(position) + 0.5;
|
||||
context.moveTo(x, 0);
|
||||
context.lineTo(x, height);
|
||||
}
|
||||
@@ -279,7 +288,8 @@ export class NetworkOverview extends PerfUI.TimelineOverviewPane.TimelineOvervie
|
||||
context.lineWidth = 2;
|
||||
context.beginPath();
|
||||
context.strokeStyle = ThemeSupport.ThemeSupport.instance().getComputedValue('--network-frame-divider-color');
|
||||
const x = Math.round(calculator.computePosition(this.selectedFilmStripTime));
|
||||
const timeInMilliseconds = TraceEngine.Types.Timing.MilliSeconds(this.selectedFilmStripTime);
|
||||
const x = Math.round(calculator.computePosition(timeInMilliseconds));
|
||||
context.moveTo(x, 0);
|
||||
context.lineTo(x, height);
|
||||
context.stroke();
|
||||
|
||||
@@ -49,15 +49,13 @@ import * as MobileThrottling from '../mobile_throttling/mobile_throttling.js';
|
||||
import * as Search from '../search/search.js';
|
||||
|
||||
import {BlockedURLsPane} from './BlockedURLsPane.js';
|
||||
|
||||
import {Events, type RequestActivatedEvent} from './NetworkDataGridNode.js';
|
||||
import {NetworkItemView} from './NetworkItemView.js';
|
||||
import {NetworkLogView} from './NetworkLogView.js';
|
||||
import {NetworkOverview} from './NetworkOverview.js';
|
||||
import networkPanelStyles from './networkPanel.css.js';
|
||||
import {NetworkSearchScope} from './NetworkSearchScope.js';
|
||||
|
||||
import {NetworkTransferTimeCalculator, type NetworkTimeCalculator} from './NetworkTimeCalculator.js';
|
||||
import {type NetworkTimeCalculator, NetworkTransferTimeCalculator} from './NetworkTimeCalculator.js';
|
||||
|
||||
const UIStrings = {
|
||||
/**
|
||||
@@ -780,7 +778,9 @@ export class NetworkPanel extends UI.Panel.Panel implements UI.ContextMenu.Provi
|
||||
const request = event.data;
|
||||
this.calculator.updateBoundaries(request);
|
||||
// FIXME: Unify all time units across the frontend!
|
||||
this.overviewPane.setBounds(this.calculator.minimumBoundary() * 1000, this.calculator.maximumBoundary() * 1000);
|
||||
this.overviewPane.setBounds(
|
||||
TraceEngine.Types.Timing.MilliSeconds(this.calculator.minimumBoundary() * 1000),
|
||||
TraceEngine.Types.Timing.MilliSeconds(this.calculator.maximumBoundary() * 1000));
|
||||
this.networkOverview.updateRequest(request);
|
||||
this.overviewPane.scheduleUpdate();
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ export class TimelineMiniMap extends
|
||||
this.#overviewComponent.reset();
|
||||
}
|
||||
|
||||
setBounds(min: number, max: number): void {
|
||||
setBounds(min: TraceEngine.Types.Timing.MilliSeconds, max: TraceEngine.Types.Timing.MilliSeconds): void {
|
||||
this.#overviewComponent.setBounds(min, max);
|
||||
}
|
||||
|
||||
|
||||
@@ -1098,7 +1098,8 @@ export class TimelinePanel extends UI.Panel.Panel implements Client, TimelineMod
|
||||
if (model && this.performanceModel) {
|
||||
this.performanceModel.addEventListener(Events.WindowChanged, this.onModelWindowChanged, this);
|
||||
this.#minimapComponent.setBounds(
|
||||
model.timelineModel().minimumRecordTime(), model.timelineModel().maximumRecordTime());
|
||||
TraceEngine.Types.Timing.MilliSeconds(model.timelineModel().minimumRecordTime()),
|
||||
TraceEngine.Types.Timing.MilliSeconds(model.timelineModel().maximumRecordTime()));
|
||||
PerfUI.LineLevelProfile.Performance.instance().reset();
|
||||
for (const profile of model.timelineModel().cpuProfiles()) {
|
||||
PerfUI.LineLevelProfile.Performance.instance().appendCPUProfile(profile.cpuProfileData, profile.target);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
import * as EnvironmentHelpers from '../../../../../test/unittests/front_end/helpers/EnvironmentHelpers.js';
|
||||
import * as TraceLoader from '../../../../../test/unittests/front_end/helpers/TraceLoader.js';
|
||||
import * as TraceEngine from '../../../../models/trace/trace.js';
|
||||
import * as Timeline from '../../../../panels/timeline/timeline.js';
|
||||
import * as ComponentSetup from '../../helpers/helpers.js';
|
||||
|
||||
@@ -28,7 +29,10 @@ async function renderMiniMap(containerSelector: string, options: {showMemory: bo
|
||||
|
||||
const models = await TraceLoader.TraceLoader.allModels(null, fileName);
|
||||
|
||||
minimap.setBounds(models.timelineModel.minimumRecordTime(), models.timelineModel.maximumRecordTime());
|
||||
minimap.setBounds(
|
||||
TraceEngine.Types.Timing.MilliSeconds(models.timelineModel.minimumRecordTime()),
|
||||
TraceEngine.Types.Timing.MilliSeconds(models.timelineModel.maximumRecordTime()),
|
||||
);
|
||||
minimap.setWindowTimes(models.performanceModel.window().left, models.performanceModel.window().right);
|
||||
minimap.setData({
|
||||
traceParsedData: models.traceParsedData,
|
||||
|
||||
@@ -39,6 +39,7 @@ devtools_module("perf_ui") {
|
||||
"OverviewGrid.ts",
|
||||
"PieChart.ts",
|
||||
"TimelineGrid.ts",
|
||||
"TimelineOverviewCalculator.ts",
|
||||
"TimelineOverviewPane.ts",
|
||||
]
|
||||
|
||||
|
||||
@@ -37,10 +37,9 @@ import * as UI from '../../legacy.js';
|
||||
import * as ThemeSupport from '../../theme_support/theme_support.js';
|
||||
|
||||
import {ChartViewport, type ChartViewportDelegate} from './ChartViewport.js';
|
||||
|
||||
import {TimelineGrid, type Calculator} from './TimelineGrid.js';
|
||||
import flameChartStyles from './flameChart.css.legacy.js';
|
||||
import {DEFAULT_FONT_SIZE, getFontFamilyForCanvas} from './Font.js';
|
||||
import {type Calculator, TimelineGrid} from './TimelineGrid.js';
|
||||
|
||||
const UIStrings = {
|
||||
/**
|
||||
@@ -2090,20 +2089,20 @@ export class FlameChart extends Common.ObjectWrapper.eventMixin<EventTypes, type
|
||||
return this.dataProvider.formatValue(value - this.zeroTime(), precision);
|
||||
}
|
||||
|
||||
maximumBoundary(): number {
|
||||
return this.chartViewport.windowRightTime();
|
||||
maximumBoundary(): TraceEngine.Types.Timing.MilliSeconds {
|
||||
return TraceEngine.Types.Timing.MilliSeconds(this.chartViewport.windowRightTime());
|
||||
}
|
||||
|
||||
minimumBoundary(): number {
|
||||
return this.chartViewport.windowLeftTime();
|
||||
minimumBoundary(): TraceEngine.Types.Timing.MilliSeconds {
|
||||
return TraceEngine.Types.Timing.MilliSeconds(this.chartViewport.windowLeftTime());
|
||||
}
|
||||
|
||||
zeroTime(): number {
|
||||
return this.dataProvider.minimumBoundary();
|
||||
zeroTime(): TraceEngine.Types.Timing.MilliSeconds {
|
||||
return TraceEngine.Types.Timing.MilliSeconds(this.dataProvider.minimumBoundary());
|
||||
}
|
||||
|
||||
boundarySpan(): number {
|
||||
return this.maximumBoundary() - this.minimumBoundary();
|
||||
boundarySpan(): TraceEngine.Types.Timing.MilliSeconds {
|
||||
return TraceEngine.Types.Timing.MilliSeconds(this.maximumBoundary() - this.minimumBoundary());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,11 +31,12 @@
|
||||
import * as Common from '../../../../core/common/common.js';
|
||||
import * as i18n from '../../../../core/i18n/i18n.js';
|
||||
import * as Platform from '../../../../core/platform/platform.js';
|
||||
import * as TraceEngine from '../../../../models/trace/trace.js';
|
||||
import * as UI from '../../legacy.js';
|
||||
import * as ThemeSupport from '../../theme_support/theme_support.js';
|
||||
|
||||
import {TimelineGrid, type Calculator} from './TimelineGrid.js';
|
||||
import overviewGridStyles from './overviewGrid.css.legacy.js';
|
||||
import {type Calculator, TimelineGrid} from './TimelineGrid.js';
|
||||
|
||||
const UIStrings = {
|
||||
/**
|
||||
@@ -393,8 +394,10 @@ export class Window extends Common.ObjectWrapper.ObjectWrapper<EventTypes> {
|
||||
if (!this.calculator) {
|
||||
return;
|
||||
}
|
||||
const startValue = this.calculator.formatValue(this.getRawSliderValue(/* leftSlider */ true));
|
||||
const endValue = this.calculator.formatValue(this.getRawSliderValue(/* leftSlider */ false));
|
||||
const startValue = this.calculator.formatValue(
|
||||
TraceEngine.Types.Timing.MilliSeconds(this.getRawSliderValue(/* leftSlider */ true)));
|
||||
const endValue = this.calculator.formatValue(
|
||||
TraceEngine.Types.Timing.MilliSeconds(this.getRawSliderValue(/* leftSlider */ false)));
|
||||
UI.ARIAUtils.setAriaValueText(this.leftResizeElement, String(startValue));
|
||||
UI.ARIAUtils.setAriaValueText(this.rightResizeElement, String(endValue));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
// Copyright 2023 The Chromium Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
import * as i18n from '../../../../core/i18n/i18n.js';
|
||||
import * as TraceEngine from '../../../../models/trace/trace.js';
|
||||
|
||||
import {type Calculator} from './TimelineGrid.js';
|
||||
|
||||
export class TimelineOverviewCalculator implements Calculator {
|
||||
#minimumBoundary: TraceEngine.Types.Timing.MilliSeconds = TraceEngine.Types.Timing.MilliSeconds(0);
|
||||
#maximumBoundary: TraceEngine.Types.Timing.MilliSeconds = TraceEngine.Types.Timing.MilliSeconds(100);
|
||||
|
||||
private workingArea!: number;
|
||||
private navStartTimes?: readonly TraceEngine.Types.TraceEvents.TraceEventNavigationStart[];
|
||||
|
||||
computePosition(time: TraceEngine.Types.Timing.MilliSeconds): number {
|
||||
return (time - this.#minimumBoundary) / this.boundarySpan() * this.workingArea;
|
||||
}
|
||||
|
||||
positionToTime(position: number): number {
|
||||
return position / this.workingArea * this.boundarySpan() + this.#minimumBoundary;
|
||||
}
|
||||
|
||||
setBounds(
|
||||
minimumBoundary: TraceEngine.Types.Timing.MilliSeconds,
|
||||
maximumBoundary: TraceEngine.Types.Timing.MilliSeconds): void {
|
||||
this.#minimumBoundary = minimumBoundary;
|
||||
this.#maximumBoundary = maximumBoundary;
|
||||
}
|
||||
|
||||
setNavStartTimes(navStartTimes: readonly TraceEngine.Types.TraceEvents.TraceEventNavigationStart[]): void {
|
||||
this.navStartTimes = navStartTimes;
|
||||
}
|
||||
|
||||
setDisplayWidth(clientWidth: number): void {
|
||||
this.workingArea = clientWidth;
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this.setBounds(
|
||||
TraceEngine.Types.Timing.MilliSeconds(0),
|
||||
TraceEngine.Types.Timing.MilliSeconds(100),
|
||||
);
|
||||
}
|
||||
|
||||
formatValue(value: number, precision?: number): string {
|
||||
// If there are nav start times the value needs to be remapped.
|
||||
if (this.navStartTimes) {
|
||||
// Find the latest possible nav start time which is considered earlier
|
||||
// than the value passed through.
|
||||
for (let i = this.navStartTimes.length - 1; i >= 0; i--) {
|
||||
const startTimeMilliseconds = TraceEngine.Helpers.Timing.microSecondsToMilliseconds(
|
||||
this.navStartTimes[i].ts,
|
||||
);
|
||||
|
||||
if (value > startTimeMilliseconds) {
|
||||
value -= (startTimeMilliseconds - this.zeroTime());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i18n.TimeUtilities.preciseMillisToString(value - this.zeroTime(), precision);
|
||||
}
|
||||
|
||||
maximumBoundary(): TraceEngine.Types.Timing.MilliSeconds {
|
||||
return this.#maximumBoundary;
|
||||
}
|
||||
|
||||
minimumBoundary(): TraceEngine.Types.Timing.MilliSeconds {
|
||||
return this.#minimumBoundary;
|
||||
}
|
||||
|
||||
zeroTime(): TraceEngine.Types.Timing.MilliSeconds {
|
||||
return this.#minimumBoundary;
|
||||
}
|
||||
|
||||
boundarySpan(): TraceEngine.Types.Timing.MilliSeconds {
|
||||
return TraceEngine.Types.Timing.MilliSeconds(this.#maximumBoundary - this.#minimumBoundary);
|
||||
}
|
||||
}
|
||||
@@ -29,12 +29,11 @@
|
||||
*/
|
||||
|
||||
import * as Common from '../../../../core/common/common.js';
|
||||
import * as i18n from '../../../../core/i18n/i18n.js';
|
||||
import * as TraceEngine from '../../../../models/trace/trace.js';
|
||||
import * as UI from '../../legacy.js';
|
||||
|
||||
import {Events as OverviewGridEvents, OverviewGrid, type WindowChangedWithPositionEvent} from './OverviewGrid.js';
|
||||
import {type Calculator} from './TimelineGrid.js';
|
||||
import {TimelineOverviewCalculator} from './TimelineOverviewCalculator.js';
|
||||
import timelineOverviewInfoStyles from './timelineOverviewInfo.css.js';
|
||||
|
||||
export class TimelineOverviewPane extends Common.ObjectWrapper.eventMixin<EventTypes, typeof UI.Widget.VBox>(
|
||||
@@ -141,7 +140,9 @@ export class TimelineOverviewPane extends Common.ObjectWrapper.eventMixin<EventT
|
||||
this.update();
|
||||
}
|
||||
|
||||
setBounds(minimumBoundary: number, maximumBoundary: number): void {
|
||||
setBounds(
|
||||
minimumBoundary: TraceEngine.Types.Timing.MilliSeconds,
|
||||
maximumBoundary: TraceEngine.Types.Timing.MilliSeconds): void {
|
||||
this.overviewCalculator.setBounds(minimumBoundary, maximumBoundary);
|
||||
this.overviewGrid.setResizeEnabled(true);
|
||||
this.cursorEnabled = true;
|
||||
@@ -178,7 +179,7 @@ export class TimelineOverviewPane extends Common.ObjectWrapper.eventMixin<EventT
|
||||
const filteredMarkers = new Map<number, Element>();
|
||||
for (const time of this.markers.keys()) {
|
||||
const marker = this.markers.get(time) as HTMLElement;
|
||||
const position = Math.round(this.overviewCalculator.computePosition(time));
|
||||
const position = Math.round(this.overviewCalculator.computePosition(TraceEngine.Types.Timing.MilliSeconds(time)));
|
||||
// Limit the number of markers to one per pixel.
|
||||
if (filteredMarkers.has(position)) {
|
||||
continue;
|
||||
@@ -269,78 +270,6 @@ export type EventTypes = {
|
||||
[Events.WindowChanged]: WindowChangedEvent,
|
||||
};
|
||||
|
||||
export class TimelineOverviewCalculator implements Calculator {
|
||||
private minimumBoundaryInternal!: number;
|
||||
private maximumBoundaryInternal!: number;
|
||||
private workingArea!: number;
|
||||
private navStartTimes?: readonly TraceEngine.Types.TraceEvents.TraceEventNavigationStart[];
|
||||
|
||||
constructor() {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
computePosition(time: number): number {
|
||||
return (time - this.minimumBoundaryInternal) / this.boundarySpan() * this.workingArea;
|
||||
}
|
||||
|
||||
positionToTime(position: number): number {
|
||||
return position / this.workingArea * this.boundarySpan() + this.minimumBoundaryInternal;
|
||||
}
|
||||
|
||||
setBounds(minimumBoundary: number, maximumBoundary: number): void {
|
||||
this.minimumBoundaryInternal = minimumBoundary;
|
||||
this.maximumBoundaryInternal = maximumBoundary;
|
||||
}
|
||||
|
||||
setNavStartTimes(navStartTimes: readonly TraceEngine.Types.TraceEvents.TraceEventNavigationStart[]): void {
|
||||
this.navStartTimes = navStartTimes;
|
||||
}
|
||||
|
||||
setDisplayWidth(clientWidth: number): void {
|
||||
this.workingArea = clientWidth;
|
||||
}
|
||||
|
||||
reset(): void {
|
||||
this.setBounds(0, 100);
|
||||
}
|
||||
|
||||
formatValue(value: number, precision?: number): string {
|
||||
// If there are nav start times the value needs to be remapped.
|
||||
if (this.navStartTimes) {
|
||||
// Find the latest possible nav start time which is considered earlier
|
||||
// than the value passed through.
|
||||
for (let i = this.navStartTimes.length - 1; i >= 0; i--) {
|
||||
const startTimeMilliseconds = TraceEngine.Helpers.Timing.microSecondsToMilliseconds(
|
||||
this.navStartTimes[i].ts,
|
||||
);
|
||||
|
||||
if (value > startTimeMilliseconds) {
|
||||
value -= (startTimeMilliseconds - this.zeroTime());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return i18n.TimeUtilities.preciseMillisToString(value - this.zeroTime(), precision);
|
||||
}
|
||||
|
||||
maximumBoundary(): number {
|
||||
return this.maximumBoundaryInternal;
|
||||
}
|
||||
|
||||
minimumBoundary(): number {
|
||||
return this.minimumBoundaryInternal;
|
||||
}
|
||||
|
||||
zeroTime(): number {
|
||||
return this.minimumBoundaryInternal;
|
||||
}
|
||||
|
||||
boundarySpan(): number {
|
||||
return this.maximumBoundaryInternal - this.minimumBoundaryInternal;
|
||||
}
|
||||
}
|
||||
|
||||
export interface TimelineOverview {
|
||||
show(parentElement: Element, insertBefore?: Element|null): void;
|
||||
update(): void;
|
||||
|
||||
@@ -13,6 +13,7 @@ import * as NetworkPriorities from './NetworkPriorities.js';
|
||||
import * as OverviewGrid from './OverviewGrid.js';
|
||||
import * as PieChart from './PieChart.js';
|
||||
import * as TimelineGrid from './TimelineGrid.js';
|
||||
import * as TimelineOverviewCalculator from './TimelineOverviewCalculator.js';
|
||||
import * as TimelineOverviewPane from './TimelineOverviewPane.js';
|
||||
|
||||
export {
|
||||
@@ -27,5 +28,6 @@ export {
|
||||
OverviewGrid,
|
||||
PieChart,
|
||||
TimelineGrid,
|
||||
TimelineOverviewCalculator,
|
||||
TimelineOverviewPane,
|
||||
};
|
||||
|
||||
@@ -3,13 +3,12 @@
|
||||
// found in the LICENSE file.
|
||||
|
||||
import type * as Common from '../../../../../front_end/core/common/common.js';
|
||||
import * as Network from '../../../../../front_end/panels/network/network.js';
|
||||
import type * as Platform from '../../../../../front_end/core/platform/platform.js';
|
||||
import {assertNotNullOrUndefined} from '../../../../../front_end/core/platform/platform.js';
|
||||
import * as SDK from '../../../../../front_end/core/sdk/sdk.js';
|
||||
import * as Network from '../../../../../front_end/panels/network/network.js';
|
||||
import * as Coordinator from '../../../../../front_end/ui/components/render_coordinator/render_coordinator.js';
|
||||
import type * as PerfUI from '../../../../../front_end/ui/legacy/components/perf_ui/perf_ui.js';
|
||||
|
||||
import {assertNotNullOrUndefined} from '../../../../../front_end/core/platform/platform.js';
|
||||
import {createTarget} from '../../helpers/EnvironmentHelpers.js';
|
||||
import {describeWithMockConnection} from '../../helpers/MockConnection.js';
|
||||
|
||||
@@ -40,7 +39,8 @@ describeWithMockConnection('NetworkOverview', () => {
|
||||
zeroTime: sinon.stub(),
|
||||
boundarySpan: sinon.stub(),
|
||||
};
|
||||
networkOverview.setCalculator(calculator as unknown as PerfUI.TimelineOverviewPane.TimelineOverviewCalculator);
|
||||
networkOverview.setCalculator(
|
||||
calculator as unknown as PerfUI.TimelineOverviewCalculator.TimelineOverviewCalculator);
|
||||
networkOverview.markAsRoot();
|
||||
networkOverview.show(document.body);
|
||||
const resourceTreeModel = target.model(SDK.ResourceTreeModel.ResourceTreeModel);
|
||||
|
||||
+16
-14
@@ -2,49 +2,51 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import type * as TraceEngine from '../../../../../../../front_end/models/trace/trace.js';
|
||||
import * as TraceEngine from '../../../../../../../front_end/models/trace/trace.js';
|
||||
import * as PerfUI from '../../../../../../../front_end/ui/legacy/components/perf_ui/perf_ui.js';
|
||||
import {describeWithLocale} from '../../../../helpers/EnvironmentHelpers.js';
|
||||
|
||||
const {assert} = chai;
|
||||
|
||||
const {MilliSeconds} = TraceEngine.Types.Timing;
|
||||
|
||||
describeWithLocale('TimelineOverviewCalculator', () => {
|
||||
it('can calculate pixels for a given time', async () => {
|
||||
const calculator = new PerfUI.TimelineOverviewPane.TimelineOverviewCalculator();
|
||||
const calculator = new PerfUI.TimelineOverviewCalculator.TimelineOverviewCalculator();
|
||||
calculator.setDisplayWidth(200);
|
||||
calculator.setBounds(0, 100);
|
||||
calculator.setBounds(MilliSeconds(0), MilliSeconds(100));
|
||||
|
||||
assert.strictEqual(calculator.computePosition(50), 100);
|
||||
assert.strictEqual(calculator.computePosition(MilliSeconds(50)), 100);
|
||||
});
|
||||
|
||||
it('can calculate the time position for a pixel value', async () => {
|
||||
const calculator = new PerfUI.TimelineOverviewPane.TimelineOverviewCalculator();
|
||||
const calculator = new PerfUI.TimelineOverviewCalculator.TimelineOverviewCalculator();
|
||||
calculator.setDisplayWidth(200);
|
||||
calculator.setBounds(0, 100);
|
||||
calculator.setBounds(MilliSeconds(0), MilliSeconds(100));
|
||||
|
||||
assert.strictEqual(calculator.positionToTime(100), 50);
|
||||
});
|
||||
|
||||
it('formats time values', async () => {
|
||||
const calculator = new PerfUI.TimelineOverviewPane.TimelineOverviewCalculator();
|
||||
const calculator = new PerfUI.TimelineOverviewCalculator.TimelineOverviewCalculator();
|
||||
calculator.setDisplayWidth(200);
|
||||
calculator.setBounds(0, 100);
|
||||
calculator.setBounds(MilliSeconds(0), MilliSeconds(100));
|
||||
const result = calculator.formatValue(55.234);
|
||||
assert.deepEqual(result, '55\u00A0ms');
|
||||
});
|
||||
|
||||
it('formats time values with custom precision', async () => {
|
||||
const calculator = new PerfUI.TimelineOverviewPane.TimelineOverviewCalculator();
|
||||
const calculator = new PerfUI.TimelineOverviewCalculator.TimelineOverviewCalculator();
|
||||
calculator.setDisplayWidth(200);
|
||||
calculator.setBounds(0, 100);
|
||||
calculator.setBounds(MilliSeconds(0), MilliSeconds(100));
|
||||
const result = calculator.formatValue(55.234, 2);
|
||||
assert.deepEqual(result, '55.23\u00A0ms');
|
||||
});
|
||||
|
||||
it('adjusts times based on navigaton start times', async () => {
|
||||
const calculator = new PerfUI.TimelineOverviewPane.TimelineOverviewCalculator();
|
||||
const calculator = new PerfUI.TimelineOverviewCalculator.TimelineOverviewCalculator();
|
||||
calculator.setDisplayWidth(200);
|
||||
calculator.setBounds(0, 100);
|
||||
calculator.setBounds(MilliSeconds(0), MilliSeconds(100));
|
||||
const fakeNavStart = {
|
||||
// TraceEngine events are in microseconds
|
||||
ts: 100_000,
|
||||
@@ -56,9 +58,9 @@ describeWithLocale('TimelineOverviewCalculator', () => {
|
||||
});
|
||||
|
||||
it('returns the correct range', async () => {
|
||||
const calculator = new PerfUI.TimelineOverviewPane.TimelineOverviewCalculator();
|
||||
const calculator = new PerfUI.TimelineOverviewCalculator.TimelineOverviewCalculator();
|
||||
calculator.setDisplayWidth(200);
|
||||
calculator.setBounds(0, 100);
|
||||
calculator.setBounds(MilliSeconds(0), MilliSeconds(100));
|
||||
assert.strictEqual(calculator.boundarySpan(), 100);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user