@bokeh/bokehjs
Version:
Interactive, novel data visualization
149 lines • 5.39 kB
JavaScript
import { TextAnnotation, TextAnnotationView } from "./text_annotation";
import { VerticalAlign, TextAlign } from "../../../core/enums";
import { TextBox } from "../../../core/graphics";
import * as mixins from "../../../core/property_mixins";
export class HTMLTitleView extends TextAnnotationView {
static __name__ = "HTMLTitleView";
_get_location() {
const hmargin = this.model.offset;
const vmargin = this.model.standoff / 2;
let sx, sy;
const { bbox } = this.layout;
switch (this.panel.side) {
case "above":
case "below": {
switch (this.model.vertical_align) {
case "top":
sy = bbox.top + vmargin;
break;
case "middle":
sy = bbox.vcenter;
break;
case "bottom":
sy = bbox.bottom - vmargin;
break;
}
switch (this.model.align) {
case "left":
sx = bbox.left + hmargin;
break;
case "center":
sx = bbox.hcenter;
break;
case "right":
sx = bbox.right - hmargin;
break;
}
break;
}
case "left": {
switch (this.model.vertical_align) {
case "top":
sx = bbox.left + vmargin;
break;
case "middle":
sx = bbox.hcenter;
break;
case "bottom":
sx = bbox.right - vmargin;
break;
}
switch (this.model.align) {
case "left":
sy = bbox.bottom - hmargin;
break;
case "center":
sy = bbox.vcenter;
break;
case "right":
sy = bbox.top + hmargin;
break;
}
break;
}
case "right": {
switch (this.model.vertical_align) {
case "top":
sx = bbox.right - vmargin;
break;
case "middle":
sx = bbox.hcenter;
break;
case "bottom":
sx = bbox.left + vmargin;
break;
}
switch (this.model.align) {
case "left":
sy = bbox.top + hmargin;
break;
case "center":
sy = bbox.vcenter;
break;
case "right":
sy = bbox.bottom - hmargin;
break;
}
break;
}
}
return [sx, sy];
}
_paint(ctx) {
const { text } = this.model;
if (text.length == 0) {
return;
}
this.model.text_baseline = this.model.vertical_align;
this.model.text_align = this.model.align;
const [sx, sy] = this._get_location();
const angle = this.panel.get_label_angle_heuristic("parallel");
this._paint_text(ctx, text, sx, sy, angle);
}
// XXX: this needs to use CSS computed styles
_get_size() {
const { text } = this.model;
const graphics = new TextBox({ text });
graphics.visuals = this.visuals.text.values();
const size = graphics.size();
const { padding } = this;
const width = size.width + padding.left + padding.right;
const height = size.height + padding.top + padding.bottom;
// XXX: The magic 2px is for backwards compatibility. This will be removed at
// some point, but currently there is no point breaking half of visual tests.
return { width, height: height == 0 ? 0 : 2 + height + this.model.standoff };
}
}
export class HTMLTitle extends TextAnnotation {
static __name__ = "HTMLTitle";
constructor(attrs) {
super(attrs);
}
static {
this.prototype.default_view = HTMLTitleView;
this.mixins([
mixins.Text,
["border_", mixins.Line],
["background_", mixins.Fill],
["background_", mixins.Hatch],
]);
this.define(({ Float, Str }) => ({
text: [Str, ""],
vertical_align: [VerticalAlign, "bottom"],
align: [TextAlign, "left"],
offset: [Float, 0],
standoff: [Float, 10],
}));
this.prototype._props.text_align.options.internal = true;
this.prototype._props.text_baseline.options.internal = true;
this.override({
text_font_size: "13px",
text_font_style: "bold",
text_line_height: 1.0,
background_fill_color: null,
background_hatch_color: null,
border_line_color: null,
});
}
}
//# sourceMappingURL=title.js.map