@bokeh/bokehjs
Version:
Interactive, novel data visualization
156 lines (153 loc) • 4.73 kB
JavaScript
import { Annotation, AnnotationView } from "../annotation";
import { display, undisplay } from "../../../core/dom";
import { SideLayout } from "../../../core/layout/side_panel";
import { Padding, BorderRadius } from "../../common/kinds";
import * as resolve from "../../common/resolve";
export class TextAnnotationView extends AnnotationView {
static __name__ = "TextAnnotationView";
text_el;
rendering_target() {
return this.plot_view.canvas_view.overlays_el;
}
update_layout() {
const { panel } = this;
if (panel != null) {
this.layout = new SideLayout(panel, () => this.get_size(), true);
}
else {
this.layout = undefined;
}
}
connect_signals() {
super.connect_signals();
this.connect(this.model.change, () => this.paint(this.layer.ctx));
}
paint(ctx) {
if (!this.model.visible) {
undisplay(this.el);
return;
}
super.paint(ctx);
}
get padding() {
return resolve.padding(this.model.padding);
}
get border_radius() {
return resolve.border_radius(this.model.border_radius);
}
render() {
super.render();
this.text_el = document.createTextNode("");
this.shadow_el.append(this.text_el);
}
_paint_text(ctx, text, sx, sy, angle) {
const { el } = this;
undisplay(el);
this.text_el.textContent = text;
this.visuals.text.set_value(ctx);
const { padding, border_radius } = this;
if (this.layout != null) {
this.position.replace(`
:host {
position: relative;
}
`);
}
else {
const panel = this.plot_view.frame;
const [rsx, rsy] = panel.bbox.relativize(sx, sy);
this.position.replace(`
:host {
position: absolute;
left: ${rsx}px;
top: ${rsy}px;
}
`);
}
this.style.replace(`
:host {
width: max-content;
height: max-content;
color: ${ctx.fillStyle};
-webkit-text-stroke: 1px ${ctx.strokeStyle};
font: ${ctx.font};
white-space: pre;
padding-left: ${padding.left}px;
padding-right: ${padding.right}px;
padding-top: ${padding.top}px;
padding-bottom: ${padding.bottom}px;
border-top-left-radius: ${border_radius.top_left}px;
border-top-right-radius: ${border_radius.top_right}px;
border-bottom-right-radius: ${border_radius.bottom_right}px;
border-bottom-left-radius: ${border_radius.bottom_left}px;
}
`);
if (this.layout != null) {
if (angle != 0) {
this.style.append(`
:host {
writing-mode: vertical-rl;
rotate: 180deg;
align-self: end;
}
`);
}
}
else {
const x_anchor = (() => {
switch (this.visuals.text.text_align.get_value()) {
case "left": return "0%";
case "center": return "50%";
case "right": return "100%";
}
})();
const y_anchor = (() => {
switch (this.visuals.text.text_baseline.get_value()) {
case "top": return "0%";
case "middle": return "50%";
case "bottom": return "100%";
default: return "50%"; // "baseline"
}
})();
this.style.append(`
:host {
transform-origin: ${x_anchor} ${y_anchor};
transform: translate(-${x_anchor}, -${y_anchor}) rotate(${angle}rad);
}
`);
}
if (this.visuals.background_fill.doit) {
this.visuals.background_fill.set_value(ctx);
this.style.append(`
:host {
background-color: ${ctx.fillStyle};
}
`);
}
if (this.visuals.border_line.doit) {
this.visuals.border_line.set_value(ctx);
// attempt to support vector-style ("8 4 8") line dashing for css mode
this.style.append(`
:host {
border-style: ${ctx.getLineDash().length < 2 ? "solid" : "dashed"};
border-width: ${ctx.lineWidth}px;
border-color: ${ctx.strokeStyle};
}
`);
}
display(el);
}
}
export class TextAnnotation extends Annotation {
static __name__ = "TextAnnotation";
constructor(attrs) {
super(attrs);
}
static {
this.define(() => ({
padding: [Padding, 0],
border_radius: [BorderRadius, 0],
}));
}
}
//# sourceMappingURL=text_annotation.js.map