UNPKG

@bokeh/bokehjs

Version:

Interactive, novel data visualization

235 lines 7.03 kB
import { Sizeable } from "./types"; import { ContentLayoutable } from "./layoutable"; import { isString } from "../util/types"; // This table lays out the rules for configuring the baseline, alignment, etc. of // title text, based on it's location and orientation // // side orient baseline align angle normal-dist // ------------------------------------------------------------------------------ // above parallel bottom center 0 height // normal middle left -90 width // horizontal bottom center 0 height // [angle > 0] middle left width * sin + height * cos // [angle < 0] middle right width * sin + height * cos // // below parallel top center 0 height // normal middle right 90 width // horizontal top center 0 height // [angle > 0] middle right width * sin + height * cos // [angle < 0] middle left width * sin + height * cos // // left parallel bottom center 90 height // normal middle right 0 width // horizontal middle right 0 width // [angle > 0] middle right width * cos + height * sin // [angle < 0] middle right width * cos + height + sin // // right parallel bottom center -90 height // normal middle left 0 width // horizontal middle left 0 width // [angle > 0] middle left width * cos + height * sin // [angle < 0] middle left width * cos + height + sin const pi2 = Math.PI / 2; const _angle_lookup = { above: { parallel: 0, normal: -pi2, horizontal: 0, vertical: -pi2, }, below: { parallel: 0, normal: pi2, horizontal: 0, vertical: pi2, }, left: { parallel: -pi2, normal: 0, horizontal: 0, vertical: -pi2, }, right: { parallel: pi2, normal: 0, horizontal: 0, vertical: pi2, }, }; const _vertical_align_lookup = { above: { parallel: "bottom", normal: "center", horizontal: "bottom", vertical: "center", }, below: { parallel: "top", normal: "center", horizontal: "top", vertical: "center", }, left: { parallel: "bottom", normal: "center", horizontal: "center", vertical: "bottom", }, right: { parallel: "bottom", normal: "center", horizontal: "center", vertical: "bottom", }, }; const _align_lookup = { above: { parallel: "center", normal: "left", horizontal: "center", vertical: "left", }, below: { parallel: "center", normal: "left", horizontal: "center", vertical: "left", }, left: { parallel: "center", normal: "right", horizontal: "right", vertical: "center", }, right: { parallel: "center", normal: "left", horizontal: "left", vertical: "center", }, }; const _align_lookup_negative = { above: "right", below: "left", left: "right", right: "left", }; const _align_lookup_positive = { above: "left", below: "right", left: "right", right: "left", }; export class SidePanel { side; static __name__ = "SidePanel"; face; dimension; orientation; is_horizontal; is_vertical; normals; constructor(side, face) { this.side = side; this.face = (() => { if (face != null && face != "auto") { return face; } else { switch (this.side) { case "left": case "above": return "front"; case "right": case "below": return "back"; } } })(); this.dimension = this.side == "above" || this.side == "below" ? 0 : 1; this.orientation = this.dimension == 0 ? "horizontal" : "vertical"; this.is_horizontal = this.dimension == 0; this.is_vertical = this.dimension == 1; this.normals = (() => { const sign = this.face == "front" ? -1 : 1; switch (this.side) { case "left": return [sign, 0]; case "right": return [sign, 0]; case "above": return [0, sign]; case "below": return [0, sign]; } })(); } get face_adjusted_side() { const { side, face } = this; switch (side) { case "left": case "right": return face == "front" ? "left" : "right"; case "above": case "below": return face == "front" ? "above" : "below"; } } get_label_text_heuristics(orient) { const side = this.face_adjusted_side; if (isString(orient)) { return { vertical_align: _vertical_align_lookup[side][orient], align: _align_lookup[side][orient], }; } else { return { vertical_align: "center", align: (orient < 0 ? _align_lookup_negative : _align_lookup_positive)[side], }; } } get_label_angle_heuristic(orient) { if (isString(orient)) { const side = this.face_adjusted_side; return _angle_lookup[side][orient]; } else { return -orient; } } } export class SideLayout extends ContentLayoutable { panel; get_size; rotate; static __name__ = "SideLayout"; constructor(panel, get_size, rotate = false) { super(); this.panel = panel; this.get_size = get_size; this.rotate = rotate; if (this.panel.is_horizontal) { this.set_sizing({ width_policy: "max", height_policy: "fixed" }); } else { this.set_sizing({ width_policy: "fixed", height_policy: "max" }); } } _content_size() { const { width, height } = this.get_size(); if (!this.rotate || this.panel.is_horizontal) { return new Sizeable({ width, height }); } else { return new Sizeable({ width: height, height: width }); } } has_size_changed() { const { width, height } = this._content_size(); if (this.panel.is_horizontal) { return this.bbox.height != height; } else { return this.bbox.width != width; } } } //# sourceMappingURL=side_panel.js.map