UNPKG

@bokeh/bokehjs

Version:

Interactive, novel data visualization

119 lines 4.02 kB
import { Glyph, GlyphView } from "./glyph"; import { generic_line_vector_legend } from "./utils"; import { Selection } from "../selections/selection"; import { LineVector } from "../../core/property_mixins"; import * as uniforms from "../../core/uniforms"; import { map } from "../../core/util/arrayable"; import { range } from "../../core/util/array"; import * as p from "../../core/properties"; const { abs, max } = Math; const UNUSED = 0; export class HSpanView extends GlyphView { static __name__ = "HSpanView"; after_visuals() { super.after_visuals(); this.max_line_width = uniforms.max(this.line_width); } _index_data(index) { for (const y_i of this.y) { index.add_point(UNUSED, y_i); } } _bounds(bounds) { const { y0, y1 } = bounds; return { x0: NaN, x1: NaN, y0, y1 }; } _map_data() { super._map_data(); const { round } = Math; if (!this.inherited_sy) { const sy = map(this.sy, (yi) => round(yi)); this._define_attr("sy", sy); } } scenterxy(i) { const { hcenter } = this.renderer.plot_view.frame.bbox; return [hcenter, this.sy[i]]; } _paint(ctx, indices, data) { const { sy } = { ...this, ...data }; const { left, right } = this.renderer.plot_view.frame.bbox; for (const i of indices) { const sy_i = sy[i]; if (!isFinite(sy_i)) { continue; } ctx.beginPath(); ctx.moveTo(left, sy_i); ctx.lineTo(right, sy_i); this.visuals.line.apply(ctx, i); } } _get_candidates(sy0, sy1) { const { max_line_width } = this; const [y0, y1] = this.renderer.yscale.r_invert(sy0 - max_line_width, (sy1 ?? sy0) + max_line_width); return this.index.indices({ x0: 0, x1: 0, y0, y1 }); } _find_spans(candidates, fn) { const { sy, line_width } = this; const indices = []; for (const i of candidates) { const sy_i = sy[i]; const line_width_i = line_width.get(i); if (fn(sy_i, line_width_i)) { indices.push(i); } } return indices; } _hit_point(geometry) { const { sy: gsy } = geometry; const candidates = this._get_candidates(gsy); const indices = this._find_spans(candidates, (sy, line_width) => { return abs(sy - gsy) <= max(line_width / 2, 2 /*px*/); }); return new Selection({ indices }); } _hit_span(geometry) { const indices = (() => { if (geometry.direction == "v") { return range(0, this.data_size); } else { const { sy: gsy } = geometry; const candidates = this._get_candidates(gsy); return this._find_spans(candidates, (sy, line_width) => { return abs(sy - gsy) <= max(line_width / 2, 2 /*px*/); }); } })(); return new Selection({ indices }); } _hit_rect(geometry) { const indices = (() => { const { sy0: gsy0, sy1: gsy1 } = geometry; const candidates = this._get_candidates(gsy0, gsy1); return this._find_spans(candidates, (sy, line_width) => { return gsy0 - line_width / 2 <= sy && sy <= gsy1 + line_width / 2; }); })(); return new Selection({ indices }); } draw_legend_for_index(ctx, bbox, index) { generic_line_vector_legend(this.visuals, ctx, bbox, index); } } export class HSpan extends Glyph { static __name__ = "HSpan"; constructor(attrs) { super(attrs); } static { this.prototype.default_view = HSpanView; this.mixins([LineVector]); this.define(() => ({ y: [p.YCoordinateSpec, { field: "y" }], })); } } //# sourceMappingURL=hspan.js.map