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