Using Urth Widgets in Scala


In [12]:
%%HTML
<urth-help/>


Out[12]:

Add, import and initialize the widget system:


In [13]:
// modify to IP and Port of this notebook server
%addjar http://localhost:8888/nbextensions/declarativewidgets/urth-widgets.jar


Using cached version of urth-widgets.jar

In [14]:
import declarativewidgets._
initWidgets

Import Polymer elements:


In [15]:
%%html
<link rel='import' href='urth_components/paper-slider/paper-slider.html' 
        is='urth-core-import' package='PolymerElements/paper-slider'>


Out[15]:

Function widget

Def


In [16]:
def math(x: Int, y: Double = 50): Double = x * y

In [17]:
%%html
<template is="dom-bind">
<urth-core-function ref="math" arg-x="{{x}}" arg-y="{{y}}" result="{{res}}" auto></urth-core-function>
    <label>x:</label><paper-slider min="10" max="100" step="1" value="{{x}}"></paper-slider><span>{{x}}</span><br>
    <label>y:</label><paper-slider min="1" max="100" step="1" value="{{y}}"></paper-slider><span>{{y}}</span><br>
Result: <span>{{res}}</span>
</template>


Out[17]:

Val


In [18]:
val fun = (x: Int,  y: Double) => x * y

In [19]:
%%html
<template is="dom-bind">
<urth-core-function id="test" ref="fun" arg-x="{{x}}" arg-y="{{y}}" result='{{res}}' auto></urth-core-function>
    <label>x:</label><paper-slider min="10" max="100" step="1" value="{{x}}"></paper-slider><span>{{x}}</span><br>
    <label>y:</label><paper-slider min="1" max="10" step="0.1" value="{{y}}"></paper-slider><span>{{y}}</span><br>
    Result: <span>{{res}}</span>
</template>


Out[19]:

Note that the function below will not get automatically invoked after the <urth-core-function> is created since the arguments are not set:


In [20]:
def moreMath(x: Int, y: Double) = x * y

In [21]:
%%html
<template is="dom-bind">
    <urth-core-function ref="moreMath" args="{{args}}" result="{{res}}" auto></urth-core-function>
    x: <input type="text" value="{{args.x::change}}"></input>
    y: <input type="text" value="{{args.y::change}}"></input>
    Result: <span>{{res}}</span>
</template>


Out[21]:

DataFrame return value


In [22]:
val sqlContext = new org.apache.spark.sql.SQLContext(sc)
import sqlContext.implicits._
import org.apache.spark.sql.DataFrame

def dfFunc(x: Int): DataFrame = {
    val seq = (0 until x).map(i => (i, i)).toSeq
    sqlContext.createDataFrame(seq)
}

In [23]:
%%html
<template is="dom-bind">
<urth-core-function ref="dfFunc" arg-x="{{x}}" result='{{res}}' limit="10" auto></urth-core-function>
    <label>x:</label><paper-slider min="0" max="20" step="1" value="{{x}}"></paper-slider><span>{{x}}</span><br>
    <label>columns:</label><span>{{res.columns}}</span> <br/>
    <label>index:</label><span>{{res.index}}</span> <br/>
    <label>data:</label><span>{{res.data}}</span>
</template>


Out[23]:

DataFrame widget


In [24]:
val seq = (0 until 10000).map(i => (i, i)).toSeq
val largeDataFrame = sqlContext.createDataFrame(seq)

In [25]:
%%html
<template is="dom-bind">
    <urth-core-dataframe ref="largeDataFrame" limit="10" value="{{x}}"></urth-core-dataframe>
    <p>Columns: <span>{{x.columns}}</span></p>
    <p>Index: <span>{{x.index}}</span></p>
    <p>Data:</p>
    <template is="dom-repeat" items="{{x.data}}">
        <span>{{item}}</span><br/>
    </template>
</template>


Out[25]:

In [26]:
case class Contact(firstname: String, lastname: String, title: String, email: String, phone: String, web: String)

In [27]:
val contacts = sqlContext.createDataFrame(Seq(
    Contact("Jane", "Doe","Scala Developer", "jane@ibm.com", "123-432-5431", "http://www.ibm.com/jane"), 
    Contact("John", "Doe","Spark Engineer", "john@ibm.com", "143-421-5411", "http://www.ibm.com/john"),
    Contact("Joe", "Smith","Product Manager", "joe@ibm.com", "123-732-8421", "http://www.ibm.com/joe")))

In [28]:
%%html
<template is="dom-bind">
    <urth-core-dataframe ref="contacts" value="{{x}}" auto></urth-core-dataframe>
    
    <template is="dom-repeat" items="{{x.data}}">
      <div class="bcard">
        <div class="info">
            <div class="line full-name"><span>{{item.0}}</span> <span>{{item.1}}</span></div>
            <span class="line title">{{item.2}}</span>
            <span class="line phone-number">{{item.3}}</span>
            <span class="line email">{{item.4}}</span>
            <span class="line website">{{item.5}}</span>
        </div>
        <div class="logo"></div>
      </div>
    </template>
</template>


Out[28]:

Channels API

Interact with urth-core-bind channel variables using the following API:

Set Item


In [29]:
declarativewidgets.WidgetChannels


Out[29]:
declarativewidgets.WidgetChannels$@112c5694

In [36]:
%%html
<template is='urth-core-bind' channel='a'>
    <div>Hello from <span>{{user}}</span></div>
    Name: <input value='{{user::input}}'></input>
</template>


Out[36]:

In [37]:
import declarativewidgets.WidgetChannels.channel

In [38]:
channel("a")


Out[38]:
Channel(org.apache.toree.comm.KernelCommWriter@7df30012,a)

In [39]:
channel("a").set("user", "tst")

In [40]:
%%html
<template is='urth-core-bind' channel='a'>
    <div>Hello again from <span>{{user}}</span></div>    
</template>


Out[40]:

Watch Item


In [41]:
%%html
<template is='urth-core-bind' channel='b'>
    <p><span>{{x}}</span></p>
    <span>{{y}}</span>
</template>


Out[41]:

In [42]:
channel("b").set("x", "mina")

Now we set up a watch handler for variable x on channel b.

Note that the first argument is of type Option, since an oldVal may not be present.


In [43]:
val handler = (oldVal: Option[String], newVal: String) => 
    channel("b").set("y", s"Hello from the kernel! old: ${oldVal.getOrElse("")}, new: $newVal")

In [44]:
channel("b").watch("x", handler)

In [45]:
channel("b").set("x", "dean")

Handlers can be typed. Seq corresponds to JavaScript arrays and Map corresponds to JavaScript object.

This example shows a handler that uses Seq:


In [46]:
%%html
<template is='urth-core-bind' channel='c'>
    <p><span>{{x}}</span></p>
    <span>{{y}}</span>
</template>


Out[46]:

In [47]:
channel("c").set("x", List(0))

In [48]:
val handler = (oldVal: Option[Seq[Int]], newVal: Seq[Int]) => 
    channel("c").set("y", s"Hello from the kernel! old: ${oldVal.getOrElse(None)}, new: $newVal")

In [49]:
channel("c").watch("x", handler)

In [50]:
channel("c").set("x", List(0, 1, 2))

In [ ]: