Skip to content

Commit f72c203

Browse files
committed
allow for plugin_config to be set from jupyterlab
1 parent 806cf5a commit f72c203

File tree

6 files changed

+55
-11
lines changed

6 files changed

+55
-11
lines changed

packages/perspective-jupyterlab/src/ts/psp_widget.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ export interface PerspectiveWidgetOptions extends PerspectiveViewerOptions {
2424
server?: boolean;
2525
title?: string;
2626
bindto?: HTMLElement;
27-
plugin_config?: PerspectiveViewerOptions;
2827

2928
// these shouldn't exist, PerspectiveViewerOptions should be sufficient e.g.
3029
// ["row-pivots"]
@@ -66,7 +65,7 @@ export class PerspectiveWidget extends Widget {
6665
const sort: Sort = options.sort || [];
6766
const filters: Filters = options.filters || [];
6867
const expressions: Expressions = options.expressions || options["expressions"] || [];
69-
const plugin_config: PerspectiveViewerOptions = options.plugin_config || {};
68+
const plugin_config: object = options.plugin_config || {};
7069
const dark: boolean = options.dark || false;
7170
const editable: boolean = options.editable || false;
7271
const server: boolean = options.server || false;
@@ -300,13 +299,20 @@ export class PerspectiveWidget extends Widget {
300299
}
301300
}
302301

303-
get plugin_config(): PerspectiveViewerOptions {
302+
// `plugin_config` cannot be synchronously read from the viewer, as it is
303+
// not part of the attribute API and only emitted from save(). Users can
304+
// pass in a plugin config and have it applied to the viewer, but they
305+
// cannot read the current `plugin_config` of the viewer if it has not
306+
// already been set from Python.
307+
get plugin_config(): object {
304308
return this._plugin_config;
305309
}
306-
set plugin_config(plugin_config: PerspectiveViewerOptions) {
310+
set plugin_config(plugin_config: object) {
307311
this._plugin_config = plugin_config;
312+
313+
// Allow plugin configs passed from Python to take effect on the viewer
308314
if (this._plugin_config) {
309-
this.viewer.restore(this._plugin_config);
315+
this.viewer.restore({plugin_config: this._plugin_config});
310316
}
311317
}
312318

@@ -414,7 +420,7 @@ export class PerspectiveWidget extends Widget {
414420
}
415421

416422
private _viewer: HTMLPerspectiveViewerElement;
417-
private _plugin_config: PerspectiveViewerOptions;
423+
private _plugin_config: object;
418424
private _client: boolean;
419425
private _server: boolean;
420426
private _dark: boolean;

packages/perspective-jupyterlab/src/ts/renderer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ export class PerspectiveDocumentWidget extends DocumentWidget<PerspectiveWidget>
103103
this.context.model.fromString(resultAsB64);
104104
this.context.save();
105105
} else if (this._type === "json") {
106+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
106107
const result: any = await view.to_json();
107108
this.context.model.fromJSON(result);
108109
this.context.save();

packages/perspective-jupyterlab/test/jupyter/widget.spec.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,23 @@ utils.with_jupyterlab(process.env.__JUPYTERLAB_PORT__, () => {
195195
expect(dimensions[1]).toEqual("100px");
196196
}
197197
);
198+
199+
test.jupyterlab(
200+
"Sets plugin config",
201+
[["table = perspective.Table(arrow_data)\n", "w = perspective.PerspectiveWidget(table)"], ["w"], ["w.columns = ['f64']\n", "w.plugin_config = {'f64': {'fixed': 10}}"]],
202+
async page => {
203+
const viewer = await default_body(page);
204+
const plugin_config = await viewer.evaluate(async viewer => {
205+
const config = await viewer.save();
206+
return config.plugin_config;
207+
});
208+
expect(plugin_config).toEqual({
209+
f64: {
210+
fixed: 10
211+
}
212+
});
213+
}
214+
);
198215
},
199216
{name: "Simple", root: path.join(__dirname, "..", "..")}
200217
);

packages/perspective-viewer/index.d.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export interface HTMLPerspectiveViewerElement extends PerspectiveViewerOptions,
1919
download(flat: boolean): Promise<any>;
2020
copy(flat: boolean): Promise<void>;
2121
save(): Promise<PerspectiveViewerOptions>;
22-
restore(x: any): Promise<void>;
22+
restore(x: PerspectiveViewerOptions): Promise<void>;
2323
reset(): void;
2424
notifyResize(): void;
2525
restyleElement(): void;
@@ -36,15 +36,16 @@ export type Pivots = string[];
3636
export type Columns = string[];
3737

3838
export interface PerspectiveViewerOptions {
39-
aggregates?: Aggregates;
40-
editable?: boolean;
4139
plugin?: string;
4240
columns?: Columns;
43-
expressions?: Expressions;
4441
"row-pivots"?: Pivots;
4542
"column-pivots"?: Pivots;
43+
aggregates?: Aggregates;
4644
filters?: Filters;
4745
sort?: Sort;
46+
expressions?: Expressions;
47+
plugin_config?: object;
48+
editable?: boolean;
4849
selectable?: boolean;
4950
}
5051

python/perspective/perspective/tests/viewer/test_viewer.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,3 +240,19 @@ def test_save_restore(self):
240240
assert viewer.plugin == "X Bar"
241241
assert viewer.editable is True
242242
assert viewer.expressions == ['"a" * 2']
243+
244+
def test_save_restore_plugin_config(self):
245+
viewer = PerspectiveViewer(plugin="datagrid", plugin_config={"a": {"fixed": 4}})
246+
config = viewer.save()
247+
248+
assert config["plugin_config"] == {
249+
"a": {
250+
"fixed": 4
251+
}
252+
}
253+
254+
viewer.reset()
255+
assert viewer.plugin_config == {}
256+
257+
viewer.restore(**config)
258+
assert viewer.plugin_config == config["plugin_config"]

python/perspective/perspective/viewer/viewer.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ class PerspectiveViewer(PerspectiveTraitlets, object):
5252
"expressions",
5353
"plugin",
5454
"editable",
55+
"plugin_config",
5556
)
5657

5758
def __init__(
@@ -93,7 +94,8 @@ def __init__(
9394
expressions which are applied to the view.
9495
plugin (:obj:`str`/:obj:`perspective.Plugin`): Which plugin to
9596
select by default.
96-
plugin_config (:obj:`dict`): Custom config for all plugins by name.
97+
plugin_config (:obj:`dict`): A configuration for the plugin, i.e.
98+
the datagrid plugin or a chart plugin.
9799
dark (:obj:`bool`): Whether to invert the color theme.
98100
editable (:obj:`bool`): Whether to allow editability using the grid.
99101
@@ -265,6 +267,7 @@ def reset(self):
265267
self.aggregates = {}
266268
self.columns = []
267269
self.plugin = "datagrid"
270+
self.plugin_config = {}
268271
self.editable = False
269272

270273
def delete(self, delete_table=True):

0 commit comments

Comments
 (0)