UNPKG

chrome-devtools-frontend

Version:
416 lines (390 loc) • 15.2 kB
// 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 type * as Platform from '../../../../core/platform/platform.js'; import * as Trace from '../../../../models/trace/trace.js'; import * as Extensions from '../../../../panels/timeline/extensions/extensions.js'; import * as EnvironmentHelpers from '../../../../testing/EnvironmentHelpers.js'; import * as TraceHelpers from '../../../../testing/TraceHelpers.js'; import * as PerfUI from '../../../legacy/components/perf_ui/perf_ui.js'; import * as ComponentSetup from '../../helpers/helpers.js'; await EnvironmentHelpers.initializeGlobalVars(); await ComponentSetup.ComponentServerSetup.setup(); const defaultGroupStyle = { height: 17, padding: 4, collapsible: false, color: 'black', backgroundColor: 'grey', nestingLevel: 0, itemsHeight: 17, }; /** * Render a basic flame chart with 3 events on the same level **/ function renderBasicExample() { class FakeProviderWithBasicEvents extends TraceHelpers.FakeFlameChartProvider { override timelineData(): PerfUI.FlameChart.FlameChartTimelineData|null { return PerfUI.FlameChart.FlameChartTimelineData.create({ entryLevels: [0, 0, 0, 1, 1, 1, 2, 2, 2], entryStartTimes: [5, 60, 80, 5, 60, 80, 5, 60, 80], entryTotalTimes: [50, 10, 10, 50, 10, 10, 50, 10, 10], groups: [ { name: 'Test Group 0' as Platform.UIString.LocalizedString, startLevel: 0, style: {...defaultGroupStyle, collapsible: true}, }, { name: 'Test Group 1' as Platform.UIString.LocalizedString, startLevel: 1, style: {...defaultGroupStyle, collapsible: true, color: 'red', backgroundColor: 'green'}, }, { name: 'Test Group 2' as Platform.UIString.LocalizedString, startLevel: 2, style: {...defaultGroupStyle, collapsible: true, color: 'blue', backgroundColor: 'yellow'}, }, ], }); } } const container = document.querySelector('div#basic'); if (!container) { throw new Error('No container'); } const delegate = new TraceHelpers.MockFlameChartDelegate(); const dataProvider = new FakeProviderWithBasicEvents(); const flameChart = new PerfUI.FlameChart.FlameChart(dataProvider, delegate); flameChart.markAsRoot(); flameChart.setWindowTimes(0, 100); flameChart.show(container); flameChart.update(); } /** * Render a flame chart with events with decorations. **/ function renderDecorationExample() { class FakeProviderWithDecorations extends TraceHelpers.FakeFlameChartProvider { override timelineData(): PerfUI.FlameChart.FlameChartTimelineData|null { return PerfUI.FlameChart.FlameChartTimelineData.create({ entryLevels: [0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 2], entryStartTimes: [5, 55, 70, 5, 30, 55, 75, 5, 10, 15, 20, 25], entryTotalTimes: [45, 10, 20, 20, 20, 5, 15, 4, 4, 4, 4, 1], entryDecorations: [ [ { type: PerfUI.FlameChart.FlameChartDecorationType.CANDY, startAtTime: Trace.Types.Timing.Micro(25_000), }, {type: PerfUI.FlameChart.FlameChartDecorationType.WARNING_TRIANGLE}, ], [{type: PerfUI.FlameChart.FlameChartDecorationType.WARNING_TRIANGLE}], [ {type: PerfUI.FlameChart.FlameChartDecorationType.HIDDEN_DESCENDANTS_ARROW}, {type: PerfUI.FlameChart.FlameChartDecorationType.WARNING_TRIANGLE}, ], [ { type: PerfUI.FlameChart.FlameChartDecorationType.CANDY, startAtTime: Trace.Types.Timing.Micro(15_000), }, ], [ { type: PerfUI.FlameChart.FlameChartDecorationType.CANDY, startAtTime: Trace.Types.Timing.Micro(10_000), }, {type: PerfUI.FlameChart.FlameChartDecorationType.HIDDEN_DESCENDANTS_ARROW}, ], [ {type: PerfUI.FlameChart.FlameChartDecorationType.HIDDEN_DESCENDANTS_ARROW}, ], [ { type: PerfUI.FlameChart.FlameChartDecorationType.CANDY, startAtTime: Trace.Types.Timing.Micro(10_000), }, {type: PerfUI.FlameChart.FlameChartDecorationType.HIDDEN_DESCENDANTS_ARROW}, {type: PerfUI.FlameChart.FlameChartDecorationType.WARNING_TRIANGLE}, ], [ {type: PerfUI.FlameChart.FlameChartDecorationType.HIDDEN_DESCENDANTS_ARROW}, ], [ {type: PerfUI.FlameChart.FlameChartDecorationType.HIDDEN_DESCENDANTS_ARROW}, {type: PerfUI.FlameChart.FlameChartDecorationType.WARNING_TRIANGLE}, ], [ { type: PerfUI.FlameChart.FlameChartDecorationType.CANDY, startAtTime: Trace.Types.Timing.Micro(1_000), }, {type: PerfUI.FlameChart.FlameChartDecorationType.HIDDEN_DESCENDANTS_ARROW}, ], [ { type: PerfUI.FlameChart.FlameChartDecorationType.CANDY, startAtTime: Trace.Types.Timing.Micro(1_000), }, {type: PerfUI.FlameChart.FlameChartDecorationType.HIDDEN_DESCENDANTS_ARROW}, {type: PerfUI.FlameChart.FlameChartDecorationType.WARNING_TRIANGLE}, ], [ { type: PerfUI.FlameChart.FlameChartDecorationType.WARNING_TRIANGLE, // This triangle should start 1/4 of hte event, and end at 3/4 of the event. customStartTime: Trace.Types.Timing.Micro(25_250), customEndTime: Trace.Types.Timing.Micro(25_750), }, ], ], groups: [{ name: 'Testing Candy Stripe, warning triangles and hidden descendants arrow decorations' as Platform.UIString.LocalizedString, startLevel: 0, style: defaultGroupStyle, }], }); } } const container = document.querySelector('div#decorations'); if (!container) { throw new Error('No container'); } const delegate = new TraceHelpers.MockFlameChartDelegate(); const dataProvider = new FakeProviderWithDecorations(); const flameChart = new PerfUI.FlameChart.FlameChart(dataProvider, delegate); flameChart.markAsRoot(); flameChart.setWindowTimes(0, 100); flameChart.show(container); flameChart.update(); } /** * Render a flame chart with nested track. **/ function renderNestedExample() { class FakeProviderWithNestedGroup extends TraceHelpers.FakeFlameChartProvider { override timelineData(): PerfUI.FlameChart.FlameChartTimelineData|null { return PerfUI.FlameChart.FlameChartTimelineData.create({ entryLevels: [0, 1, 2], entryStartTimes: [5, 5, 5], entryTotalTimes: [50, 50, 50], groups: [ { name: 'Test Group 0' as Platform.UIString.LocalizedString, startLevel: 0, style: {...defaultGroupStyle, collapsible: true}, }, { name: 'Test Nested Group 1' as Platform.UIString.LocalizedString, startLevel: 0, style: {...defaultGroupStyle, collapsible: true, color: 'red', backgroundColor: 'green'}, }, { name: 'Test Group 2' as Platform.UIString.LocalizedString, startLevel: 2, style: {...defaultGroupStyle, collapsible: true, color: 'blue', backgroundColor: 'yellow'}, }, ], }); } } const container = document.querySelector('div#nested'); if (!container) { throw new Error('No container'); } const delegate = new TraceHelpers.MockFlameChartDelegate(); const dataProvider = new FakeProviderWithNestedGroup(); const flameChart = new PerfUI.FlameChart.FlameChart(dataProvider, delegate); flameChart.markAsRoot(); flameChart.setWindowTimes(0, 100); flameChart.show(container); flameChart.update(); } /** * Render a flame chart with nested case and buttons to hide/unhide and reorder * tracks **/ function renderTrackCustomizationExample() { class FakeProviderWithBasicEvents extends TraceHelpers.FakeFlameChartProvider { override timelineData(): PerfUI.FlameChart.FlameChartTimelineData|null { return PerfUI.FlameChart.FlameChartTimelineData.create({ entryLevels: [0, 0, 1, 1, 2, 2, 3, 3], entryStartTimes: [5, 60, 5, 60, 5, 60], entryTotalTimes: [50, 10, 50, 10, 50, 10], groups: [ { name: 'Test Group 0' as Platform.UIString.LocalizedString, startLevel: 0, expanded: true, style: {...defaultGroupStyle, collapsible: true}, }, { name: 'Test Group 1' as Platform.UIString.LocalizedString, startLevel: 1, expanded: true, style: {...defaultGroupStyle, collapsible: true, color: 'red', backgroundColor: 'green'}, }, { name: 'Test Group 2' as Platform.UIString.LocalizedString, startLevel: 2, expanded: true, style: {...defaultGroupStyle, collapsible: true, color: 'blue', backgroundColor: 'yellow'}, }, { name: 'Test Group 3' as Platform.UIString.LocalizedString, startLevel: 2, expanded: true, style: {...defaultGroupStyle, nestingLevel: 1}, }, ], }); } } const container = document.querySelector('div#track-customization'); if (!container) { throw new Error('No container'); } const delegate = new TraceHelpers.MockFlameChartDelegate(); const dataProvider = new FakeProviderWithBasicEvents(); const flameChart = new PerfUI.FlameChart.FlameChart(dataProvider, delegate); flameChart.markAsRoot(); flameChart.setWindowTimes(0, 100); flameChart.show(container); flameChart.update(); const indexInput = document.querySelector('#indexOfTrack') as HTMLInputElement; const buttonHide = document.querySelector('#hide'); buttonHide?.addEventListener('click', () => { const index = Number(indexInput.value); flameChart.hideGroup(index); }); const buttonUnhide = document.querySelector('#unhide'); buttonUnhide?.addEventListener('click', () => { const index = Number(indexInput.value); flameChart.showGroup(index); }); const buttonForMoveUp = document.querySelector('#testForMoveUp'); buttonForMoveUp?.addEventListener('click', () => { const index = Number(indexInput.value); flameChart.moveGroupUp(index); }); const buttonForMoveDown = document.querySelector('#testForMoveDown'); buttonForMoveDown?.addEventListener('click', () => { const index = Number(indexInput.value); flameChart.moveGroupDown(index); }); } /** * Render a flame chart with event initiators of different sizes. * Some initiator and initiated events are hidden. **/ function renderInitiatorsExample() { class FakeProviderWithVariousTasksForInitiators extends TraceHelpers.FakeFlameChartProvider { override timelineData(): PerfUI.FlameChart.FlameChartTimelineData|null { return PerfUI.FlameChart.FlameChartTimelineData.create({ entryLevels: [0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 0, 1, 2, 3], entryStartTimes: [5, 5, 5, 15, 15, 15, 40, 40, 40, 55.4, 55.4, 55.4, 80, 80, 80, 17], entryTotalTimes: [6, 6, 6, 5, 5, 20, 15, 15, 15, 2, 2, 2, 10, 10, 10, 10], entryDecorations: [ [], [], [ {type: PerfUI.FlameChart.FlameChartDecorationType.HIDDEN_DESCENDANTS_ARROW}, ], [], [], [], [], [], [ {type: PerfUI.FlameChart.FlameChartDecorationType.HIDDEN_DESCENDANTS_ARROW}, ], [], [], [ {type: PerfUI.FlameChart.FlameChartDecorationType.HIDDEN_DESCENDANTS_ARROW}, ], [ {type: PerfUI.FlameChart.FlameChartDecorationType.HIDDEN_DESCENDANTS_ARROW}, ], ], initiatorsData: [ {initiatorIndex: 2, eventIndex: 3, isInitiatorHidden: true}, {initiatorIndex: 1, eventIndex: 13}, {initiatorIndex: 3, eventIndex: 6}, {initiatorIndex: 3, eventIndex: 8, isEntryHidden: true}, {initiatorIndex: 6, eventIndex: 11}, {initiatorIndex: 11, eventIndex: 12, isInitiatorHidden: true, isEntryHidden: true}, {initiatorIndex: 5, eventIndex: 15}, ], groups: [{ name: 'Testing initiators' as Platform.UIString.LocalizedString, startLevel: 0, style: defaultGroupStyle, }], }); } override maxStackDepth(): number { return 4; } } const container = document.querySelector('div#initiators'); if (!container) { throw new Error('No container'); } const delegate = new TraceHelpers.MockFlameChartDelegate(); const dataProvider = new FakeProviderWithVariousTasksForInitiators(); const flameChart = new PerfUI.FlameChart.FlameChart(dataProvider, delegate); flameChart.markAsRoot(); flameChart.setSelectedEntry(14); flameChart.setWindowTimes(0, 100); flameChart.show(container); flameChart.update(); } /** * Used to test the color palette for extension events */ function renderExtensionTrackExample() { const colorPalette = Trace.Types.Extensions.extensionPalette; const paletteLength = colorPalette.length; class FakeProviderWithExtensionColors extends TraceHelpers.FakeFlameChartProvider { override entryColor(entryIndex: number): string { const color = colorPalette[entryIndex % paletteLength]; return Extensions.ExtensionUI.extensionEntryColor( {args: {color}} as Trace.Types.Extensions.SyntheticExtensionEntry); } override maxStackDepth(): number { return paletteLength + 1; } override timelineData(): PerfUI.FlameChart.FlameChartTimelineData|null { return PerfUI.FlameChart.FlameChartTimelineData.create({ entryLevels: colorPalette.map((_, i) => i), entryStartTimes: colorPalette.map(() => 0), entryTotalTimes: colorPalette.map(() => 100), groups: [{ name: 'Testing extension palette' as Platform.UIString.LocalizedString, startLevel: 0, style: defaultGroupStyle, }], }); } } const container = document.querySelector('div#extension'); if (!container) { throw new Error('No container'); } const delegate = new TraceHelpers.MockFlameChartDelegate(); const dataProvider = new FakeProviderWithExtensionColors(); const flameChart = new PerfUI.FlameChart.FlameChart(dataProvider, delegate); flameChart.markAsRoot(); flameChart.setWindowTimes(0, 100); flameChart.show(container); flameChart.update(); } renderBasicExample(); renderDecorationExample(); renderNestedExample(); renderTrackCustomizationExample(); renderInitiatorsExample(); renderExtensionTrackExample();