@bokeh/bokehjs
Version:
Interactive, novel data visualization
91 lines • 3.04 kB
JavaScript
import { UIElement, UIElementView } from "./ui_element";
import { DOMNode } from "../dom/dom_node";
import { HTML } from "../dom/html";
import { build_views, remove_views } from "../../core/build_views";
import { Ref, Or } from "../../core/kinds";
// TODO UIElement needs to inherit from DOMNode
export const ElementLike = Or(Ref(UIElement), Ref(DOMNode), Ref(HTML));
export class PaneView extends UIElementView {
static __name__ = "PaneView";
_element_views = new Map();
get elements() {
return this.model.elements;
}
get element_views() {
return this.elements.map((element) => this._element_views.get(element)).filter((view) => view != null);
}
*children() {
yield* super.children();
yield* this.element_views;
}
async lazy_initialize() {
await super.lazy_initialize();
await this._build_elements();
}
async _build_elements() {
return await build_views(this._element_views, this.elements, { parent: this });
}
async _update_elements() {
const { created } = await this._build_elements();
const created_elements = new Set(created);
// First remove and then either reattach existing elements or render and
// attach new elements, so that the order of children is consistent, while
// avoiding expensive re-rendering of existing views.
for (const element_view of this.element_views) {
element_view.el.remove();
}
for (const element_view of this.element_views) {
const is_new = created_elements.has(element_view);
const target = element_view.rendering_target() ?? this.self_target;
if (is_new) {
element_view.render_to(target);
}
else {
target.append(element_view.el);
}
}
this.r_after_render();
}
remove() {
remove_views(this._element_views);
super.remove();
}
connect_signals() {
super.connect_signals();
const { elements } = this.model.properties;
this.on_change(elements, async () => {
await this._update_elements();
});
}
render() {
super.render();
for (const element_view of this.element_views) {
const target = element_view.rendering_target() ?? this.self_target;
element_view.render_to(target);
}
}
has_finished() {
if (!super.has_finished()) {
return false;
}
for (const element_view of this.element_views) {
if (!element_view.has_finished()) {
return false;
}
}
return true;
}
}
export class Pane extends UIElement {
static __name__ = "Pane";
constructor(attrs) {
super(attrs);
}
static {
this.prototype.default_view = PaneView;
this.define(({ List }) => ({
elements: [List(ElementLike), []],
}));
}
}
//# sourceMappingURL=pane.js.map