UNPKG

@bokeh/bokehjs

Version:

Interactive, novel data visualization

99 lines 3.48 kB
import { Marker, MarkerView } from "./marker"; import { MarkerType } from "../../core/enums"; import { marker_funcs } from "./defs"; import * as p from "../../core/properties"; import * as u from "../../core/uniforms"; import { CustomJS } from "../callbacks/customjs"; import { execute_sync } from "../../core/util/callbacks"; import { dict, is_empty } from "../../core/util/object"; function is_MarkerType(type) { return MarkerType.valid(type); } export class ScatterView extends MarkerView { static __name__ = "ScatterView"; async load_glglyph() { const { MultiMarkerGL } = await import("./webgl/multi_marker"); return MultiMarkerGL; } _compute_can_use_webgl() { return is_empty(this.model.defs) || u.every(this.marker, is_MarkerType); } async _update_defs() { for (const cb of dict(this.model.defs).values()) { if (cb instanceof CustomJS) { await cb.compile(); } } } connect_signals() { super.connect_signals(); const { defs } = this.model.properties; this.on_change(defs, () => this._update_defs()); } async lazy_initialize() { await super.lazy_initialize(); await this._update_defs(); } _paint(ctx, indices, data) { const { sx, sy, size, angle, marker } = { ...this, ...data }; const defs = dict(this.model.defs); const { visuals } = this; for (const i of indices) { const sx_i = sx[i]; const sy_i = sy[i]; const size_i = size.get(i); const angle_i = angle.get(i); const marker_i = marker.get(i); if (!isFinite(sx_i + sy_i + size_i + angle_i) || marker_i == null) { continue; } ctx.beginPath(); ctx.translate(sx_i, sy_i); if (angle_i != 0) { ctx.rotate(angle_i); } const r = size_i / 2; if (is_MarkerType(marker_i)) { marker_funcs[marker_i](ctx, i, r, visuals); } else { const fn = defs.get(marker_i); if (fn != null) { const path = execute_sync(fn, this.model, { ctx, i, r, visuals }); if (path instanceof Path2D) { this.visuals.fill.apply(ctx, i, path); this.visuals.hatch.apply(ctx, i, path); this.visuals.line.apply(ctx, i, path); } } } if (angle_i != 0) { ctx.rotate(-angle_i); } ctx.translate(-sx_i, -sy_i); } } draw_legend_for_index(ctx, { x0, x1, y0, y1 }, index) { const n = index + 1; const marker = this.marker.get(index); const args = { ...this._get_legend_args({ x0, x1, y0, y1 }, index), marker: new p.UniformScalar(marker, n), }; this._paint(ctx, [index], args); } } export class Scatter extends Marker { static __name__ = "Scatter"; constructor(attrs) { super(attrs); } static { this.prototype.default_view = ScatterView; this.define(({ KeyVal, Or, Func, Ref }) => ({ marker: [p.MarkerSpec, { value: "circle" }], defs: [KeyVal(p.ExtMarkerType, Or(Func(), Ref(CustomJS))), {}], })); } } //# sourceMappingURL=scatter.js.map