We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
examples/howto/{js_events,events_app} contain bad CSS
* https://github.com/bokeh/bokeh/blob/master/examples/howto/js_events.py#L19
* https://github.com/bokeh/bokeh/blob/master/examples/howto/events_app.py#L21
* the same in user_guide

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `examples/howto/events_app.py`
Content:
```
1 """ Demonstration Bokeh app of how to register event callbacks in both
2 Javascript and Python using an adaptation of the color_scatter example
3 from the bokeh gallery. This example extends the js_events.py example
4 with corresponding Python event callbacks.
5 """
6 
7 import numpy as np
8 
9 from bokeh.io import curdoc
10 from bokeh.plotting import figure
11 from bokeh import events
12 from bokeh.models import CustomJS, Div, Button
13 from bokeh.layouts import column, row
14 
15 
16 def display_event(div, attributes=[]):
17     """
18     Function to build a suitable CustomJS to display the current event
19     in the div model.
20     """
21     style = 'float:left;clear:left;font_size=0.5pt'
22     return CustomJS(args=dict(div=div), code="""
23         var attrs = %s;
24         var args = [];
25         for (var i=0; i<attrs.length; i++ ) {
26             val = JSON.stringify(cb_obj[attrs[i]], function(key, val) {
27                 return val.toFixed ? Number(val.toFixed(2)) : val;
28             })
29             args.push(attrs[i] + '=' + val)
30         }
31         var line = "<span style=%r><b>" + cb_obj.event_name + "</b>(" + args.join(", ") + ")</span>\\n";
32         var text = div.text.concat(line);
33         var lines = text.split("\\n")
34         if ( lines.length > 35 ) { lines.shift(); }
35         div.text = lines.join("\\n");
36     """ % (attributes, style))
37 
38 def print_event(attributes=[]):
39     """
40     Function that returns a Python callback to pretty print the events.
41     """
42     def python_callback(event):
43         cls_name = event.__class__.__name__
44         attrs = ', '.join(['{attr}={val}'.format(attr=attr, val=event.__dict__[attr])
45                        for attr in attributes])
46         print('{cls_name}({attrs})'.format(cls_name=cls_name, attrs=attrs))
47     return python_callback
48 
49 # Follows the color_scatter gallery example
50 
51 N = 4000
52 x = np.random.random(size=N) * 100
53 y = np.random.random(size=N) * 100
54 radii = np.random.random(size=N) * 1.5
55 colors = [
56     "#%02x%02x%02x" % (int(r), int(g), 150) for r, g in zip(50+2*x, 30+2*y)
57 ]
58 
59 p = figure(tools="pan,wheel_zoom,zoom_in,zoom_out,reset,tap,lasso_select,box_select")
60 
61 p.scatter(x, y, radius=radii,
62           fill_color=colors, fill_alpha=0.6,
63           line_color=None)
64 
65 # Add a div to display events and a button to trigger button click events
66 
67 div = Div(width=1000)
68 button = Button(label="Button", button_type="success")
69 layout = column(button, row(p, div))
70 
71 
72 point_attributes = ['x','y','sx','sy']
73 pan_attributes = point_attributes + ['delta_x', 'delta_y']
74 pinch_attributes = point_attributes + ['scale']
75 wheel_attributes = point_attributes+['delta']
76 
77 ## Register Javascript event callbacks
78 
79 # Button event
80 button.js_on_event(events.ButtonClick, display_event(div))
81 
82 # LOD events
83 p.js_on_event(events.LODStart, display_event(div))
84 p.js_on_event(events.LODEnd,   display_event(div))
85 
86 # Point events
87 
88 p.js_on_event(events.Tap,       display_event(div, attributes=point_attributes))
89 p.js_on_event(events.DoubleTap, display_event(div, attributes=point_attributes))
90 p.js_on_event(events.Press,     display_event(div, attributes=point_attributes))
91 
92 # Mouse wheel event
93 p.js_on_event(events.MouseWheel, display_event(div,attributes=wheel_attributes))
94 
95 # Mouse move, enter and leave
96 p.js_on_event(events.MouseMove,  display_event(div, attributes=point_attributes))
97 p.js_on_event(events.MouseEnter, display_event(div, attributes=point_attributes))
98 p.js_on_event(events.MouseLeave, display_event(div, attributes=point_attributes))
99 
100 # Pan events
101 p.js_on_event(events.Pan,      display_event(div, attributes=pan_attributes))
102 p.js_on_event(events.PanStart, display_event(div, attributes=point_attributes))
103 p.js_on_event(events.PanEnd,   display_event(div, attributes=point_attributes))
104 
105 # Pinch events
106 p.js_on_event(events.Pinch,      display_event(div, attributes=pinch_attributes))
107 p.js_on_event(events.PinchStart, display_event(div, attributes=point_attributes))
108 p.js_on_event(events.PinchEnd,   display_event(div, attributes=point_attributes))
109 
110 # Selection events
111 p.js_on_event(events.SelectionGeometry, display_event(div, attributes=['geometry', 'final']))
112 
113 # Reset events
114 p.js_on_event(events.Reset, display_event(div))
115 
116 
117 ## Register Python event callbacks
118 
119 # Button event
120 button.on_event(events.ButtonClick, print_event())
121 
122 # LOD events
123 p.on_event(events.LODStart, print_event())
124 p.on_event(events.LODEnd,   print_event())
125 
126 # Point events
127 
128 p.on_event(events.Tap,       print_event(attributes=point_attributes))
129 p.on_event(events.DoubleTap, print_event(attributes=point_attributes))
130 p.on_event(events.Press,     print_event(attributes=point_attributes))
131 
132 # Mouse wheel event
133 p.on_event(events.MouseWheel, print_event(attributes=wheel_attributes))
134 
135 # Mouse move, enter and leave
136 p.on_event(events.MouseMove,  print_event(attributes=point_attributes))
137 p.on_event(events.MouseEnter, print_event(attributes=point_attributes))
138 p.on_event(events.MouseLeave, print_event(attributes=point_attributes))
139 
140 # Pan events
141 p.on_event(events.Pan,      print_event(attributes=pan_attributes))
142 p.on_event(events.PanStart, print_event(attributes=point_attributes))
143 p.on_event(events.PanEnd,   print_event(attributes=point_attributes))
144 
145 # Pinch events
146 p.on_event(events.Pinch,      print_event(attributes=pinch_attributes))
147 p.on_event(events.PinchStart, print_event(attributes=point_attributes))
148 p.on_event(events.PinchEnd,   print_event(attributes=point_attributes))
149 
150 # Selection events
151 p.on_event(events.SelectionGeometry, print_event(attributes=['geometry', 'final']))
152 
153 # Reset events
154 p.on_event(events.Reset, print_event())
155 
156 curdoc().add_root(layout)
157
```

