@quartic/bokehjs
Version:
Interactive, novel data visualization
310 lines (309 loc) • 11.7 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var wait_for_element, indexOf = [].indexOf || function (item) { for (var i = 0, l = this.length; i < l; i++) {
if (i in this && this[i] === item)
return i;
} return -1; }, extend = function (child, parent) { for (var key in parent) {
if (hasProp.call(parent, key))
child[key] = parent[key];
} function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty;
var $ = require("jquery");
require("jquery-ui/sortable");
var SlickGrid = require("slick_grid/slick.grid");
var RowSelectionModel = require("slick_grid/plugins/slick.rowselectionmodel");
var CheckboxSelectColumn = require("slick_grid/plugins/slick.checkboxselectcolumn");
var hittest = require("core/hittest");
var p = require("core/properties");
var string_1 = require("core/util/string");
var array_1 = require("core/util/array");
var table_widget_1 = require("./table_widget");
var widget_1 = require("./widget");
wait_for_element = function (el, fn) {
var handler, interval;
handler = (function (_this) {
return function () {
if ($.contains(document.documentElement, el)) {
clearInterval(interval);
return fn();
}
};
})(this);
return interval = setInterval(handler, 50);
};
exports.DataProvider = (function () {
function DataProvider(source) {
var j, ref, results;
this.source = source;
this.data = this.source.data;
this.fields = Object.keys(this.data);
if (indexOf.call(this.fields, "index") < 0) {
this.data["index"] = (function () {
results = [];
for (var j = 0, ref = this.getLength(); 0 <= ref ? j < ref : j > ref; 0 <= ref ? j++ : j--) {
results.push(j);
}
return results;
}).apply(this);
this.fields.push("index");
}
}
DataProvider.prototype.getLength = function () {
return this.source.get_length();
};
DataProvider.prototype.getItem = function (offset) {
var field, item, j, len, ref;
item = {};
ref = this.fields;
for (j = 0, len = ref.length; j < len; j++) {
field = ref[j];
item[field] = this.data[field][offset];
}
return item;
};
DataProvider.prototype._setItem = function (offset, item) {
var field, value;
for (field in item) {
value = item[field];
this.data[field][offset] = value;
}
};
DataProvider.prototype.setItem = function (offset, item) {
this._setItem(offset, item);
return this.updateSource();
};
DataProvider.prototype.getField = function (index, field) {
var offset;
offset = this.data["index"].indexOf(index);
return this.data[field][offset];
};
DataProvider.prototype._setField = function (index, field, value) {
var offset;
offset = this.data["index"].indexOf(index);
this.data[field][offset] = value;
};
DataProvider.prototype.setField = function (index, field, value) {
this._setField(index, field, value);
return this.updateSource();
};
DataProvider.prototype.updateSource = function () {
return this.source.trigger("change:data", this, this.source.attributes['data']);
};
DataProvider.prototype.getItemMetadata = function (index) {
return null;
};
DataProvider.prototype.getRecords = function () {
var i;
return (function () {
var j, ref, results;
results = [];
for (i = j = 0, ref = this.getLength(); 0 <= ref ? j < ref : j > ref; i = 0 <= ref ? ++j : --j) {
results.push(this.getItem(i));
}
return results;
}).call(this);
};
DataProvider.prototype.sort = function (columns) {
var cols, column, i, j, len, record, records;
cols = (function () {
var j, len, results;
results = [];
for (j = 0, len = columns.length; j < len; j++) {
column = columns[j];
results.push([column.sortCol.field, column.sortAsc ? 1 : -1]);
}
return results;
})();
if (cols.length === 0) {
cols = [["index", 1]];
}
records = this.getRecords();
records.sort(function (record1, record2) {
var field, j, len, ref, result, sign, value1, value2;
for (j = 0, len = cols.length; j < len; j++) {
ref = cols[j], field = ref[0], sign = ref[1];
value1 = record1[field];
value2 = record2[field];
result = value1 === value2 ? 0 : value1 > value2 ? sign : -sign;
if (result !== 0) {
return result;
}
}
return 0;
});
for (i = j = 0, len = records.length; j < len; i = ++j) {
record = records[i];
this._setItem(i, record);
}
return this.updateSource();
};
return DataProvider;
})();
exports.DataTableView = (function (superClass) {
extend(DataTableView, superClass);
function DataTableView() {
return DataTableView.__super__.constructor.apply(this, arguments);
}
DataTableView.prototype.className = "bk-data-table";
DataTableView.prototype.initialize = function (options) {
DataTableView.__super__.initialize.call(this, options);
wait_for_element(this.el, (function (_this) {
return function () {
return _this.render();
};
})(this));
this.listenTo(this.model, 'change', (function (_this) {
return function () {
return _this.render();
};
})(this));
this.listenTo(this.model.source, 'change:data', (function (_this) {
return function () {
return _this.updateGrid();
};
})(this));
this.listenTo(this.model.source, 'stream', (function (_this) {
return function () {
return _this.updateGrid();
};
})(this));
this.listenTo(this.model.source, 'patch', (function (_this) {
return function () {
return _this.updateGrid();
};
})(this));
return this.listenTo(this.model.source, 'change:selected', (function (_this) {
return function () {
return _this.updateSelection();
};
})(this));
};
DataTableView.prototype.updateGrid = function () {
this.data.constructor(this.model.source);
this.grid.invalidate();
this.grid.render();
this.model.source.data = this.model.source.data;
return this.model.source.trigger('change');
};
DataTableView.prototype.updateSelection = function () {
var cur_grid_range, indices, min_index, selected;
selected = this.model.source.selected;
indices = selected['1d'].indices;
this.grid.setSelectedRows(indices);
cur_grid_range = this.grid.getViewport();
if (this.model.scroll_to_selection && !array_1.any(indices, function (i) {
return (cur_grid_range.top <= i && i <= cur_grid_range.bottom);
})) {
min_index = Math.max(0, Math.min.apply(null, indices) - 1);
return this.grid.scrollRowToTop(min_index);
}
};
DataTableView.prototype.newIndexColumn = function () {
return {
id: string_1.uniqueId(),
name: "#",
field: "index",
width: 40,
behavior: "select",
cannotTriggerInsert: true,
resizable: false,
selectable: false,
sortable: true,
cssClass: "bk-cell-index"
};
};
DataTableView.prototype.render = function () {
var checkboxSelector, column, columns, height, options, width;
columns = (function () {
var j, len, ref, results;
ref = this.model.columns;
results = [];
for (j = 0, len = ref.length; j < len; j++) {
column = ref[j];
results.push(column.toColumn());
}
return results;
}).call(this);
if (this.model.selectable === "checkbox") {
checkboxSelector = new CheckboxSelectColumn({
cssClass: "bk-cell-select"
});
columns.unshift(checkboxSelector.getColumnDefinition());
}
if (this.model.row_headers && (this.model.source.get_column("index") != null)) {
columns.unshift(this.newIndexColumn());
}
width = this.model.width;
height = this.model.height;
options = {
enableCellNavigation: this.model.selectable !== false,
enableColumnReorder: true,
forceFitColumns: this.model.fit_columns,
autoHeight: height === "auto",
multiColumnSort: this.model.sortable,
editable: this.model.editable,
autoEdit: false
};
if (width != null) {
this.el.style.width = this.model.width + "px";
}
else {
this.el.style.width = this.model.default_width + "px";
}
if ((height != null) && height !== "auto") {
this.el.style.height = this.model.height + "px";
}
this.data = new exports.DataProvider(this.model.source);
this.grid = new SlickGrid(this.el, this.data, columns, options);
this.grid.onSort.subscribe((function (_this) {
return function (event, args) {
columns = args.sortCols;
_this.data.sort(columns);
_this.grid.invalidate();
return _this.grid.render();
};
})(this));
if (this.model.selectable !== false) {
this.grid.setSelectionModel(new RowSelectionModel({
selectActiveRow: checkboxSelector == null
}));
if (checkboxSelector != null) {
this.grid.registerPlugin(checkboxSelector);
}
this.grid.onSelectedRowsChanged.subscribe((function (_this) {
return function (event, args) {
var selected;
selected = hittest.create_hit_test_result();
selected['1d'].indices = args.rows;
return _this.model.source.selected = selected;
};
})(this));
}
this._prefix_ui();
return this;
};
return DataTableView;
})(widget_1.WidgetView);
exports.DataTable = (function (superClass) {
extend(DataTable, superClass);
function DataTable() {
return DataTable.__super__.constructor.apply(this, arguments);
}
DataTable.prototype.type = 'DataTable';
DataTable.prototype.default_view = exports.DataTableView;
DataTable.define({
columns: [p.Array, []],
fit_columns: [p.Bool, true],
sortable: [p.Bool, true],
editable: [p.Bool, false],
selectable: [p.Bool, true],
row_headers: [p.Bool, true],
scroll_to_selection: [p.Bool, true]
});
DataTable.override({
height: 400
});
DataTable.internal({
default_width: [p.Number, 600]
});
return DataTable;
})(table_widget_1.TableWidget);