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.
new TableDisplay( new CsvPlotReader().read("demoResources/interest-rates.csv"))
import com.twosigma.beakerx.table.*
import com.twosigma.beakerx.table.format.TableDisplayStringFormat
display = new TableDisplay(new CsvPlotReader().read("demoResources/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.
display.setStringFormatForTimes(TimeUnit.HOURS)
null
import com.twosigma.beakerx.table.*
import com.twosigma.beakerx.table.renderer.TableDisplayCellRenderer
def display2 = new TableDisplay(new CsvPlotReader().read("demoResources/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
import com.twosigma.beakerx.table.*
import com.twosigma.beakerx.fileloader.CsvPlotReader
import com.twosigma.beakerx.table.format.TableDisplayStringFormat
def display3 = new TableDisplay(new CsvPlotReader().read("demoResources/interest-rates.csv"))
display3.setStringFormatForType(ColumnType.Double, TableDisplayStringFormat.getDecimalFormat(9,9))
//freeze a column
display3.setColumnFrozen("y1", true)
//freeze a column to the right
display3.setColumnFrozenRight("y10", 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
import com.twosigma.beakerx.table.*
import com.twosigma.beakerx.table.highlight.TableDisplayCellHighlighter
def display4 = new TableDisplay(new CsvPlotReader().read("demoResources/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
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
import com.twosigma.beakerx.table.*
import com.twosigma.beakerx.table.highlight.*
display6 = new TableDisplay(new CsvPlotReader().read("demoResources/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
display6.removeAllCellHighlighters()
null
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
def mapList4 = [
[a:1, b:2, c:3],
[a:4, b:5, c:6],
[a:7, b:8, c:5]
]
def display7 = new TableDisplay(mapList4)
//set what happens on a double click
display7.setDoubleClickAction { row, col, tableDisplay ->
tableDisplay.values[row][col] = tableDisplay.values[row].sum()
}
//run tagged cell on action
//display7.setDoubleClickAction("misc_formatting");
//add a context menu item
display7.addContextMenuItem("negate") { row, col, tableDisplay ->
tableDisplay.values[row][col] = -tableDisplay.values[row][col]
}
//run tagged cell on action
//display7.addContextMenuItem("negate", "misc_formatting");
display7
Math.random()
0.03323809813551626
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 = 15
td4.headerFontSize = 30
def colors = [[Color.LIGHT_GRAY, Color.GRAY, Color.RED],
[Color.YELLOW, 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
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
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
def display2 = new TableDisplay(mapList)
//run tagged cell on action
display2.addContextMenuItem("run print cell", "print_cell");
display2.setDoubleClickAction("print_cell");
display2
abc++
println abc
3
null
beakerx.runByTag("print_cell")
null
def display3 = new TableDisplay(mapList)
display3.setDoubleClickAction {beakerx.runByTag("print_cell2")}
display3.addContextMenuItem("print_cell2") { beakerx.runByTag("print_cell2") }
display3
abc++
println abc
4
null
Bind running a cell to the context menu or double click action on the table.
display4 = new TableDisplay(mapList)
//run tagged cell on action
display4.addContextMenuItem("run tagged_cell cell", "tagged_cell");
display4.setDoubleClickAction("tagged_cell");
display4
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."
}
You selected context menu 'run tagged_cell cell' on the cell [1, 1]
null
displayHtml = new TableDisplay([[col1: "This & that", col2: "This / that", col3: "This > that"]]);
displayHtml