and\n",
" // instead do things like draw to the HTML canvas. In this case though,\n",
" // the program changes the contents of the
based on the current\n",
" // slider value.\n",
" super.render()\n",
"\n",
" this.content_el = div({style: {\n",
" textAlign: \"center\",\n",
" fontSize: \"1.2em\",\n",
" padding: \"2px\",\n",
" color: \"#b88d8e\",\n",
" backgroundColor: \"#2a3153\",\n",
" }})\n",
" this.shadow_el.appendChild(this.content_el)\n",
"\n",
" this._update_text()\n",
" }\n",
"\n",
" private _update_text(): void {\n",
" this.content_el.textContent = `${this.model.text}: ${this.model.slider.value}`\n",
" }\n",
"}\n",
"\n",
"export namespace Custom {\n",
" export type Attrs = p.AttrsOf
\n",
"\n",
" export type Props = UIElement.Props & {\n",
" text: p.Property\n",
" slider: p.Property\n",
" }\n",
"}\n",
"\n",
"export interface Custom extends Custom.Attrs {}\n",
"\n",
"export class Custom extends UIElement {\n",
" properties: Custom.Props\n",
" __view_type__: CustomView\n",
"\n",
" constructor(attrs?: Partial) {\n",
" super(attrs)\n",
" }\n",
"\n",
" static {\n",
" // If there is an associated view, this is typically boilerplate.\n",
" this.prototype.default_view = CustomView\n",
"\n",
" // The this.define() block adds corresponding \"properties\" to the JS\n",
" // model. These should normally line up 1-1 with the Python model\n",
" // class. Most property types have counterparts. For example,\n",
" // bokeh.core.properties.String will correspond to ``String`` in the\n",
" // JS implementation. Where JS lacks a given type, you can use\n",
" // ``p.Any`` as a \"wildcard\" property type.\n",
" this.define(({String, Ref}) => ({\n",
" text: [ String, \"Custom text\" ],\n",
" slider: [ Ref(Slider) ],\n",
" }))\n",
" }\n",
"}\n",
"\"\"\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Define the Python Model\n",
"\n",
"This JavaScript implementation is then attached to a corresponding Python Bokeh model:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from bokeh.core.properties import Instance, Required, String\n",
"\n",
"class Custom(UIElement):\n",
"\n",
" __implementation__ = TypeScript(CODE)\n",
"\n",
" text = String(default=\"Custom text\")\n",
"\n",
" slider = Required(Instance(Slider))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Use the Python Model\n",
"\n",
"Then the new model can be used seamlessly in the same way as any built-in Bokeh model:"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from bokeh.io import show, output_file\n",
"from bokeh.layouts import column\n",
"from bokeh.models import Slider\n",
"\n",
"slider = Slider(start=0, end=10, step=0.1, value=0, title=\"value\")\n",
"\n",
"custom = Custom(text=\"Special Slider Display\", slider=slider)\n",
"\n",
"layout = column(slider, custom)\n",
"\n",
"show(layout)\n",
"\n",
"# Necessary to explicitly reload BokehJS to pick up new extension code\n",
"output_notebook()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"show(layout)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Next Section"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To explore the next topic in the appendices, click on this link: [A2 - Visualizing Big Data with Datashader](A2%20-%20Visualizing%20Big%20Data%20with%20Datashader.ipynb)\n",
"\n",
"To go back to the overview, click [here](00%20-%20Introduction%20and%20Setup.ipynb)."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"anaconda-cloud": {},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.13"
}
},
"nbformat": 4,
"nbformat_minor": 4
}