Embed a new Bokeh model/root into an existing Bokeh document using BokehJS, but render it inside a specific target div element

How can I embed a new Bokeh model/root into an existing Bokeh document using BokehJS, but render it inside a specific target div element on my HTML page?

How can I achieve this using BokehJS? Any code examples or pointers would be greatly appreciated.

           // Selecting existing  ajaxdatasource , model, doc 

            var existing_model=Bokeh.index['EURUSD M1'].model;
            var existing_ajax_source = exsisting_model.select(name="price_bullet")[0].data_source
            var existing_doc = Bokeh.documents[0];

            // Creating a new model

            new_model = Bokeh.Plotting.figure({
                title: 'Example of random data',
                tools: "pan,wheel_zoom,box_zoom,reset,save",
                sizing_mode:'stretch_both',
                x_axis_type:"datetime",
                'x_range': existing_model.x_range,
                'y_range': existing_model.y_range,

            });

            // Defining glyph 

            const line = new Bokeh.Line({
                x: { field: "time" },
                y: { field: "close" },
                line_color: "blue",
                line_width: 2
            });

            new_model.add_glyph(line, existing_ajax_source);



            //Adding a new grid with a target div inside

            grid.addWidget({
                        w: 6,
                        h: 3,
                        content:`
                        <div style=border: 2px solid transparent;border-radius: 10px, background-color: #f1f1f1;' class='grid-stack-item-content'>
                            <div id='newdiv' data-root-id='newdiv' style='display: contents;'></div>
                         </div>`,
                    });

            var newDiv = document.getElementById('newdiv');

            // ?? how can i embed new model to existing_doc and target div "newDiv" ?

with this line I can add the figure to the existing document but I can’t point to the div I want.

// js code 
 existing_doc.add_root(new_model)

cc @mateusz I am not sure how this could be accomplished with present APIs

We don’t have an APIs for this. However, one can move the host element of a root model’s view after creation. Something like this:

new_target_el.append(Bokeh.index[new_model.id].el)

You don’t even have to remove it, as it will be effectively a move between two elements. Since Bokeh 3.0, all components are self-contained, so you don’t have to care about setting right CSS classes or styles on the new target, as it used to be done in Bokeh 2.x.

I would suggest starting a new feature issue for this.

2 Likes

Thank you very much @Bryan @mateusz , it worked perfectly for me, although I had to set a small interval to give time to bokeh.index to add the new key to find the new root.
Ok here is my solution:

new_model.id = "rsi";
//hides the model until it is not in the expected div
new_model.visible = false;
//Add the model to the root
Bokeh.documents[0].add_root(new_model);
// Wait for the key to be in the index , append model to the target div and make plot visible
waitForIndex(new_model,"mydivID")

function waitForIndex(figure,div_id) {

    if (Bokeh.index[figure.id] !== undefined) {
        
        divEl = document.getElementById(div_id);
        divEl.append(Bokeh.index[figure.id].el)

        figure.visible = true
        console.log("plot added to the doc and target div")
        
 

    } else {
        setTimeout(() => waitForIndex(figure,div_id), 10);
    }
}


2 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.