Interactive Tables and their API

The table UI allows column drag/drop, hide, sorting, formatting, searching, selecting/export as CSV. This makes it easy to paste into a spreadsheet like Excel.

There is a menu in the top-left for the whole table, and each column has a menu that appears on hover.

There are also keyboard commands: digits change the precision of all columns, shift-digit changes the precision of the current column. Arrow keys navigate, and the page up/down keys work too.


In [ ]:
new TableDisplay( new CSV().read("../resources/data/interest-rates.csv"))

Formatting and Alignment


In [ ]:
import com.twosigma.beakerx.table.*
import com.twosigma.beakerx.table.format.TableDisplayStringFormat

display = new TableDisplay(new CSV().read("../resources/data/interest-rates.csv"))
//show all time columns in days
display.setStringFormatForTimes(TimeUnit.DAYS)
//min 4, max 6 decimal places for all doubles
display.setStringFormatForType(ColumnType.Double, TableDisplayStringFormat.getDecimalFormat(4,6))
//setting for a column takes precidence over the type
display.setStringFormatForColumn("m3", TableDisplayStringFormat.getDecimalFormat(0, 0))
//set the alignment
display.setAlignmentProviderForType(ColumnType.Double, TableDisplayAlignmentProvider.RIGHT_ALIGNMENT)
display.setAlignmentProviderForColumn('m3', TableDisplayAlignmentProvider.CENTER_ALIGNMENT)

//using a closure
display.setStringFormatForColumn("y3") { value, row, col, tableDisplay ->
   if(value < 8) {
       ":("
   } else {
       ":)"
  } 
}

display

This changes the format of the table above in the previous output cell. It's updated because the object is synchronized between the kernel and the client.


In [ ]:
display.setStringFormatForTimes(TimeUnit.HOURS)

Bar Charts Renderer


In [ ]:
import com.twosigma.beakerx.table.*
import com.twosigma.beakerx.table.renderer.TableDisplayCellRenderer

def display2 = new TableDisplay(new CSV().read("../resources/data/interest-rates.csv"))
//right now, the only renderer option is for data bars
display2.setRendererForType(ColumnType.Double, TableDisplayCellRenderer.getDataBarsRenderer())
//use the false parameter to hide the String value
display2.setRendererForColumn("y10", TableDisplayCellRenderer.getDataBarsRenderer(false))
display2

Column Visibility and Placement


In [ ]:
import com.twosigma.beakerx.table.*
import com.twosigma.beakerx.fileloader.CSV
import com.twosigma.beakerx.table.format.TableDisplayStringFormat

def display3 = new TableDisplay(new CSV().read("../resources/data/interest-rates.csv"))
display3.setStringFormatForType(ColumnType.Double, TableDisplayStringFormat.getDecimalFormat(9,9))
//freeze a column
display3.setColumnFrozen("y1", true)
//hide a column
display3.setColumnVisible("y30", false)

//explicitly set column order/visiblity
display3.setColumnOrder(["m3", "y1", "y5", "time", "y2"]) //Columns in the list will be shown in the provided order. Columns not in the list will be hidden.
display3

Heatmaps


In [ ]:
import com.twosigma.beakerx.table.*
import com.twosigma.beakerx.table.highlight.TableDisplayCellHighlighter

def display4 = new TableDisplay(new CSV().read("../resources/data/interest-rates.csv"))
display4.addCellHighlighter(TableDisplayCellHighlighter.getHeatmapHighlighter("m3", TableDisplayCellHighlighter.FULL_ROW))

//the following two overloads should also be supported
//set the min and max used for calculating the color
//display4.addCellHighlighter(TableDisplayCellHighlighter.getHeatmapHighlighter("y1", TableDisplayCellHighlighter.FULL_ROW, 0, 5))
//set the colors used for the min and max
//display4.addCellHighlighter(TableDisplayCellHighlighter.getHeatmapHighlighter("m6", TableDisplayCellHighlighter.SINGLE_COLUMN, null, null, Color.YELLOW, Color.BLUE))

display4

Cell Background Color


