UNPKG

@bokeh/bokehjs

Version:

Interactive, novel data visualization

167 lines 7.05 kB
import { BaseGLGlyph } from "./base"; import { Float32Buffer, NormalizedUint8Buffer, Uint8Buffer } from "./buffer"; import { resolve_line_dash } from "../../../core/visuals/line"; export class BaseLineGL extends BaseGLGlyph { glyph; static __name__ = "BaseLineGL"; _antialias = 1.5; // Make this larger to test antialiasing at edges. _miter_limit = 10.0; // Threshold for miters to be replaced by bevels. // data properties _points; _show; // Applies to segments not points. // visual properties _linewidth = new Float32Buffer(this.regl_wrapper); _line_color = new NormalizedUint8Buffer(this.regl_wrapper, 4); _line_cap = new Uint8Buffer(this.regl_wrapper); _line_join = new Uint8Buffer(this.regl_wrapper); _is_dashed = false; // visual properties that are only used if line is dashed. _length_so_far; // Depends on both data and visuals. _dash_tex = []; _dash_tex_info; _dash_scale; _dash_offset; constructor(regl_wrapper, glyph) { super(regl_wrapper, glyph); this.glyph = glyph; } _draw_single(main_gl_glyph, transform, line_offset, point_offset, nsegments, framebuffer, show = null) { const solid_props = { scissor: this.regl_wrapper.scissor, viewport: this.regl_wrapper.viewport, canvas_size: [transform.width, transform.height], antialias: this._antialias / transform.pixel_ratio, miter_limit: this._miter_limit, points: main_gl_glyph._points, show: show ?? main_gl_glyph._show, nsegments, linewidth: this._linewidth, line_color: this._line_color, line_cap: this._line_cap, line_join: this._line_join, framebuffer, point_offset, line_offset, }; if (this._is_dashed && this._dash_tex[line_offset] != null) { const dashed_props = { ...solid_props, length_so_far: main_gl_glyph._length_so_far, dash_tex: this._dash_tex[line_offset], dash_tex_info: this._dash_tex_info, dash_scale: this._dash_scale, dash_offset: this._dash_offset, }; this.regl_wrapper.dashed_line()(dashed_props); } else { this.regl_wrapper.solid_line()(solid_props); } } _set_length_single(length_so_far, points, show) { // Set length so far for a single line from the points and show flags for that line. // Only needed if line is dashed. const nsegments = length_so_far.length; let length = 0.0; for (let i = 0; i < nsegments; i++) { length_so_far[i] = length; if (show[i + 1] == 1) { length += Math.sqrt((points[2 * i + 4] - points[2 * i + 2]) ** 2 + (points[2 * i + 5] - points[2 * i + 3]) ** 2); } else { // Reset to zero at invalid point. length = 0.0; } } } _set_points_single(points, sx, sy) { // Set points array for a single line. const npoints = points.length / 2 - 2; const is_closed = (npoints > 2 && sx[0] == sx[npoints - 1] && sy[0] == sy[npoints - 1] && isFinite(sx[0] + sy[0])); for (let i = 1; i < npoints + 1; i++) { points[2 * i] = sx[i - 1]; points[2 * i + 1] = sy[i - 1]; } if (is_closed) { points[0] = points[2 * npoints - 2]; // Last but one point. points[1] = points[2 * npoints - 1]; points[2 * npoints + 2] = points[4]; // Second point. points[2 * npoints + 3] = points[5]; } else { points[0] = 0.0; points[1] = 0.0; points[2 * npoints + 2] = 0.0; points[2 * npoints + 3] = 0.0; } } _set_show_single(show, points) { // Set show flags for a single line from the points of that line. // Do not show line segments which have a NaN coordinate at either end, and // also take account of line being closed (start and end points identical). const npoints = points.length / 2 - 2; let start_finite = isFinite(points[2] + points[3]); for (let i = 1; i < npoints; i++) { const end_finite = isFinite(points[2 * i + 2] + points[2 * i + 3]); show[i] = (start_finite && end_finite) ? 1 : 0; start_finite = end_finite; } const is_closed = npoints > 2 && points[0] == points[2 * npoints - 2] && points[1] == points[2 * npoints - 1]; if (is_closed) { show[0] = show[npoints - 1]; show[npoints] = show[1]; } else { show[0] = 0; show[npoints] = 0; } } _set_visuals() { const line_visuals = this._get_visuals(); this._line_color.set_from_color(line_visuals.line_color, line_visuals.line_alpha); this._linewidth.set_from_prop(line_visuals.line_width); this._line_cap.set_from_line_cap(line_visuals.line_cap); this._line_join.set_from_line_join(line_visuals.line_join); const { line_dash } = line_visuals; this._is_dashed = !(line_dash.is_Scalar() && line_dash.get(0).length == 0); if (this._is_dashed) { if (this._dash_offset == null) { this._dash_offset = new Float32Buffer(this.regl_wrapper); } this._dash_offset.set_from_prop(line_visuals.line_dash_offset); const n = line_dash.length; if (this._dash_tex_info == null) { this._dash_tex_info = new Float32Buffer(this.regl_wrapper, 4); } const dash_tex_info = this._dash_tex_info.get_sized_array(4 * n); if (this._dash_scale == null) { this._dash_scale = new Float32Buffer(this.regl_wrapper); } const dash_scale = this._dash_scale.get_sized_array(n); // All other dash properties are assumed vector rather than scalar. for (let i = 0; i < n; i++) { const arr = resolve_line_dash(line_dash.get(i)); if (arr.length > 0) { // This line is dashed const [tex_info, tex, scale] = this.regl_wrapper.get_dash(arr); this._dash_tex.push(tex); for (let j = 0; j < 4; j++) { dash_tex_info[4 * i + j] = tex_info[j]; } dash_scale[i] = scale; } else { // This line is solid this._dash_tex.push(null); dash_tex_info.fill(0, 4 * i, 4 * (i + 1)); dash_scale[i] = 0; } } this._dash_tex_info.update(); this._dash_scale.update(); } } } //# sourceMappingURL=base_line.js.map