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