-
Notifications
You must be signed in to change notification settings - Fork 105
Zoom plots in editor #8126
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Zoom plots in editor #8126
Conversation
E2E Tests 🚀 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
Adds zoom functionality for Positron plots in editor views, wiring zoom state through services, clients, and UI.
- Introduce
ZoomLevel
enum andIZoomablePlotClient
interface - Extend plot services and clients to store, emit, and persist zoom level
- Update browser components and actions to render zoom controls and apply zoom
Reviewed Changes
Copilot reviewed 18 out of 18 changed files in this pull request and generated 2 comments.
Show a summary per file
File | Description |
---|---|
test/common/testPositronPlotsService.ts | Add zoom-level map, getter/setter, and event emitter to test service |
test/common/testPositronPlotClient.ts & test/common/testPlotsServiceHelper.ts | Initialize default zoom_level in test metadata |
common/staticPlotClient.ts | Implement IZoomablePlotClient , zoom-level emitter, and setters/getters |
common/positronPlots.ts | Define ZoomLevel enum, IZoomablePlotClient , and type guard |
common/languageRuntimePlotClient.ts | Extend runtime plot client with zoom-level state and events |
contrib/positronPlotsEditor/browser/editorPlotsContainer.tsx | Subscribe to plot-client zoom events and apply zoom in editor |
contrib/positronPlots/browser/positronPlotsService.ts | Add setEditorPlotZoom /getEditorPlotZoom , persist metadata on zoom |
contrib/positronPlots/browser/positronPlotsActions.ts | Register zoom submenu and individual zoom actions |
contrib/positronPlots/browser/components/zoomPlotMenuButton.tsx | Switch to shared ZoomLevel import |
contrib/positronPlots/browser/components/*Instance.tsx | Pass instance zoomLevel into PanZoomImage |
contrib/positronPlots/browser/components/panZoomImage.tsx | Update zoom logic to consume optional prop |
Comments suppressed due to low confidence (1)
src/vs/workbench/services/positronPlots/common/positronPlots.ts:341
- The method signature uses a plain
number
forzoom
, but consumers will pass aZoomLevel
. Consider changing this parameter tozoom: ZoomLevel
for type safety and consistency.
setEditorPlotZoom(plotId: string, zoom: number): void;
src/vs/workbench/contrib/positronPlots/browser/components/panZoomImage.tsx
Outdated
Show resolved
Hide resolved
src/vs/workbench/services/positronPlots/test/common/testPositronPlotsService.ts
Outdated
Show resolved
Hide resolved
cc725b7
to
0c860cd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these are all working for me:
- upon reloading positron via
Developer: Reload Window
, the plot zoom in the editor and Plots pane were both restored - able to adjust zoom for plot in Editor and Editor in separate window, same behaviour as Plots pane
- when plot size is larger than the plot area, can pan up/down/left/right with trackpad or scrollwheel (scrollwheel to move up/down; Shift+scrollwheel to move left/right)
@@ -180,12 +180,12 @@ export const PlotsContainer = (props: PlotContainerProps) => { | |||
height={plotHeight} | |||
plotClient={plotInstance} | |||
width={plotWidth} | |||
zoom={props.zoom} />; | |||
zoom={plotInstance.zoomLevel} />; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we still need this separate prop now that zoomLevel
is part of the plotInstance
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch!
this._register(plot.onDidChangeZoomLevel((zoomLevel) => { | ||
// Store the zoom level in the plot metadata | ||
this.storePlotMetadata(plot.metadata); | ||
})); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is the zoomLevel
already reflected in plot.metadata
, or should the metadata be updated with the zoom level before storing it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the plot client updates the metadata when the zoom changes. I should fix up the comment though since this is updating the stored metadata.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, it makes sense to update it before storing. It'll move the responsibility of updating the metadata to the service and future plot clients won't have to worry about it.
@@ -62,6 +62,7 @@ export class PositronPlotsEditor extends EditorPane implements IPositronPlotsEdi | |||
|
|||
private readonly _onFocusedEmitter = this._register(new Emitter<void>()); | |||
private _plotClient: IPositronPlotClient | undefined; | |||
_zoomContextKey: IContextKey<string>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: should this be private?
_zoomContextKey: IContextKey<string>; | |
private _zoomContextKey: IContextKey<string>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should!
|
||
export enum ZoomLevel { | ||
Fit = 0, | ||
Fifty = 0.5, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An observation I think unrelated to the changes in this PR:
50% zoom level seemed to be equivalent to Fit for me, in the Plots pane, Editor and new window. I also expected 75% zoom to be 75% of Fit, but I think there is an intrinsic size of the plot image which these percentages correspond to?
I wonder if the zoom percentages should be relative to the Fit rather than an intrinsic size (if that is the case)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The level affects the image scaling, which depends on the rendered size. When the plot is shown in the editor, the rendered size is different because of the available space. It's the same plot comm underneath but with a proxy on top so that the editor and view can have their own render options.
The Plots pane may have 350x300 pixels while the editor may have 700x600. Unless the plot size is set to intrinsic, the plot is going to render to fill the space. The zooming changes the scaling when displayed by changing the width and height via CSS. So the final size might be the same or similar when the view is at 100% and the editor is at 50% zoom. I think it's just the coincidence that the Plots pane width and height are about half the size of the editor that causes this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm still seeing Fit and 50% be the same in the Editor, and now in the Plots pane the Zoom seems to be the same with every zoom option. This was recorded on a larger, more square monitor, but I'm seeing the same behaviour on the 16" Macbook screen as well.
plots_zoom.mp4
Maybe this is a separate enhancement / docs change to describe how the zoom level works? I had expected that the Zoom percentage is relative to the initial "Fit" image size, so I expected 50% and 75% to scale the image down, but then 100% and Fit would be equivalent in this case...I'm not sure the best path forward, maybe just awaiting some user feedback!
For the Plots pane, could you check if you see the same behaviour? The Zoom control isn't re-scaling the image, even if I modify how large the Plots pane is.
})); | ||
this._zoomContextKey.set(this._plotClient.metadata.zoom_level?.toString() ?? ''); | ||
} | ||
|
||
this.renderContainer(this._plotClient); | ||
this.onSizeChanged((event: ISize) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure the right spot for this, but I am seeing a leaked disposable when I have the plot open qa-example-content/workspaces/r-plots/ggplot-example.R
in an editor:
lifecycle.ts:50 [LEAKED DISPOSABLE] Error: CREATED via:
at GCBasedDisposableTracker.trackDisposable (vscode-file://vscode-app/Users/sashimi/dev/positron-dev/out/vs/base/common/lifecycle.js:27:23)
at trackDisposable (vscode-file://vscode-app/Users/sashimi/dev/positron-dev/out/vs/base/common/lifecycle.js:198:24)
at toDisposable (vscode-file://vscode-app/Users/sashimi/dev/positron-dev/out/vs/base/common/lifecycle.js:276:18)
at PositronPlotsEditor._event [as onSizeChanged] (vscode-file://vscode-app/Users/sashimi/dev/positron-dev/out/vs/base/common/event.js:876:28)
at PositronPlotsEditor.setInput (vscode-file://vscode-app/Users/sashimi/dev/positron-dev/out/vs/workbench/contrib/positronPlotsEditor/browser/positronPlotsEditor.js:119:14)
at async EditorPanes.doSetInput (vscode-file://vscode-app/Users/sashimi/dev/positron-dev/out/vs/workbench/browser/parts/editor/editorPanes.js:343:13)
at async EditorPanes.doOpenEditor (vscode-file://vscode-app/Users/sashimi/dev/positron-dev/out/vs/workbench/browser/parts/editor/editorPanes.js:183:40)
at async EditorPanes.openEditor (vscode-file://vscode-app/Users/sashimi/dev/positron-dev/out/vs/workbench/browser/parts/editor/editorPanes.js:82:20)
at async vscode-file://vscode-app/Users/sashimi/dev/positron-dev/out/vs/workbench/browser/parts/editor/editorGroupView.js:1057:61
2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! I couldn't reproduce it but looking at the code it's obvious why the disposable is leaking.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not seeing this anymore! 👍
065342d
to
4903d33
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not without changing how the editor action bar contribution is processed. I'm not even sure how easy it is to update the contribution dynamically and it would also need to support extensions contributing to this, which would likely be through their extensions |
Update plot metadata to save zoom level Plot view remembers zoom level for plots
Add plot zoom event
7f343cd
to
587878b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the unit test failures seem related to this PR, but otherwise LGTM and zooming in the Plots pane is working again 👌
Address #4359
Adds the zoom level to the plot metadata. This is used to set the button text in the Plots pane and to set the zoom prop when rendering in the pane and editor.
An editor zoom action has been added as a menu button for the zoom levels. The currently selected zoom level is checked when opening the menu.
The actions have been moved to the left side.
The plot metadata has been updated to include the zoom level. The zoom level is restored for the editor and view when reloading the UI.
Release Notes
New Features
Bug Fixes
QA Notes