Path: `examples/howto/js_events.py`
Content:
```
1 """ Demonstration of how to register event callbacks using an adaptation
2 of the color_scatter example from the bokeh gallery
3 """
4 
5 import numpy as np
6 
7 from bokeh.io import show, output_file
8 from bokeh.plotting import figure
9 from bokeh import events
10 from bokeh.models import CustomJS, Div, Button
11 from bokeh.layouts import column, row
12 
13 
14 def display_event(div, attributes=[]):
15     """
16     Function to build a suitable CustomJS to display the current event
17     in the div model.
18     """
19     style = 'float:left;clear:left;font_size=0.5pt'
20     return CustomJS(args=dict(div=div), code="""
21         var attrs = %s;
22         var args = [];
23         for (var i=0; i<attrs.length; i++ ) {
24             val = JSON.stringify(cb_obj[attrs[i]], function(key, val) {
25                 return val.toFixed ? Number(val.toFixed(2)) : val;
26             })
27             args.push(attrs[i] + '=' + val)
28         }
29         var line = "<span style=%r><b>" + cb_obj.event_name + "</b>(" + args.join(", ") + ")</span>\\n";
30         var text = div.text.concat(line);
31         var lines = text.split("\\n")
32         if ( lines.length > 35 ) { lines.shift(); }
33         div.text = lines.join("\\n");
34     """ % (attributes, style))
35 
36 # Follows the color_scatter gallery example
37 
38 N = 4000
39 x = np.random.random(size=N) * 100
40 y = np.random.random(size=N) * 100
41 radii = np.random.random(size=N) * 1.5
42 colors = [
43     "#%02x%02x%02x" % (int(r), int(g), 150) for r, g in zip(50+2*x, 30+2*y)
44 ]
45 
46 p = figure(tools="pan,wheel_zoom,zoom_in,zoom_out,reset,tap,lasso_select,box_select")
47 
48 p.scatter(x, y, radius=radii,
49           fill_color=colors, fill_alpha=0.6,
50           line_color=None)
51 
52 # Add a div to display events and a button to trigger button click events
53 
54 div = Div(width=1000)
55 button = Button(label="Button", button_type="success")
56 layout = column(button, row(p, div))
57 
58 
59 ## Register event callbacks
60 
61 # Button event
62 button.js_on_event(events.ButtonClick, display_event(div))
63 
64 # LOD events
65 p.js_on_event(events.LODStart, display_event(div))
66 p.js_on_event(events.LODEnd, display_event(div))
67 
68 # Point events
69 point_attributes = ['x','y','sx','sy']
70 p.js_on_event(events.Tap,       display_event(div, attributes=point_attributes))
71 p.js_on_event(events.DoubleTap, display_event(div, attributes=point_attributes))
72 p.js_on_event(events.Press,     display_event(div, attributes=point_attributes))
73 
74 # Mouse wheel event
75 p.js_on_event(events.MouseWheel, display_event(div,attributes=point_attributes+['delta']))
76 
77 # Mouse move, enter and leave
78 p.js_on_event(events.MouseMove,  display_event(div, attributes=point_attributes))
79 p.js_on_event(events.MouseEnter, display_event(div, attributes=point_attributes))
80 p.js_on_event(events.MouseLeave, display_event(div, attributes=point_attributes))
81 
82 # Pan events
83 pan_attributes = point_attributes + ['delta_x', 'delta_y']
84 p.js_on_event(events.Pan,      display_event(div, attributes=pan_attributes))
85 p.js_on_event(events.PanStart, display_event(div, attributes=point_attributes))
86 p.js_on_event(events.PanEnd,   display_event(div, attributes=point_attributes))
87 
88 # Pinch events
89 pinch_attributes = point_attributes + ['scale']
90 p.js_on_event(events.Pinch,      display_event(div, attributes=pinch_attributes))
91 p.js_on_event(events.PinchStart, display_event(div, attributes=point_attributes))
92 p.js_on_event(events.PinchEnd,   display_event(div, attributes=point_attributes))
93 
94 # Selection events
95 p.js_on_event(events.SelectionGeometry, display_event(div, attributes=['geometry', 'final']))
96 
97 output_file("js_events.html", title="JS Events Example")
98 show(layout)
99
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/examples/howto/events_app.py b/examples/howto/events_app.py
--- a/examples/howto/events_app.py
+++ b/examples/howto/events_app.py
@@ -18,7 +18,7 @@
     Function to build a suitable CustomJS to display the current event
     in the div model.
     """
-    style = 'float:left;clear:left;font_size=0.5pt'
+    style = 'float: left; clear: left; font-size: 0.5pt'
     return CustomJS(args=dict(div=div), code="""
         var attrs = %s;
         var args = [];
diff --git a/examples/howto/js_events.py b/examples/howto/js_events.py
--- a/examples/howto/js_events.py
+++ b/examples/howto/js_events.py
@@ -16,7 +16,7 @@
     Function to build a suitable CustomJS to display the current event
     in the div model.
     """
-    style = 'float:left;clear:left;font_size=0.5pt'
+    style = 'float: left; clear: left; font-size: 0.5pt'
     return CustomJS(args=dict(div=div), code="""
         var attrs = %s;
         var args = [];

{"golden_diff": "diff --git a/examples/howto/events_app.py b/examples/howto/events_app.py\n--- a/examples/howto/events_app.py\n+++ b/examples/howto/events_app.py\n@@ -18,7 +18,7 @@\n     Function to build a suitable CustomJS to display the current event\n     in the div model.\n     \"\"\"\n-    style = 'float:left;clear:left;font_size=0.5pt'\n+    style = 'float: left; clear: left; font-size: 0.5pt'\n     return CustomJS(args=dict(div=div), code=\"\"\"\n         var attrs = %s;\n         var args = [];\ndiff --git a/examples/howto/js_events.py b/examples/howto/js_events.py\n--- a/examples/howto/js_events.py\n+++ b/examples/howto/js_events.py\n@@ -16,7 +16,7 @@\n     Function to build a suitable CustomJS to display the current event\n     in the div model.\n     \"\"\"\n-    style = 'float:left;clear:left;font_size=0.5pt'\n+    style = 'float: left; clear: left; font-size: 0.5pt'\n     return CustomJS(args=dict(div=div), code=\"\"\"\n         var attrs = %s;\n         var args = [];\n", "issue": "examples/howto/{js_events,events_app} contain bad CSS\n* https://github.com/bokeh/bokeh/blob/master/examples/howto/js_events.py#L19\r\n* https://github.com/bokeh/bokeh/blob/master/examples/howto/events_app.py#L21\r\n* the same in user_guide\n", "before_files": [{"content": "\"\"\" Demonstration Bokeh app of how to register event callbacks in both\nJavascript and Python using an adaptation of the color_scatter example\nfrom the bokeh gallery. This example extends the js_events.py example\nwith corresponding Python event callbacks.\n\"\"\"\n\nimport numpy as np\n\nfrom bokeh.io import curdoc\nfrom bokeh.plotting import figure\nfrom bokeh import events\nfrom bokeh.models import CustomJS, Div, Button\nfrom bokeh.layouts import column, row\n\n\ndef display_event(div, attributes=[]):\n    \"\"\"\n    Function to build a suitable CustomJS to display the current event\n    in the div model.\n    \"\"\"\n    style = 'float:left;clear:left;font_size=0.5pt'\n    return CustomJS(args=dict(div=div), code=\"\"\"\n        var attrs = %s;\n        var args = [];\n        for (var i=0; i<attrs.length; i++ ) {\n            val = JSON.stringify(cb_obj[attrs[i]], function(key, val) {\n                return val.toFixed ? Number(val.toFixed(2)) : val;\n            })\n            args.push(attrs[i] + '=' + val)\n        }\n        var line = \"<span style=%r><b>\" + cb_obj.event_name + \"</b>(\" + args.join(\", \") + \")</span>\\\\n\";\n        var text = div.text.concat(line);\n        var lines = text.split(\"\\\\n\")\n        if ( lines.length > 35 ) { lines.shift(); }\n        div.text = lines.join(\"\\\\n\");\n    \"\"\" % (attributes, style))\n\ndef print_event(attributes=[]):\n    \"\"\"\n    Function that returns a Python callback to pretty print the events.\n    \"\"\"\n    def python_callback(event):\n        cls_name = event.__class__.__name__\n        attrs = ', '.join(['{attr}={val}'.format(attr=attr, val=event.__dict__[attr])\n                       for attr in attributes])\n        print('{cls_name}({attrs})'.format(cls_name=cls_name, attrs=attrs))\n    return python_callback\n\n# Follows the color_scatter gallery example\n\nN = 4000\nx = np.random.random(size=N) * 100\ny = np.random.random(size=N) * 100\nradii = np.random.random(size=N) * 1.5\ncolors = [\n    \"#%02x%02x%02x\" % (int(r), int(g), 150) for r, g in zip(50+2*x, 30+2*y)\n]\n\np = figure(tools=\"pan,wheel_zoom,zoom_in,zoom_out,reset,tap,lasso_select,box_select\")\n\np.scatter(x, y, radius=radii,\n          fill_color=colors, fill_alpha=0.6,\n          line_color=None)\n\n# Add a div to display events and a button to trigger button click events\n\ndiv = Div(width=1000)\nbutton = Button(label=\"Button\", button_type=\"success\")\nlayout = column(button, row(p, div))\n\n\npoint_attributes = ['x','y','sx','sy']\npan_attributes = point_attributes + ['delta_x', 'delta_y']\npinch_attributes = point_attributes + ['scale']\nwheel_attributes = point_attributes+['delta']\n\n## Register Javascript event callbacks\n\n# Button event\nbutton.js_on_event(events.ButtonClick, display_event(div))\n\n# LOD events\np.js_on_event(events.LODStart, display_event(div))\np.js_on_event(events.LODEnd,   display_event(div))\n\n# Point events\n\np.js_on_event(events.Tap,       display_event(div, attributes=point_attributes))\np.js_on_event(events.DoubleTap, display_event(div, attributes=point_attributes))\np.js_on_event(events.Press,     display_event(div, attributes=point_attributes))\n\n# Mouse wheel event\np.js_on_event(events.MouseWheel, display_event(div,attributes=wheel_attributes))\n\n# Mouse move, enter and leave\np.js_on_event(events.MouseMove,  display_event(div, attributes=point_attributes))\np.js_on_event(events.MouseEnter, display_event(div, attributes=point_attributes))\np.js_on_event(events.MouseLeave, display_event(div, attributes=point_attributes))\n\n# Pan events\np.js_on_event(events.Pan,      display_event(div, attributes=pan_attributes))\np.js_on_event(events.PanStart, display_event(div, attributes=point_attributes))\np.js_on_event(events.PanEnd,   display_event(div, attributes=point_attributes))\n\n# Pinch events\np.js_on_event(events.Pinch,      display_event(div, attributes=pinch_attributes))\np.js_on_event(events.PinchStart, display_event(div, attributes=point_attributes))\np.js_on_event(events.PinchEnd,   display_event(div, attributes=point_attributes))\n\n# Selection events\np.js_on_event(events.SelectionGeometry, display_event(div, attributes=['geometry', 'final']))\n\n# Reset events\np.js_on_event(events.Reset, display_event(div))\n\n\n## Register Python event callbacks\n\n# Button event\nbutton.on_event(events.ButtonClick, print_event())\n\n# LOD events\np.on_event(events.LODStart, print_event())\np.on_event(events.LODEnd,   print_event())\n\n# Point events\n\np.on_event(events.Tap,       print_event(attributes=point_attributes))\np.on_event(events.DoubleTap, print_event(attributes=point_attributes))\np.on_event(events.Press,     print_event(attributes=point_attributes))\n\n# Mouse wheel event\np.on_event(events.MouseWheel, print_event(attributes=wheel_attributes))\n\n# Mouse move, enter and leave\np.on_event(events.MouseMove,  print_event(attributes=point_attributes))\np.on_event(events.MouseEnter, print_event(attributes=point_attributes))\np.on_event(events.MouseLeave, print_event(attributes=point_attributes))\n\n# Pan events\np.on_event(events.Pan,      print_event(attributes=pan_attributes))\np.on_event(events.PanStart, print_event(attributes=point_attributes))\np.on_event(events.PanEnd,   print_event(attributes=point_attributes))\n\n# Pinch events\np.on_event(events.Pinch,      print_event(attributes=pinch_attributes))\np.on_event(events.PinchStart, print_event(attributes=point_attributes))\np.on_event(events.PinchEnd,   print_event(attributes=point_attributes))\n\n# Selection events\np.on_event(events.SelectionGeometry, print_event(attributes=['geometry', 'final']))\n\n# Reset events\np.on_event(events.Reset, print_event())\n\ncurdoc().add_root(layout)\n", "path": "examples/howto/events_app.py"}, {"content": "\"\"\" Demonstration of how to register event callbacks using an adaptation\nof the color_scatter example from the bokeh gallery\n\"\"\"\n\nimport numpy as np\n\nfrom bokeh.io import show, output_file\nfrom bokeh.plotting import figure\nfrom bokeh import events\nfrom bokeh.models import CustomJS, Div, Button\nfrom bokeh.layouts import column, row\n\n\ndef display_event(div, attributes=[]):\n    \"\"\"\n    Function to build a suitable CustomJS to display the current event\n    in the div model.\n    \"\"\"\n    style = 'float:left;clear:left;font_size=0.5pt'\n    return CustomJS(args=dict(div=div), code=\"\"\"\n        var attrs = %s;\n        var args = [];\n        for (var i=0; i<attrs.length; i++ ) {\n            val = JSON.stringify(cb_obj[attrs[i]], function(key, val) {\n                return val.toFixed ? Number(val.toFixed(2)) : val;\n            })\n            args.push(attrs[i] + '=' + val)\n        }\n        var line = \"<span style=%r><b>\" + cb_obj.event_name + \"</b>(\" + args.join(\", \") + \")</span>\\\\n\";\n        var text = div.text.concat(line);\n        var lines = text.split(\"\\\\n\")\n        if ( lines.length > 35 ) { lines.shift(); }\n        div.text = lines.join(\"\\\\n\");\n    \"\"\" % (attributes, style))\n\n# Follows the color_scatter gallery example\n\nN = 4000\nx = np.random.random(size=N) * 100\ny = np.random.random(size=N) * 100\nradii = np.random.random(size=N) * 1.5\ncolors = [\n    \"#%02x%02x%02x\" % (int(r), int(g), 150) for r, g in zip(50+2*x, 30+2*y)\n]\n\np = figure(tools=\"pan,wheel_zoom,zoom_in,zoom_out,reset,tap,lasso_select,box_select\")\n\np.scatter(x, y, radius=radii,\n          fill_color=colors, fill_alpha=0.6,\n          line_color=None)\n\n# Add a div to display events and a button to trigger button click events\n\ndiv = Div(width=1000)\nbutton = Button(label=\"Button\", button_type=\"success\")\nlayout = column(button, row(p, div))\n\n\n## Register event callbacks\n\n# Button event\nbutton.js_on_event(events.ButtonClick, display_event(div))\n\n# LOD events\np.js_on_event(events.LODStart, display_event(div))\np.js_on_event(events.LODEnd, display_event(div))\n\n# Point events\npoint_attributes = ['x','y','sx','sy']\np.js_on_event(events.Tap,       display_event(div, attributes=point_attributes))\np.js_on_event(events.DoubleTap, display_event(div, attributes=point_attributes))\np.js_on_event(events.Press,     display_event(div, attributes=point_attributes))\n\n# Mouse wheel event\np.js_on_event(events.MouseWheel, display_event(div,attributes=point_attributes+['delta']))\n\n# Mouse move, enter and leave\np.js_on_event(events.MouseMove,  display_event(div, attributes=point_attributes))\np.js_on_event(events.MouseEnter, display_event(div, attributes=point_attributes))\np.js_on_event(events.MouseLeave, display_event(div, attributes=point_attributes))\n\n# Pan events\npan_attributes = point_attributes + ['delta_x', 'delta_y']\np.js_on_event(events.Pan,      display_event(div, attributes=pan_attributes))\np.js_on_event(events.PanStart, display_event(div, attributes=point_attributes))\np.js_on_event(events.PanEnd,   display_event(div, attributes=point_attributes))\n\n# Pinch events\npinch_attributes = point_attributes + ['scale']\np.js_on_event(events.Pinch,      display_event(div, attributes=pinch_attributes))\np.js_on_event(events.PinchStart, display_event(div, attributes=point_attributes))\np.js_on_event(events.PinchEnd,   display_event(div, attributes=point_attributes))\n\n# Selection events\np.js_on_event(events.SelectionGeometry, display_event(div, attributes=['geometry', 'final']))\n\noutput_file(\"js_events.html\", title=\"JS Events Example\")\nshow(layout)\n", "path": "examples/howto/js_events.py"}], "after_files": [{"content": "\"\"\" Demonstration Bokeh app of how to register event callbacks in both\nJavascript and Python using an adaptation of the color_scatter example\nfrom the bokeh gallery. This example extends the js_events.py example\nwith corresponding Python event callbacks.\n\"\"\"\n\nimport numpy as np\n\nfrom bokeh.io import curdoc\nfrom bokeh.plotting import figure\nfrom bokeh import events\nfrom bokeh.models import CustomJS, Div, Button\nfrom bokeh.layouts import column, row\n\n\ndef display_event(div, attributes=[]):\n    \"\"\"\n    Function to build a suitable CustomJS to display the current event\n    in the div model.\n    \"\"\"\n    style = 'float: left; clear: left; font-size: 0.5pt'\n    return CustomJS(args=dict(div=div), code=\"\"\"\n        var attrs = %s;\n        var args = [];\n        for (var i=0; i<attrs.length; i++ ) {\n            val = JSON.stringify(cb_obj[attrs[i]], function(key, val) {\n                return val.toFixed ? Number(val.toFixed(2)) : val;\n            })\n            args.push(attrs[i] + '=' + val)\n        }\n        var line = \"<span style=%r><b>\" + cb_obj.event_name + \"</b>(\" + args.join(\", \") + \")</span>\\\\n\";\n        var text = div.text.concat(line);\n        var lines = text.split(\"\\\\n\")\n        if ( lines.length > 35 ) { lines.shift(); }\n        div.text = lines.join(\"\\\\n\");\n    \"\"\" % (attributes, style))\n\ndef print_event(attributes=[]):\n    \"\"\"\n    Function that returns a Python callback to pretty print the events.\n    \"\"\"\n    def python_callback(event):\n        cls_name = event.__class__.__name__\n        attrs = ', '.join(['{attr}={val}'.format(attr=attr, val=event.__dict__[attr])\n                       for attr in attributes])\n        print('{cls_name}({attrs})'.format(cls_name=cls_name, attrs=attrs))\n    return python_callback\n\n# Follows the color_scatter gallery example\n\nN = 4000\nx = np.random.random(size=N) * 100\ny = np.random.random(size=N) * 100\nradii = np.random.random(size=N) * 1.5\ncolors = [\n    \"#%02x%02x%02x\" % (int(r), int(g), 150) for r, g in zip(50+2*x, 30+2*y)\n]\n\np = figure(tools=\"pan,wheel_zoom,zoom_in,zoom_out,reset,tap,lasso_select,box_select\")\n\np.scatter(x, y, radius=radii,\n          fill_color=colors, fill_alpha=0.6,\n          line_color=None)\n\n# Add a div to display events and a button to trigger button click events\n\ndiv = Div(width=1000)\nbutton = Button(label=\"Button\", button_type=\"success\")\nlayout = column(button, row(p, div))\n\n\npoint_attributes = ['x','y','sx','sy']\npan_attributes = point_attributes + ['delta_x', 'delta_y']\npinch_attributes = point_attributes + ['scale']\nwheel_attributes = point_attributes+['delta']\n\n## Register Javascript event callbacks\n\n# Button event\nbutton.js_on_event(events.ButtonClick, display_event(div))\n\n# LOD events\np.js_on_event(events.LODStart, display_event(div))\np.js_on_event(events.LODEnd,   display_event(div))\n\n# Point events\n\np.js_on_event(events.Tap,       display_event(div, attributes=point_attributes))\np.js_on_event(events.DoubleTap, display_event(div, attributes=point_attributes))\np.js_on_event(events.Press,     display_event(div, attributes=point_attributes))\n\n# Mouse wheel event\np.js_on_event(events.MouseWheel, display_event(div,attributes=wheel_attributes))\n\n# Mouse move, enter and leave\np.js_on_event(events.MouseMove,  display_event(div, attributes=point_attributes))\np.js_on_event(events.MouseEnter, display_event(div, attributes=point_attributes))\np.js_on_event(events.MouseLeave, display_event(div, attributes=point_attributes))\n\n# Pan events\np.js_on_event(events.Pan,      display_event(div, attributes=pan_attributes))\np.js_on_event(events.PanStart, display_event(div, attributes=point_attributes))\np.js_on_event(events.PanEnd,   display_event(div, attributes=point_attributes))\n\n# Pinch events\np.js_on_event(events.Pinch,      display_event(div, attributes=pinch_attributes))\np.js_on_event(events.PinchStart, display_event(div, attributes=point_attributes))\np.js_on_event(events.PinchEnd,   display_event(div, attributes=point_attributes))\n\n# Selection events\np.js_on_event(events.SelectionGeometry, display_event(div, attributes=['geometry', 'final']))\n\n# Reset events\np.js_on_event(events.Reset, display_event(div))\n\n\n## Register Python event callbacks\n\n# Button event\nbutton.on_event(events.ButtonClick, print_event())\n\n# LOD events\np.on_event(events.LODStart, print_event())\np.on_event(events.LODEnd,   print_event())\n\n# Point events\n\np.on_event(events.Tap,       print_event(attributes=point_attributes))\np.on_event(events.DoubleTap, print_event(attributes=point_attributes))\np.on_event(events.Press,     print_event(attributes=point_attributes))\n\n# Mouse wheel event\np.on_event(events.MouseWheel, print_event(attributes=wheel_attributes))\n\n# Mouse move, enter and leave\np.on_event(events.MouseMove,  print_event(attributes=point_attributes))\np.on_event(events.MouseEnter, print_event(attributes=point_attributes))\np.on_event(events.MouseLeave, print_event(attributes=point_attributes))\n\n# Pan events\np.on_event(events.Pan,      print_event(attributes=pan_attributes))\np.on_event(events.PanStart, print_event(attributes=point_attributes))\np.on_event(events.PanEnd,   print_event(attributes=point_attributes))\n\n# Pinch events\np.on_event(events.Pinch,      print_event(attributes=pinch_attributes))\np.on_event(events.PinchStart, print_event(attributes=point_attributes))\np.on_event(events.PinchEnd,   print_event(attributes=point_attributes))\n\n# Selection events\np.on_event(events.SelectionGeometry, print_event(attributes=['geometry', 'final']))\n\n# Reset events\np.on_event(events.Reset, print_event())\n\ncurdoc().add_root(layout)\n", "path": "examples/howto/events_app.py"}, {"content": "\"\"\" Demonstration of how to register event callbacks using an adaptation\nof the color_scatter example from the bokeh gallery\n\"\"\"\n\nimport numpy as np\n\nfrom bokeh.io import show, output_file\nfrom bokeh.plotting import figure\nfrom bokeh import events\nfrom bokeh.models import CustomJS, Div, Button\nfrom bokeh.layouts import column, row\n\n\ndef display_event(div, attributes=[]):\n    \"\"\"\n    Function to build a suitable CustomJS to display the current event\n    in the div model.\n    \"\"\"\n    style = 'float: left; clear: left; font-size: 0.5pt'\n    return CustomJS(args=dict(div=div), code=\"\"\"\n        var attrs = %s;\n        var args = [];\n        for (var i=0; i<attrs.length; i++ ) {\n            val = JSON.stringify(cb_obj[attrs[i]], function(key, val) {\n                return val.toFixed ? Number(val.toFixed(2)) : val;\n            })\n            args.push(attrs[i] + '=' + val)\n        }\n        var line = \"<span style=%r><b>\" + cb_obj.event_name + \"</b>(\" + args.join(\", \") + \")</span>\\\\n\";\n        var text = div.text.concat(line);\n        var lines = text.split(\"\\\\n\")\n        if ( lines.length > 35 ) { lines.shift(); }\n        div.text = lines.join(\"\\\\n\");\n    \"\"\" % (attributes, style))\n\n# Follows the color_scatter gallery example\n\nN = 4000\nx = np.random.random(size=N) * 100\ny = np.random.random(size=N) * 100\nradii = np.random.random(size=N) * 1.5\ncolors = [\n    \"#%02x%02x%02x\" % (int(r), int(g), 150) for r, g in zip(50+2*x, 30+2*y)\n]\n\np = figure(tools=\"pan,wheel_zoom,zoom_in,zoom_out,reset,tap,lasso_select,box_select\")\n\np.scatter(x, y, radius=radii,\n          fill_color=colors, fill_alpha=0.6,\n          line_color=None)\n\n# Add a div to display events and a button to trigger button click events\n\ndiv = Div(width=1000)\nbutton = Button(label=\"Button\", button_type=\"success\")\nlayout = column(button, row(p, div))\n\n\n## Register event callbacks\n\n# Button event\nbutton.js_on_event(events.ButtonClick, display_event(div))\n\n# LOD events\np.js_on_event(events.LODStart, display_event(div))\np.js_on_event(events.LODEnd, display_event(div))\n\n# Point events\npoint_attributes = ['x','y','sx','sy']\np.js_on_event(events.Tap,       display_event(div, attributes=point_attributes))\np.js_on_event(events.DoubleTap, display_event(div, attributes=point_attributes))\np.js_on_event(events.Press,     display_event(div, attributes=point_attributes))\n\n# Mouse wheel event\np.js_on_event(events.MouseWheel, display_event(div,attributes=point_attributes+['delta']))\n\n# Mouse move, enter and leave\np.js_on_event(events.MouseMove,  display_event(div, attributes=point_attributes))\np.js_on_event(events.MouseEnter, display_event(div, attributes=point_attributes))\np.js_on_event(events.MouseLeave, display_event(div, attributes=point_attributes))\n\n# Pan events\npan_attributes = point_attributes + ['delta_x', 'delta_y']\np.js_on_event(events.Pan,      display_event(div, attributes=pan_attributes))\np.js_on_event(events.PanStart, display_event(div, attributes=point_attributes))\np.js_on_event(events.PanEnd,   display_event(div, attributes=point_attributes))\n\n# Pinch events\npinch_attributes = point_attributes + ['scale']\np.js_on_event(events.Pinch,      display_event(div, attributes=pinch_attributes))\np.js_on_event(events.PinchStart, display_event(div, attributes=point_attributes))\np.js_on_event(events.PinchEnd,   display_event(div, attributes=point_attributes))\n\n# Selection events\np.js_on_event(events.SelectionGeometry, display_event(div, attributes=['geometry', 'final']))\n\noutput_file(\"js_events.html\", title=\"JS Events Example\")\nshow(layout)\n", "path": "examples/howto/js_events.py"}]}