Skip to content

Commit 94ae9d7

Browse files
committed
Allow max_cells and max_columns statically for D3FC plugins
Signed-off-by: Andrew Stein <steinlink@gmail.com>
1 parent 6e8e396 commit 94ae9d7

8 files changed

Lines changed: 634 additions & 556 deletions

File tree

docs/md/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
- [Loading data from a virtual `Table`](./how_to/javascript/loading_virtual_data.md)
4949
- [Saving and restoring UI state](./how_to/javascript/save_restore.md)
5050
- [Listening for events](./how_to/javascript/events.md)
51+
- [Plugin render limits](./how_to/javascript/events.md)
5152
- [React Component](./how_to/javascript/react.md)
5253
- [Python](./how_to/python.md)
5354
- [Installation](./how_to/python/installation.md)
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Plugin render limits
2+
3+
`<perspective-viewer>` plugins (especially charts) may in some cases generate
4+
extremely large output which may lock up the browser. In order to prevent
5+
accidents (which generally require a browser refresh to fix), each plugin has a
6+
`max_cells` and `max_columns` heuristic which requires the user to opt-in to
7+
fully rendering `View`s which exceed these limits. To over ride this behavior,
8+
must set these values for each plugin type individually, _before_ calling
9+
`HTMLPerspectiveViewerElement::restore` (with the respective `plugin` name).
10+
11+
If you have a `<perspective-viewer>` instance, you can set these properties via
12+
iterating over the plugins returned by the
13+
`HTMLPerspectiveViewerElement::getAllPlugins` method:
14+
15+
```javascript
16+
const viewer = document.querySelector("perspective-viewer");
17+
for (const plugin of await viewer.getAllPlugins()) {
18+
if (plugin.name === "Treemap") {
19+
// Sets all treemap `max_cells`, not just this instance!
20+
plugin.max_cells = 1_000_000;
21+
plugin.max_columns = 1000;
22+
}
23+
}
24+
```
25+
26+
... Or alternatively, you can look up the Custom Element classes and set the
27+
static variants if you know the element name (you can e.g. look this up in your
28+
browser's DOM inspector):
29+
30+
```javascript
31+
const plugin = customElements.get("perspective-viewer-d3fc-treemap");
32+
plugin.max_cells = 1_000_000;
33+
plugin.max_columns = 1000;
34+
```
35+
36+
<div class="warning">
37+
This distinction is just for syntax aesthetics - both methods will apply to all
38+
instances, regardless of set via an instance, or the class itself.
39+
</div>

packages/perspective-viewer-d3fc/src/ts/index.ts

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,47 +11,48 @@
1111
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
1212

1313
import type { IPerspectiveViewerPlugin } from "@finos/perspective-viewer";
14-
import { register } from "./plugin/plugin";
15-
register();
14+
import { init } from "./plugin/d3fc_global_styles";
15+
16+
await init();
1617

1718
declare global {
1819
interface CustomElementRegistry {
1920
get(
2021
tagName: "perspective-viewer-d3fc-area"
21-
): HTMLPerspectiveViewerD3FCPluginElement;
22+
): typeof HTMLPerspectiveViewerD3FCPluginElement;
2223
get(
2324
tagName: "perspective-viewer-d3fc-xbar"
24-
): HTMLPerspectiveViewerD3FCPluginElement;
25+
): typeof HTMLPerspectiveViewerD3FCPluginElement;
2526
get(
2627
tagName: "perspective-viewer-d3fc-candlestick"
27-
): HTMLPerspectiveViewerD3FCPluginElement;
28+
): typeof HTMLPerspectiveViewerD3FCPluginElement;
2829
get(
2930
tagName: "perspective-viewer-d3fc-ybar"
30-
): HTMLPerspectiveViewerD3FCPluginElement;
31+
): typeof HTMLPerspectiveViewerD3FCPluginElement;
3132
get(
3233
tagName: "perspective-viewer-d3fc-heatmap"
33-
): HTMLPerspectiveViewerD3FCPluginElement;
34+
): typeof HTMLPerspectiveViewerD3FCPluginElement;
3435
get(
3536
tagName: "perspective-viewer-d3fc-yline"
36-
): HTMLPerspectiveViewerD3FCPluginElement;
37+
): typeof HTMLPerspectiveViewerD3FCPluginElement;
3738
get(
3839
tagName: "perspective-viewer-d3fc-ohlc"
39-
): HTMLPerspectiveViewerD3FCPluginElement;
40+
): typeof HTMLPerspectiveViewerD3FCPluginElement;
4041
get(
4142
tagName: "perspective-viewer-d3fc-sunburst"
42-
): HTMLPerspectiveViewerD3FCPluginElement;
43+
): typeof HTMLPerspectiveViewerD3FCPluginElement;
4344
get(
4445
tagName: "perspective-viewer-d3fc-treemap"
45-
): HTMLPerspectiveViewerD3FCPluginElement;
46+
): typeof HTMLPerspectiveViewerD3FCPluginElement;
4647
get(
4748
tagName: "perspective-viewer-d3fc-xyline"
48-
): HTMLPerspectiveViewerD3FCPluginElement;
49+
): typeof HTMLPerspectiveViewerD3FCPluginElement;
4950
get(
5051
tagName: "perspective-viewer-d3fc-xyscatter"
51-
): HTMLPerspectiveViewerD3FCPluginElement;
52+
): typeof HTMLPerspectiveViewerD3FCPluginElement;
5253
get(
5354
tagName: "perspective-viewer-d3fc-yscatter"
54-
): HTMLPerspectiveViewerD3FCPluginElement;
55+
): typeof HTMLPerspectiveViewerD3FCPluginElement;
5556

