Skip to content

Commit 65433cf

Browse files
committed
refactor: decouple plot viewers and implement PlotManager for extensibility
1 parent 11af1ea commit 65433cf

9 files changed

Lines changed: 732 additions & 826 deletions

File tree

session.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,17 +254,17 @@ export async function showDataView(source: string, type: string, title: string,
254254
```typescript
255255
case 'httpgd': {
256256
if (request.url) {
257-
await globalHttpgdManager?.showViewer(request.url);
257+
await globalPlotManager?.showHttpgdPlot(request.url);
258258
}
259259
break;
260260
}
261261
```
262262

263-
**Detail (`httpgd` [-> src/plotViewer/index.ts#L72](src/plotViewer/index.ts#L72)):**
263+
**Detail (`httpgd` [-> src/plotViewer/index.ts](src/plotViewer/index.ts)):**
264264
Triggered when an R script opens an `httpgd` graphics device (a modern SVG/HTML-based plotting device for R).
265265

266266
1. **Intercepting the URL**: R tells VS Code the exact local URL/port where the `httpgd` server is streaming the plots.
267-
2. **Delegation to Manager**: The session handler passes this URL to the `globalHttpgdManager` (an instance of `HttpgdManager` defined in `src/plotViewer/index.ts`).
267+
2. **Delegation to Manager**: The session handler passes this URL to the `globalPlotManager` (an instance of `CommonPlotManager` defined in `src/plotViewer/index.ts`).
268268
3. **Viewer Instantiation**: The manager parses the URL, extracting the host and security token. It searches to see if a viewer for that host already exists. If not, it instantiates a new `HttpgdViewer`.
269269
4. **Webview Rendering**: The `HttpgdViewer` spins up a dedicated `WebviewPanel`. Instead of just embedding the plot as a static image, it loads a full React-based frontend application (bundled in the extension's resources) into the webview. This frontend connects directly to the R `httpgd` server via WebSockets to provide a live, interactive, resizable plot viewer with history tracking and export capabilities.
270270

src/extension.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ import * as apiImplementation from './apiImplementation';
2020
import * as rHelp from './helpViewer';
2121
import * as completions from './completions';
2222
import * as rShare from './liveShare';
23-
import * as httpgdViewer from './plotViewer';
23+
import * as plotViewer from './plotViewer';
24+
import { PlotManager } from './plotViewer/types';
2425
import * as languageService from './languageService';
2526
import { RTaskProvider } from './tasks';
2627

@@ -32,7 +33,7 @@ export let rWorkspace: workspaceViewer.WorkspaceDataProvider | undefined = undef
3233
export let globalRHelp: rHelp.RHelp | undefined = undefined;
3334
export let extensionContext: vscode.ExtensionContext;
3435
export let enableSessionWatcher: boolean | undefined = undefined;
35-
export let globalHttpgdManager: httpgdViewer.HttpgdManager | undefined = undefined;
36+
export let globalPlotManager: PlotManager | undefined = undefined;
3637
export let rmdPreviewManager: rmarkdown.RMarkdownPreviewManager | undefined = undefined;
3738
export let rmdKnitManager: rmarkdown.RMarkdownKnitManager | undefined = undefined;
3839
export let sessionStatusBarItem: vscode.StatusBarItem | undefined = undefined;
@@ -200,8 +201,8 @@ export async function activate(context: vscode.ExtensionContext): Promise<apiImp
200201
}
201202
));
202203

203-
// initialize httpgd viewer
204-
globalHttpgdManager = httpgdViewer.initializeHttpgd();
204+
// initialize plot manager
205+
globalPlotManager = plotViewer.initializePlotManager();
205206

206207
// initialize the package/help related functions
207208
globalRHelp = await rHelp.initializeHelp(context, rExtension);

src/liveShare/shareCommands.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import { forwardCommands, shareWorkspace } from './shareTree';
99
import { runTextInTerm } from '../rTerminal';
1010
import { requestFile, WorkspaceData } from '../session';
1111
import { HelpFile } from '../helpViewer';
12-
import { globalHttpgdManager, globalRHelp } from '../extension';
12+
import { globalPlotManager, globalRHelp } from '../extension';
1313

1414
// used in sending messages to the guest service,
1515
// distinguishes the type of vscode message to show
@@ -99,7 +99,7 @@ export const Commands: ICommands = {
9999
void updateGuestPlot(args[0]);
100100
},
101101
[Callback.NotifyGuestPlotManager]: (args: [url: string]): void => {
102-
void globalHttpgdManager?.showViewer(args[0]);
102+
void globalPlotManager?.showHttpgdPlot(args[0]);
103103
},
104104
[Callback.OrderDetach]: (): void => {
105105
void detachGuest();

src/liveShare/shareSession.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import path = require('path');
22
import * as vscode from 'vscode';
33

4-
import { extensionContext, globalHttpgdManager, globalRHelp, rWorkspace } from '../extension';
4+
import { extensionContext, globalPlotManager, globalRHelp, rWorkspace } from '../extension';
55
import { asViewColumn, config, readContent } from '../util';
66
import { showBrowser, showDataView, showWebView, WorkspaceData } from '../session';
77
import { liveSession, UUID, rGuestService, _sessionStatusBarItem as sessionStatusBarItem } from '.';
@@ -118,7 +118,7 @@ export async function updateGuestRequest(file: string, force: boolean = false):
118118
}
119119
case 'httpgd': {
120120
if (request.url) {
121-
await globalHttpgdManager?.showViewer(request.url);
121+
await globalPlotManager?.showHttpgdPlot(request.url);
122122
}
123123
break;
124124
}

0 commit comments

Comments
 (0)