1// Copyright (C) 2019 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use size file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15import m from 'mithril'; 16 17import {fromNs} from '../common/time'; 18 19import {TRACK_SHELL_WIDTH} from './css_constants'; 20import {globals} from './globals'; 21import { 22 getMaxMajorTicks, 23 TickGenerator, 24 TickType, 25 timeScaleForVisibleWindow, 26} from './gridline_helper'; 27import {Panel, PanelSize} from './panel'; 28 29// This is used to display the summary of search results. 30export class TickmarkPanel extends Panel { 31 view() { 32 return m('.tickbar'); 33 } 34 35 renderCanvas(ctx: CanvasRenderingContext2D, size: PanelSize) { 36 const {visibleWindowTime, visibleTimeScale} = globals.frontendLocalState; 37 38 ctx.fillStyle = '#999'; 39 ctx.fillRect(TRACK_SHELL_WIDTH - 2, 0, 2, size.height); 40 41 ctx.save(); 42 ctx.beginPath(); 43 ctx.rect(TRACK_SHELL_WIDTH, 0, size.width - TRACK_SHELL_WIDTH, size.height); 44 ctx.clip(); 45 46 const span = globals.frontendLocalState.visibleWindow.timestampSpan; 47 if (size.width > TRACK_SHELL_WIDTH && span.duration > 0n) { 48 const maxMajorTicks = getMaxMajorTicks(size.width - TRACK_SHELL_WIDTH); 49 const map = timeScaleForVisibleWindow(TRACK_SHELL_WIDTH, size.width); 50 for (const {type, time} of new TickGenerator( 51 span, maxMajorTicks, globals.state.traceTime.start)) { 52 const px = Math.floor(map.tpTimeToPx(time)); 53 if (type === TickType.MAJOR) { 54 ctx.fillRect(px, 0, 1, size.height); 55 } 56 } 57 } 58 59 const data = globals.searchSummary; 60 for (let i = 0; i < data.tsStarts.length; i++) { 61 const tStart = data.tsStarts[i]; 62 const tEnd = data.tsEnds[i]; 63 if (tEnd <= visibleWindowTime.start.seconds || 64 tStart >= visibleWindowTime.end.seconds) { 65 continue; 66 } 67 const rectStart = 68 Math.max(visibleTimeScale.secondsToPx(tStart), 0) + TRACK_SHELL_WIDTH; 69 const rectEnd = visibleTimeScale.secondsToPx(tEnd) + TRACK_SHELL_WIDTH; 70 ctx.fillStyle = '#ffe263'; 71 ctx.fillRect( 72 Math.floor(rectStart), 73 0, 74 Math.ceil(rectEnd - rectStart), 75 size.height); 76 } 77 const index = globals.state.searchIndex; 78 if (index !== -1) { 79 const startSec = fromNs(globals.currentSearchResults.tsStarts[index]); 80 const triangleStart = 81 Math.max(visibleTimeScale.secondsToPx(startSec), 0) + 82 TRACK_SHELL_WIDTH; 83 ctx.fillStyle = '#000'; 84 ctx.beginPath(); 85 ctx.moveTo(triangleStart, size.height); 86 ctx.lineTo(triangleStart - 3, 0); 87 ctx.lineTo(triangleStart + 3, 0); 88 ctx.lineTo(triangleStart, size.height); 89 ctx.fill(); 90 ctx.closePath(); 91 } 92 93 ctx.restore(); 94 } 95} 96