5657
whenDefined(tagName: "perspective-viewer-d3fc-area"): Promise<void>;
5758
whenDefined(tagName: "perspective-viewer-d3fc-xbar"): Promise<void>;
@@ -76,5 +77,9 @@ declare global {
7677

7778
export class HTMLPerspectiveViewerD3FCPluginElement
7879
extends HTMLElement
79-
implements IPerspectiveViewerPlugin {}
80+
implements IPerspectiveViewerPlugin
81+
{
82+
static get max_cells(): number;
83+
static set max_cells(value: number);
84+
}
8085
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
2+
// ┃ ██████ ██████ ██████ █ █ █ █ █ █▄ ▀███ █ ┃
3+
// ┃ ▄▄▄▄▄█ █▄▄▄▄▄ ▄▄▄▄▄█ ▀▀▀▀▀█▀▀▀▀▀ █ ▀▀▀▀▀█ ████████▌▐███ ███▄ ▀█ █ ▀▀▀▀▀ ┃
4+
// ┃ █▀▀▀▀▀ █▀▀▀▀▀ █▀██▀▀ ▄▄▄▄▄ █ ▄▄▄▄▄█ ▄▄▄▄▄█ ████████▌▐███ █████▄ █ ▄▄▄▄▄ ┃
5+
// ┃ █ ██████ █ ▀█▄ █ ██████ █ ███▌▐███ ███████▄ █ ┃
6+
// ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
7+
// ┃ Copyright (c) 2017, the Perspective Authors. ┃
8+
// ┃ ╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌ ┃
9+
// ┃ This file is part of the Perspective library, distributed under the terms ┃
10+
// ┃ of the [Apache License 2.0](https://www.apache.org/licenses/LICENSE-2.0). ┃
11+
// ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
12+
13+
export const D3FC_GLOBAL_STYLES = [];
14+
15+
// Capture (and restore) `document.querySelector` to prevent D3FC from
16+
// attaching styles to the document `<head>`.
17+
export async function init() {
18+
const old_doc = window.document.querySelector;
19+
// @ts-ignore
20+
window.document.querySelector = () => {
21+
return {
22+
appendChild(elem) {
23+
D3FC_GLOBAL_STYLES.push(elem);
24+
return elem;
25+
},
26+
};
27+
};
28+
29+
const { register } = await import("./plugin");
30+
window.document.querySelector = old_doc;
31+
register();
32+
}

0 commit comments

Comments
 (0)