This PR addresses two key pieces of feedback provided on search in #38 1. Make the search results more visually prominent 2. Make it easier to find the matches by having some way of jumping to next For the visual prominence facet, I switched from yellow outlines to orange backgrounds. |Before|After| |-|-| ||| For the easy identification portion, I added prev/next buttons to each view, which can also be operated by hitting Enter for next or Shift+Enter for previous. 
213 lines
6.8 KiB
TypeScript
213 lines
6.8 KiB
TypeScript
import {h} from 'preact'
|
|
import {FlamechartID, FlamechartViewState} from '../store/flamechart-view-state'
|
|
import {CanvasContext} from '../gl/canvas-context'
|
|
import {Flamechart} from '../lib/flamechart'
|
|
import {FlamechartRenderer, FlamechartRendererOptions} from '../gl/flamechart-renderer'
|
|
import {useActionCreator} from '../lib/preact-redux'
|
|
import {Frame, Profile, CallTreeNode} from '../lib/profile'
|
|
import {memoizeByShallowEquality} from '../lib/utils'
|
|
import {FlamechartView} from './flamechart-view'
|
|
import {
|
|
getRowAtlas,
|
|
createGetColorBucketForFrame,
|
|
getCanvasContext,
|
|
createGetCSSColorForFrame,
|
|
getFrameToColorBucket,
|
|
} from '../store/getters'
|
|
import {Vec2, Rect} from '../lib/math'
|
|
import {actions} from '../store/actions'
|
|
import {memo} from 'preact/compat'
|
|
import {ActiveProfileState} from '../store'
|
|
import {FlamechartSearchContextProvider} from './flamechart-search-view'
|
|
|
|
interface FlamechartSetters {
|
|
setLogicalSpaceViewportSize: (logicalSpaceViewportSize: Vec2) => void
|
|
setConfigSpaceViewportRect: (configSpaceViewportRect: Rect) => void
|
|
setNodeHover: (hover: {node: CallTreeNode; event: MouseEvent} | null) => void
|
|
setSelectedNode: (node: CallTreeNode | null) => void
|
|
}
|
|
|
|
const {
|
|
setHoveredNode,
|
|
setLogicalSpaceViewportSize,
|
|
setConfigSpaceViewportRect,
|
|
setSelectedNode,
|
|
} = actions.flamechart
|
|
|
|
export function useFlamechartSetters(id: FlamechartID, profileIndex: number): FlamechartSetters {
|
|
return {
|
|
setNodeHover: useActionCreator(
|
|
(hover: {node: CallTreeNode; event: MouseEvent} | null) =>
|
|
setHoveredNode({profileIndex, args: {id, hover}}),
|
|
[profileIndex, id],
|
|
),
|
|
setLogicalSpaceViewportSize: useActionCreator(
|
|
(logicalSpaceViewportSize: Vec2) =>
|
|
setLogicalSpaceViewportSize({profileIndex, args: {id, logicalSpaceViewportSize}}),
|
|
[profileIndex, id],
|
|
),
|
|
setConfigSpaceViewportRect: useActionCreator(
|
|
(configSpaceViewportRect: Rect) =>
|
|
setConfigSpaceViewportRect({profileIndex, args: {id, configSpaceViewportRect}}),
|
|
[profileIndex, id],
|
|
),
|
|
setSelectedNode: useActionCreator(
|
|
(selectedNode: CallTreeNode | null) =>
|
|
setSelectedNode({profileIndex, args: {id, selectedNode}}),
|
|
[profileIndex, id],
|
|
),
|
|
}
|
|
}
|
|
|
|
export type FlamechartViewProps = {
|
|
canvasContext: CanvasContext
|
|
flamechart: Flamechart
|
|
flamechartRenderer: FlamechartRenderer
|
|
renderInverted: boolean
|
|
getCSSColorForFrame: (frame: Frame) => string
|
|
} & FlamechartSetters &
|
|
FlamechartViewState
|
|
|
|
export const getChronoViewFlamechart = memoizeByShallowEquality(
|
|
({
|
|
profile,
|
|
getColorBucketForFrame,
|
|
}: {
|
|
profile: Profile
|
|
getColorBucketForFrame: (frame: Frame) => number
|
|
}): Flamechart => {
|
|
return new Flamechart({
|
|
getTotalWeight: profile.getTotalWeight.bind(profile),
|
|
forEachCall: profile.forEachCall.bind(profile),
|
|
formatValue: profile.formatValue.bind(profile),
|
|
getColorBucketForFrame,
|
|
})
|
|
},
|
|
)
|
|
|
|
export const createMemoizedFlamechartRenderer = (options?: FlamechartRendererOptions) =>
|
|
memoizeByShallowEquality(
|
|
({
|
|
canvasContext,
|
|
flamechart,
|
|
}: {
|
|
canvasContext: CanvasContext
|
|
flamechart: Flamechart
|
|
}): FlamechartRenderer => {
|
|
return new FlamechartRenderer(
|
|
canvasContext.gl,
|
|
getRowAtlas(canvasContext),
|
|
flamechart,
|
|
canvasContext.rectangleBatchRenderer,
|
|
canvasContext.flamechartColorPassRenderer,
|
|
options,
|
|
)
|
|
},
|
|
)
|
|
|
|
const getChronoViewFlamechartRenderer = createMemoizedFlamechartRenderer()
|
|
|
|
export interface FlamechartViewContainerProps {
|
|
activeProfileState: ActiveProfileState
|
|
glCanvas: HTMLCanvasElement
|
|
}
|
|
|
|
export const ChronoFlamechartView = memo((props: FlamechartViewContainerProps) => {
|
|
const {activeProfileState, glCanvas} = props
|
|
const {index, profile, chronoViewState} = activeProfileState
|
|
|
|
const canvasContext = getCanvasContext(glCanvas)
|
|
const frameToColorBucket = getFrameToColorBucket(profile)
|
|
const getColorBucketForFrame = createGetColorBucketForFrame(frameToColorBucket)
|
|
const getCSSColorForFrame = createGetCSSColorForFrame(frameToColorBucket)
|
|
|
|
const flamechart = getChronoViewFlamechart({profile, getColorBucketForFrame})
|
|
const flamechartRenderer = getChronoViewFlamechartRenderer({
|
|
canvasContext,
|
|
flamechart,
|
|
})
|
|
|
|
const setters = useFlamechartSetters(FlamechartID.CHRONO, index)
|
|
|
|
return (
|
|
<FlamechartSearchContextProvider
|
|
flamechart={flamechart}
|
|
selectedNode={chronoViewState.selectedNode}
|
|
setSelectedNode={setters.setSelectedNode}
|
|
configSpaceViewportRect={chronoViewState.configSpaceViewportRect}
|
|
setConfigSpaceViewportRect={setters.setConfigSpaceViewportRect}
|
|
>
|
|
<FlamechartView
|
|
renderInverted={false}
|
|
flamechart={flamechart}
|
|
flamechartRenderer={flamechartRenderer}
|
|
canvasContext={canvasContext}
|
|
getCSSColorForFrame={getCSSColorForFrame}
|
|
{...chronoViewState}
|
|
{...setters}
|
|
/>
|
|
</FlamechartSearchContextProvider>
|
|
)
|
|
})
|
|
|
|
export const getLeftHeavyFlamechart = memoizeByShallowEquality(
|
|
({
|
|
profile,
|
|
getColorBucketForFrame,
|
|
}: {
|
|
profile: Profile
|
|
getColorBucketForFrame: (frame: Frame) => number
|
|
}): Flamechart => {
|
|
return new Flamechart({
|
|
getTotalWeight: profile.getTotalNonIdleWeight.bind(profile),
|
|
forEachCall: profile.forEachCallGrouped.bind(profile),
|
|
formatValue: profile.formatValue.bind(profile),
|
|
getColorBucketForFrame,
|
|
})
|
|
},
|
|
)
|
|
|
|
const getLeftHeavyFlamechartRenderer = createMemoizedFlamechartRenderer()
|
|
|
|
export const LeftHeavyFlamechartView = memo((ownProps: FlamechartViewContainerProps) => {
|
|
const {activeProfileState, glCanvas} = ownProps
|
|
|
|
const {index, profile, leftHeavyViewState} = activeProfileState
|
|
|
|
const canvasContext = getCanvasContext(glCanvas)
|
|
const frameToColorBucket = getFrameToColorBucket(profile)
|
|
const getColorBucketForFrame = createGetColorBucketForFrame(frameToColorBucket)
|
|
const getCSSColorForFrame = createGetCSSColorForFrame(frameToColorBucket)
|
|
|
|
const flamechart = getLeftHeavyFlamechart({
|
|
profile,
|
|
getColorBucketForFrame,
|
|
})
|
|
const flamechartRenderer = getLeftHeavyFlamechartRenderer({
|
|
canvasContext,
|
|
flamechart,
|
|
})
|
|
|
|
const setters = useFlamechartSetters(FlamechartID.LEFT_HEAVY, index)
|
|
|
|
return (
|
|
<FlamechartSearchContextProvider
|
|
flamechart={flamechart}
|
|
selectedNode={leftHeavyViewState.selectedNode}
|
|
setSelectedNode={setters.setSelectedNode}
|
|
configSpaceViewportRect={leftHeavyViewState.configSpaceViewportRect}
|
|
setConfigSpaceViewportRect={setters.setConfigSpaceViewportRect}
|
|
>
|
|
<FlamechartView
|
|
renderInverted={false}
|
|
flamechart={flamechart}
|
|
flamechartRenderer={flamechartRenderer}
|
|
canvasContext={canvasContext}
|
|
getCSSColorForFrame={getCSSColorForFrame}
|
|
{...leftHeavyViewState}
|
|
{...setters}
|
|
/>
|
|
</FlamechartSearchContextProvider>
|
|
)
|
|
})
|