In [ ]:
def map = [
   [a:1, b:2, c:3],
   [a:4, b:5, c:6],
   [a:7, b:8, c:5]
]
def display5 = new TableDisplay(map)
display5.addCellHighlighter { row, column, tableDisplay ->
  if (column == 2) {
    display5.values[row][column] < 5 ? Color.RED : Color.GREEN
  }
}
display5

Heatmaps per Column


In [ ]:
import com.twosigma.beakerx.table.*
import com.twosigma.beakerx.table.highlight.*

display6 = new TableDisplay(new CSV().read("../resources/data/interest-rates.csv"))
display6.addCellHighlighter(TableDisplayCellHighlighter.getHeatmapHighlighter("m3", 0, 8, Color.ORANGE, Color.PINK))
display6.addCellHighlighter(TableDisplayCellHighlighter.getHeatmapHighlighter("m6", TableDisplayCellHighlighter.SINGLE_COLUMN, 6, 8, Color.BLACK, Color.PINK))

display6.addCellHighlighter(new ThreeColorHeatmapHighlighter("y1", TableDisplayCellHighlighter.SINGLE_COLUMN, 4, 6, 8, new Color(247,106,106), new Color(239,218,82), new Color(100,189,122)))

display6

In [ ]:
display6.removeAllCellHighlighters()

Color Unique Entries


In [ ]:
import com.twosigma.beakerx.table.highlight.*

def table = new TableDisplay([[1,2,3], 
                              [3,4,5], 
                              [6,2,8], 
                              [6,2,8], 
                              [6,2,8], 
                              [6,4,8], 
                              [6,2,8], 
                              [6,2,8], 
                              [6,5,8]], 
                             ['a', 'b', 'c'], 
                             ['double', 'double', 'double'])
table.addCellHighlighter(TableDisplayCellHighlighter.getUniqueEntriesHighlighter("b", TableDisplayCellHighlighter.FULL_ROW))
table

Font Size, Color, and Vertical Headers


In [ ]:
def mapList5 = [
 [firstCol:1, secondCol:2, thirdCol:3],
 [firstCol:4, secondCol:5, thirdCol:6],
 [firstCol:9, secondCol:8, thirdCol:9]
]
def td4 = new TableDisplay(mapList5)

//tool tip can be set with a closure
td4.setToolTip { row, col, display ->
 "The value is: " + display.values[row][col]
}
td4

//set the font size and color
td4.dataFontSize = 35
td4.headerFontSize = 30

def colors = [[Color.LIGHT_GRAY, Color.GRAY, Color.RED],
            [Color.DARK_GREEN, Color.ORANGE, Color.RED],
            [Color.MAGENTA, Color.BLUE, Color.BLACK]]

td4.setFontColorProvider { row, col, td ->
 colors[row][col]
}

//try different filter options
td4.setRowFilter { row, model ->
 //model[row][1] == 8
 true
 //false
 //model[row][0] == model[row][2]
}

//set vertical headers
//you can also do this in the right-click menu
td4.setHeadersVertical(true)

td4

Programmable Actions

Bind a closure or running a cell to the context menu or double click action on the table.


In [ ]:
abc = 0; // test variable
mapList = [
   [a:1, b:2, c:3],
   [a:4, b:5, c:6],
   [a:7, b:8, c:5]
]
OutputCell.HIDDEN

In [ ]:
def display1 = new TableDisplay(mapList)
//set what happens on a double click
display1.setDoubleClickAction { row, col, tableDisplay ->
   tableDisplay.values[row][col] = tableDisplay.values[row].sum()
}

//add a context menu item
display1.addContextMenuItem("negate") { row, col, tableDisplay ->
   tableDisplay.values[row][col] = -tableDisplay.values[row][col]
}

display1

In [ ]:
def display2 = new TableDisplay(mapList)

//run tagged cell on action
display2.addContextMenuItem("run print cell", "print_cell");
display2.setDoubleClickAction("print_cell");

display2

In [ ]:
abc++
println abc

In [ ]:
display4 = new TableDisplay(mapList)

//run tagged cell on action
display4.addContextMenuItem("run tagged_cell cell", "tagged_cell");
display4.setDoubleClickAction("tagged_cell");

