@bokeh/bokehjs
Version:
Interactive, novel data visualization
99 lines • 3.48 kB
JavaScript
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