from bokeh.util.compiler import TypeScript from bokeh.models import Label TS_CODE = """ import * as p from "core/properties" import {Label, LabelView} from "models/annotations/label" declare const katex: any export class LatexLabelView extends LabelView { model: LatexLabel render(): void { //--- Start of copied section from ``Label.render`` implementation // Here because AngleSpec does units tranform and label doesn't support specs let angle: number switch (this.model.angle_units) { case "rad": { angle = -this.model.angle break } case "deg": { angle = (-this.model.angle * Math.PI) / 180.0 break } default: throw new Error("unreachable code") } const panel = this.panel != null ? this.panel : this.plot_view.frame const xscale = this.plot_view.frame.xscales[this.model.x_range_name] const yscale = this.plot_view.frame.yscales[this.model.y_range_name] let sx = this.model.x_units == "data" ? xscale.compute(this.model.x) : panel.xview.compute(this.model.x) let sy = this.model.y_units == "data" ? yscale.compute(this.model.y) : panel.yview.compute(this.model.y) sx += this.model.x_offset sy -= this.model.y_offset //--- End of copied section from ``Label.render`` implementation // Must render as superpositioned div (not on canvas) so that KaTex // css can properly style the text this._css_text(this.plot_view.canvas_view.ctx, "", sx, sy, angle) // ``katex`` is loaded into the global window at runtime // katex.renderToString returns a html ``span`` element katex.render(this.model.text, this.el, {displayMode: true}) } } export namespace LatexLabel { export type Attrs = p.AttrsOf export type Props = Label.Props } export interface LatexLabel extends LatexLabel.Attrs {} export class LatexLabel extends Label { properties: LatexLabel.Props constructor(attrs?: Partial) { super(attrs) } static init_LatexLabel() { this.prototype.default_view = LatexLabelView } } """ class LatexLabel(Label): """A subclass of the Bokeh built-in `Label` that supports rendering LaTex using the KaTex typesetting library. Only the render method of LabelView is overloaded to perform the text -> latex (via katex) conversion. Note: ``render_mode="canvas`` isn't supported and certain DOM manipulation happens in the Label superclass implementation that requires explicitly setting `render_mode='css'`). """ __javascript__ = ["https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.js"] __css__ = ["https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.css"] __implementation__ = TypeScript(TS_CODE)