UNPKG

@bokeh/bokehjs

Version:

Interactive, novel data visualization

129 lines 5.36 kB
import { LineVector, FillVector, HatchVector } from "../../core/property_mixins"; import { Glyph, GlyphView } from "./glyph"; import { generic_area_vector_legend } from "./utils"; import { Selection } from "../selections/selection"; import { BBox } from "../../core/util/bbox"; import { inplace_map } from "../../core/util/arrayable"; import { BorderRadius } from "../common/kinds"; import * as resolve from "../common/resolve"; import { round_rect } from "../common/painting"; export class LRTBView extends GlyphView { static __name__ = "LRTBView"; async load_glglyph() { const { LRTBGL } = await import("./webgl/lrtb"); return LRTBGL; } get_anchor_point(anchor, i, _spt) { const left = Math.min(this.sleft[i], this.sright[i]); const right = Math.max(this.sright[i], this.sleft[i]); const top = Math.min(this.stop[i], this.sbottom[i]); // screen coordinates !!! const bottom = Math.max(this.sbottom[i], this.stop[i]); // switch (anchor) { case "top_left": return { x: left, y: top }; case "top": case "top_center": return { x: (left + right) / 2, y: top }; case "top_right": return { x: right, y: top }; case "bottom_left": return { x: left, y: bottom }; case "bottom": case "bottom_center": return { x: (left + right) / 2, y: bottom }; case "bottom_right": return { x: right, y: bottom }; case "left": case "center_left": return { x: left, y: (top + bottom) / 2 }; case "center": case "center_center": return { x: (left + right) / 2, y: (top + bottom) / 2 }; case "right": case "center_right": return { x: right, y: (top + bottom) / 2 }; } } _set_data(indices) { super._set_data(indices); this.border_radius = resolve.border_radius(this.model.border_radius); } _index_data(index) { const { min, max } = Math; const { data_size } = this; for (let i = 0; i < data_size; i++) { const { l, r, t, b } = this._lrtb(i); index.add_rect(min(l, r), min(t, b), max(r, l), max(t, b)); } } _paint(ctx, indices, data) { const { sleft, sright, stop, sbottom, border_radius } = { ...this, ...data }; for (const i of indices) { const sleft_i = sleft[i]; const stop_i = stop[i]; const sright_i = sright[i]; const sbottom_i = sbottom[i]; if (!isFinite(sleft_i + stop_i + sright_i + sbottom_i)) { continue; } ctx.beginPath(); const box = BBox.from_lrtb({ left: sleft_i, right: sright_i, top: stop_i, bottom: sbottom_i }); round_rect(ctx, box, border_radius); this.visuals.fill.apply(ctx, i); this.visuals.hatch.apply(ctx, i); this.visuals.line.apply(ctx, i); } } // We need to clamp the endpoints inside the viewport, because various browser canvas // implementations have issues drawing rects with endpoints far outside the viewport _clamp_to_viewport() { const { min, max } = Math; const { h_range, v_range } = this.renderer.plot_view.frame.bbox; if (!this.inherited_sleft) { inplace_map(this.sleft, (left) => max(left, h_range.start)); } if (!this.inherited_sright) { inplace_map(this.sright, (right) => min(right, h_range.end)); } if (!this.inherited_stop) { inplace_map(this.stop, (top) => max(top, v_range.start)); } if (!this.inherited_sbottom) { inplace_map(this.sbottom, (bottom) => min(bottom, v_range.end)); } } _hit_rect(geometry) { return this._hit_rect_against_index(geometry); } _hit_point(geometry) { const { sx, sy } = geometry; const x = this.renderer.xscale.invert(sx); const y = this.renderer.yscale.invert(sy); const indices = [...this.index.indices({ x0: x, y0: y, x1: x, y1: y })]; return new Selection({ indices }); } _hit_span(geometry) { const { sx, sy } = geometry; let indices; if (geometry.direction == "v") { const y = this.renderer.yscale.invert(sy); const hr = this.renderer.plot_view.frame.bbox.h_range; const [x0, x1] = this.renderer.xscale.r_invert(hr.start, hr.end); indices = [...this.index.indices({ x0, y0: y, x1, y1: y })]; } else { const x = this.renderer.xscale.invert(sx); const vr = this.renderer.plot_view.frame.bbox.v_range; const [y0, y1] = this.renderer.yscale.r_invert(vr.start, vr.end); indices = [...this.index.indices({ x0: x, y0, x1: x, y1 })]; } return new Selection({ indices }); } draw_legend_for_index(ctx, bbox, index) { generic_area_vector_legend(this.visuals, ctx, bbox, index); } } export class LRTB extends Glyph { static __name__ = "LRTB"; constructor(attrs) { super(attrs); } static { this.mixins([LineVector, FillVector, HatchVector]); this.define(() => ({ border_radius: [BorderRadius, 0], })); } } //# sourceMappingURL=lrtb.js.map