display4

In [ ]:
def details = display4.details

if(details != null){
  switch(details.actionType){
    case 'DOUBLE_CLICK':
    print ("You clicked on the cell [" + details.row + ", " + details.col + "]")
      break;
    case 'CONTEXT_MENU_CLICK':
     print ("You selected context menu '" + details.contextMenuItem + "' on the cell [" + details.row + ", " + details.col + "]")
    break;
  }
}else{
  println "no table tag action performed."
}

HTML format

HTML format allows markup and styling of the cell's content. Interactive JavaScript and images are not supported however. See below for image support.


In [ ]:
tbl = new TableDisplay([x: '<em style="color:red">italic red</em>',
                      y: '<b style="color:blue">bold blue</b>',
                      z: 'multiline strings<br/>work fine too']);
tbl.setStringFormatForColumn("Value", TableDisplayStringFormat.getHTMLFormat())
tbl

Image format

Image format allows loading any image supported by the web browser, including PNG, JPG, and SVG formats. It can be a relative URL served from the same directories as the notebook itself, an absolute URL to anywhere on the web, or a data URL with encoded data.


In [ ]:
tbl = new TableDisplay(['Peacock': '../resources/img/butterfly1.jpg',
                        'Morpho': '../resources/img/butterfly2.jpg',
                        'Swallowtail': '../resources/img/butterfly3.jpg']);
tbl.setStringFormatForColumn("Value", TableDisplayStringFormat.getImageFormat())
tbl

In [ ]:
tbl = new TableDisplay(['https://en.wikipedia.org/wiki/IPython': 'http://jupyter.org/assets/nav_logo.svg',
                        'https://en.wikipedia.org/wiki/Two_Sigma': 'https://upload.wikimedia.org/wikipedia/commons/thumb/5/54/2_sigma_logo.png/150px-2_sigma_logo.png']);
tbl.setStringFormatForColumn("Value", TableDisplayStringFormat.getImageFormat())
tbl

In [ ]:
tbl = new TableDisplay(['up': 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4NCjwhRE9DVFlQRSBzdmcgUFVCTElDICItLy9XM0MvL0RURCBTVkcgMS4xLy9FTiIgImh0dHA6Ly93d3cudzMub3JnL0dyYXBoaWNzL1NWRy8xLjEvRFREL3N2ZzExLmR0ZCI+DQo8c3ZnIHZlcnNpb249IjEuMSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgaGVpZ2h0PSI2NCIgd2lkdGg9IjY0IiB2aWV3Qm94PSIwIDAgNjQgNjQiPg0KICA8cG9seWdvbiBmaWxsPSIjNmJhMmM3IiBwb2ludHM9IjMwLDQgNCw2MCA2MCw2MCI+PC9wb2x5Z29uPg0KPC9zdmc+DQo=',
                        'down': 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz4KPCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj4KPHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIGhlaWdodD0iNjQiIHdpZHRoPSI2NCIgdmlld0JveD0iMCAwIDY0IDY0Ij4KICA8cG9seWdvbiBmaWxsPSIjNmJhMmM3IiBwb2ludHM9IjMwLDYwIDYwLDQgNCw0Ij48L3BvbHlnb24+Cjwvc3ZnPgo=']);
tbl.setStringFormatForColumn("Value", TableDisplayStringFormat.getImageFormat())
tbl

Auto linking of URLs

The normal string format automatically detects URLs and links them. An underline appears when the mouse hovers over such a string, and when you click it opens in a new window.


In [ ]:
new TableDisplay(['Two Sigma': 'http://twosigma.com', 'BeakerX': 'surrounding text http://BeakerX.com works fine'])

Seamless Update


In [ ]:
def mapListToUpdate = [
   [a:1, b:2, c:3],
   [a:4, b:5, c:6],
   [a:7, b:8, c:9]
]
tableToUpdate = new TableDisplay(mapListToUpdate)

tableToUpdate

In [ ]:
tableToUpdate.values[0][0] = 99
tableToUpdate.sendModel()

In [ ]:
tableToUpdate.updateCell(2,"c",121)
tableToUpdate.sendModel()