diff --git a/flamechart-view.tsx b/flamechart-view.tsx index 94ee8f3..c04ed98 100644 --- a/flamechart-view.tsx +++ b/flamechart-view.tsx @@ -5,7 +5,7 @@ import {ReloadableComponent} from './reloadable' import {CallTreeNode, Frame} from './profile' import {Flamechart} from './flamechart' -import {Rect, Vec2, AffineTransform} from './math' +import {Rect, Vec2, AffineTransform, clamp} from './math' import {formatPercent} from './utils' import {FlamechartMinimapView} from './flamechart-minimap-view' @@ -50,36 +50,30 @@ export class FlamechartView extends ReloadableComponent { const configSpaceDetailViewHeight = Sizes.DETAIL_VIEW_HEIGHT / Sizes.FRAME_HEIGHT - const configSpaceOriginBounds = new Rect( - new Vec2(0, -1), - Vec2.max( - new Vec2(0, 0), - this.configSpaceSize() - .minus(viewportRect.size) - .plus(new Vec2(0, configSpaceDetailViewHeight + 1)), - ), + const configSpaceSize = this.configSpaceSize() + + const width = clamp( + viewportRect.size.x, + Math.min(configSpaceSize.x, 3 * this.props.flamechart.getMinFrameWidth()), + configSpaceSize.x, ) - const configSpaceSizeBounds = new Rect( - new Vec2(this.minConfigSpaceViewportRectWidth(), viewportRect.height()), - new Vec2(this.configSpaceSize().x, viewportRect.height()), + const size = viewportRect.size.withX(width) + + const origin = Vec2.clamp( + viewportRect.origin, + new Vec2(0, -1), + Vec2.max( + Vec2.zero, + configSpaceSize.minus(size).plus(new Vec2(0, configSpaceDetailViewHeight + 1)), + ), ) this.setState({ - configSpaceViewportRect: new Rect( - configSpaceOriginBounds.closestPointTo(viewportRect.origin), - configSpaceSizeBounds.closestPointTo(viewportRect.size), - ), + configSpaceViewportRect: new Rect(origin, viewportRect.size.withX(width)), }) } diff --git a/math.ts b/math.ts index bf8d417..55476c5 100644 --- a/math.ts +++ b/math.ts @@ -56,6 +56,10 @@ export class Vec2 { return new Vec2(Math.max(a.x, b.x), Math.max(a.y, b.y)) } + static clamp(v: Vec2, min: Vec2, max: Vec2) { + return new Vec2(clamp(v.x, min.x, max.x), clamp(v.y, min.y, max.y)) + } + static zero = new Vec2(0, 0) static unit = new Vec2(1, 1) diff --git a/sandwich-view.tsx b/sandwich-view.tsx index c1c2b27..1e14632 100644 --- a/sandwich-view.tsx +++ b/sandwich-view.tsx @@ -8,7 +8,7 @@ import {CanvasContext} from './canvas-context' import {FlamechartRenderer, FlamechartRowAtlasKey} from './flamechart-renderer' import {Flamechart} from './flamechart' import {RowAtlas} from './row-atlas' -import {Rect, AffineTransform, Vec2} from './math' +import {Rect, AffineTransform, Vec2, clamp} from './math' import {FlamechartPanZoomView, FlamechartPanZoomViewProps} from './flamechart-pan-zoom-view' import {noop, formatPercent} from './utils' import {Hovertip} from './hovertip' @@ -43,25 +43,21 @@ export class FlamechartWrapper extends ReloadableComponent< private clampViewportToFlamegraph(viewportRect: Rect, flamegraph: Flamechart, inverted: boolean) { const configSpaceSize = new Vec2(flamegraph.getTotalWeight(), flamegraph.getLayers().length) - let configSpaceOriginBounds = new Rect( + const width = clamp( + viewportRect.size.x, + Math.min(configSpaceSize.x, 3 * flamegraph.getMinFrameWidth()), + configSpaceSize.x, + ) + + const size = viewportRect.size.withX(width) + + const origin = Vec2.clamp( + viewportRect.origin, new Vec2(0, inverted ? 0 : -1), - Vec2.max(new Vec2(0, 0), configSpaceSize.minus(viewportRect.size).plus(new Vec2(0, 1))), + Vec2.max(Vec2.zero, configSpaceSize.minus(size).plus(new Vec2(0, 1))), ) - const minConfigSpaceViewportRectWidth = Math.min( - flamegraph.getTotalWeight(), - 3 * flamegraph.getMinFrameWidth(), - ) - - const configSpaceSizeBounds = new Rect( - new Vec2(minConfigSpaceViewportRectWidth, viewportRect.height()), - new Vec2(configSpaceSize.x, viewportRect.height()), - ) - - return new Rect( - configSpaceOriginBounds.closestPointTo(viewportRect.origin), - configSpaceSizeBounds.closestPointTo(viewportRect.size), - ) + return new Rect(origin, viewportRect.size.withX(width)) } private setConfigSpaceViewportRect = (viewportRect: Rect) => {