Hi,
I am currently working on a Bokeh server app that needs to render text with custom CSS inside a plot in real time. I tried to do this with a Glyph Text object, however the styling attributes currently available are too limited. So I tried to make a Bokeh extension for it according to issue 6977, but I couldn’t gather exactly how to do that after reading the documentation.
I want to make an extension with custom CSS that displays text in the main plot through a CustomDataSource object, but I don’t know exactly how to add it to the plot. The custom extension class currently inherits from LayoutDOM, and contains an Instance(ColumnDataSource) object as an attribute. What I want to know is, what method do I need to call to add this custom class to the main plot? I’ve tried add_layout(), add_tools() and add_glyph() so far, but those didn’t work.
Here is my code for the extension:
class Custom(LayoutDOM, Renderer):
“”“Custom text class so CSS can be applied to it.”""
implementation = “custom.ts”
source = Instance(ColumnDataSource)
``
Here is my TypeScript for the extension (taken mostly from the example in the Extending Bokeh documentation):
import {div, empty} from “core/dom”
import * as p from “core/properties”
import {LayoutDOM, LayoutDOMView} from “models/layouts/layout_dom”
export class CustomView extends LayoutDOMView {
initialize(options) {
super.initialize(options)
this.render()
// Set BokehJS listener so that when the Bokeh slider has a change
// event, we can process the new data
// this.connect(this.model.slider.change, () => this.render())
}
render() {
// BokehjS Views create
// this.el
. Many Bokeh views ignore this default
// do things like draw to the HTML canvas. In this case though, we change
// the contents of the
empty(this.el)
for (var _i = 0; i < this.model.x.length; _i++ ) {
this.el.appendChild(div({
style: {
‘padding’: ‘1px’,
‘color’: ‘#000000’,
‘text-shadow’: ‘-1px 0 white, 0 1px white, 1px 0 white, 0 -1px white’,
},
}, ${this.model.source.text}
))
}
// this.el.appendChild(div({
// style: {
// ‘padding’: ‘2px’,
// ‘color’: ‘#000000’,
// ‘text-shadow’: ‘-1px 0 white, 0 1px white, 1px 0 white, 0 -1px white’;
// },
// }, ${this.model.text}: ${this.model.text}
))
}
}
export class Custom extends LayoutDOM {
// If there is an associated view, this is typically boilerplate.
default_view = CustomView
// The type
class attribute should generally match exactly the name
// of the corresponding Python class.
type = “Custom”
}
// The @define block adds corresponding “properties” to the JS model. These
// should normally line up 1-1 with the Python model class. Most property
// types have counterparts, e.g. bokeh.core.properties.String will be
// p.String
in the JS implementation. Any time the JS type system is not
// yet as complete, you can use p.Any
as a “wildcard” property type.
Custom.define({
source: [ p.Any ],
})
``
Would really appreciate some help on how to make this work. Thank you!
Regards,
Shreya Gupta