Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent bokeh from injecting bokeh js multiple times #5795

Merged
merged 10 commits into from Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 1 addition & 3 deletions demo/bokeh_plot/run.py
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removes deprecated bokeh syntax

@@ -1,6 +1,5 @@
import gradio as gr
import xyzservices.providers as xyz
from bokeh.tile_providers import get_provider
from bokeh.models import ColumnDataSource, Whisker
from bokeh.plotting import figure
from bokeh.sampledata.autompg2 import autompg2 as df
Expand All @@ -10,14 +9,13 @@

def get_plot(plot_type):
if plot_type == "map":
tile_provider = get_provider(xyz.OpenStreetMap.Mapnik)
plot = figure(
x_range=(-2000000, 6000000),
y_range=(-1000000, 7000000),
x_axis_type="mercator",
y_axis_type="mercator",
)
plot.add_tile(tile_provider)
plot.add_tile(xyz.OpenStreetMap.Mapnik)
return plot
elif plot_type == "whisker":
classes = list(sorted(df["class"].unique()))
Expand Down
63 changes: 23 additions & 40 deletions js/plot/static/Plot.svelte
Expand Up @@ -18,7 +18,7 @@
export let caption: string;
export let bokeh_version: string | null;
export let show_actions_button: bool;
const divId = `bokehDiv-${Math.random().toString(5).substring(2)}`;
const div_id = `bokehDiv-${Math.random().toString(5).substring(2)}`;

function get_color(index: number): string {
let current_color = colors[index % colors.length];
Expand All @@ -38,32 +38,23 @@
$: plot = value?.plot;
$: type = value?.type;

// Need to keep track of this because
// otherwise embed_bokeh may try to embed before
// bokeh is loaded
$: bokeh_loaded = window.Bokeh === undefined;

function embed_bokeh(
_plot: Record<string, any>,
_type: string,
_bokeh_loaded: boolean
): void {
if (document) {
if (document.getElementById(divId)) {
document.getElementById(divId).innerHTML = "";
if (document.getElementById(div_id)) {
document.getElementById(div_id).innerHTML = "";
}
}
if (_type == "bokeh" && window.Bokeh) {
if (!_bokeh_loaded) {
load_bokeh();
bokeh_loaded = true;
}
load_bokeh();
let plotObj = JSON.parse(_plot);
window.Bokeh.embed.embed_item(plotObj, divId);
window.Bokeh.embed.embed_item(plotObj, div_id);
}
}

$: embed_bokeh(plot, type, bokeh_loaded);
$: embed_bokeh(plot, type);

$: if (type == "altair") {
spec = JSON.parse(plot);
Expand Down Expand Up @@ -108,8 +99,8 @@
}

// Plotly
let plotDiv;
let plotlyGlobalStyle;
let plot_div;
let plotly_global_style;

const main_src = `https://cdn.bokeh.org/bokeh/release/bokeh-${bokeh_version}.min.js`;

Expand All @@ -123,7 +114,6 @@
function load_plugins(): HTMLScriptElement[] {
return plugins_src.map((src, i) => {
const script = document.createElement("script");
script.onload = (): void => initializeBokeh(i + 1);
script.src = src;
document.head.appendChild(script);

Expand All @@ -133,20 +123,22 @@

function load_bokeh(): HTMLScriptElement {
const script = document.createElement("script");
script.onload = handleBokehLoaded;
script.onload = handle_bokeh_loaded;
script.src = main_src;
document.head.appendChild(script);
bokeh_loaded = true;
const is_bokeh_script_present = document.head.querySelector(`script[src="${main_src}"]`);
if (!is_bokeh_script_present) {
document.head.appendChild(script);
}
return script;
}

function load_plotly_css(): void {
if (!plotlyGlobalStyle) {
plotlyGlobalStyle = document.getElementById("plotly.js-style-global");
const plotlyStyleClone = plotlyGlobalStyle.cloneNode();
target.appendChild(plotlyStyleClone);
for (const rule of plotlyGlobalStyle.sheet.cssRules) {
plotlyStyleClone.sheet.insertRule(rule.cssText);
if (!plotly_global_style) {
plotly_global_style = document.getElementById("plotly.js-style-global");
const plotly_style_clone = plotly_global_style.cloneNode();
target.appendChild(plotly_style_clone);
for (const rule of plotly_global_style.sheet.cssRules) {
plotly_style_clone.sheet.insertRule(rule.cssText);
}
}
}
Expand All @@ -155,16 +147,7 @@

let plugin_scripts = [];

const resolves = [];

const initializeBokeh = (index): void => {
if (type == "bokeh") {
resolves[index]();
}
};

function handleBokehLoaded(): void {
initializeBokeh(0);
function handle_bokeh_loaded(): void {
plugin_scripts = load_plugins();
}

Expand All @@ -175,7 +158,7 @@
plotObj.layout.title
? (plotObj.layout.margin = { autoexpand: true })
: (plotObj.layout.margin = { l: 0, r: 0, b: 0, t: 0 });
Plotly.react(plotDiv, plotObj);
Plotly.react(plot_div, plotObj);
}
});

Expand All @@ -188,9 +171,9 @@
</script>

{#if value && type == "plotly"}
<div data-testid={"plotly"} bind:this={plotDiv} />
<div data-testid={"plotly"} bind:this={plot_div} />
{:else if type == "bokeh"}
<div data-testid={"bokeh"} id={divId} class="gradio-bokeh" />
<div data-testid={"bokeh"} id={div_id} class="gradio-bokeh" />
{:else if type == "altair"}
<div data-testid={"altair"} class="altair layout">
<Vega {spec} options={{ actions: show_actions_button }} />
Expand Down