Repository: bokeh/bokeh

Issue:
Add surface3d custom model example



Discussion:

Resolving patch:
diff --git a/examples/app/surface3d/main.py b/examples/app/surface3d/main.py
new file mode 100644
--- /dev/null
+++ b/examples/app/surface3d/main.py
@@ -0,0 +1,37 @@
+from os.path import dirname, join
+
+import numpy as np
+
+from bokeh.driving import count
+from bokeh.io import curdoc
+from bokeh.models import ColumnDataSource, Div, Column
+
+from surface3d import Surface3d
+
+x = np.arange(0, 300, 10)
+y = np.arange(0, 300, 10)
+xx, yy = np.meshgrid(x, y)
+xx = xx.ravel()
+yy = yy.ravel()
+
+def compute(t):
+    value = np.sin(xx/50 + t/10) * np.cos(yy/50 + t/10) * 50 + 50
+    return dict(x=xx, y=yy, z=value, color=value)
+
+source = ColumnDataSource(data=compute(0))
+
+content_filename = join(dirname(__file__), "description.html")
+
+description = Div(text=open(content_filename).read(),
+                  render_as_text=False, width=600)
+
+surface = Surface3d(x="x", y="y", z="z", color="color", data_source=source)
+
+curdoc().add_root(Column(description, surface))
+
+@count()
+def update(t):
+    source.data = compute(t)
+
+curdoc().add_periodic_callback(update, 100)
+curdoc().title = "Surface3d Custom Extension"
diff --git a/examples/app/surface3d/surface3d.py b/examples/app/surface3d/surface3d.py
new file mode 100644
--- /dev/null
+++ b/examples/app/surface3d/surface3d.py
@@ -0,0 +1,63 @@
+from os.path import dirname, join
+
+from bokeh.core.properties import Any, Dict, Instance, String
+from bokeh.models import ColumnDataSource, LayoutDOM
+
+# This defines some default options for the Graph3d feature of vis.js
+# See: http://visjs.org/graph3d_examples.html for more details. Note
+# that we are fixing the size of this component, in ``options``, but
+# with additional work it could be made more responsive.
+DEFAULTS = {
+    'width':          '600px',
+    'height':         '600px',
+    'style':          'surface',
+    'showPerspective': True,
+    'showGrid':        True,
+    'keepAspectRatio': True,
+    'verticalRatio':   1.0,
+    'legendLabel':     'stuff',
+    'cameraPosition':  {
+        'horizontal': -0.35,
+        'vertical':    0.22,
+        'distance':    1.8,
+    }
+}
+
+# This custom extension model will have a DOM view that should layout-able in
+# Bokeh layouts, so use ``LayoutDOM`` as the base class. If you wanted to create
+# a custom tool, you could inherit from ``Tool``, or from ``Glyph`` if you
+# wanted to create a custom glyph, etc.
+class Surface3d(LayoutDOM):
+
+    # The special class attribute ``__implementation__`` should contain a string
+    # of JavaScript (or CoffeeScript) code that implements the JavaScript side
+    # of the custom extension model.
+    __implementation__ = open(join(dirname(__file__), "surface3d.coffee")).read()
+
+    # Below are all the "properties" for this model. Bokeh properties are
+    # class attributes that define the fields (and their types) that can be
+    # communicated automatically between Python and the browser. Properties
+    # also support type validation. More information about properties in
+    # can be found here:
+    #
+    #    http://bokeh.pydata.org/en/latest/docs/reference/core.html#bokeh-core-properties
+
+    # This is a Bokeh ColumnDataSource that can be updated in the Bokeh
+    # server by Python code
+    data_source = Instance(ColumnDataSource)
+
+    # The vis.js library that we are wrapping expects data for x, y, z, and
+    # color. The data will actually be stored in the ColumnDataSource, but
+    # these properties let us specify the *name* of the column that should
+    # be used for each field.
+    x = String
+
+    y = String
+
+    z = String
+
+    color = String
+
+    # Any of the available vis.js options for Graph3d can be set by changing
+    # the contents of this dictionary.
+    options = Dict(String, Any, default=DEFAULTS)


Test patch: