Socket
Socket
Sign inDemoInstall

fin-hypergrid

Package Overview
Dependencies
Maintainers
2
Versions
43
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

fin-hypergrid - npm Package Compare versions

Comparing version 1.0.7 to 1.0.8

add-ons/aggregations-view.js

8

add-ons/drill-down.js

@@ -106,3 +106,3 @@ 'use strict';

if (smartApply === false || changed && smartApply) {
this.applyAnalytics(true);
this.applyAnalytics({rowClick: true});
this.changed();

@@ -127,3 +127,3 @@ }

while (this.toggleAllRows(true, depth || Infinity)) {
this.applyAnalytics(true);
this.applyAnalytics({rowClick: true});
changed = true;

@@ -195,2 +195,4 @@ }

//TODO: THIS IMPLEMENTATION IS SPECIFIC TO TREEVIEW it should be moved to add-ons/tree-view.js
/**

@@ -207,3 +209,3 @@ * @summary Expand nested drill-downs containing this row.

if (smartApply === false || changed && smartApply) {
this.applyAnalytics(true);
this.applyAnalytics({rowClick: true});
this.changed();

@@ -210,0 +212,0 @@ }

'use strict';
var newPipe = { type: 'DataSourceTreeview', test: test },
referencePipe = 'JSDataSource';
/**

@@ -26,37 +23,56 @@ * @classdesc This is a simple helper class to set up the tree-view data source in the context of a hypergrid.

/**
* @summary Add the tree-view data source into the shared pipeline.
* @desc The tree-view data source is inserted into the shared pipeline of the given data model's prototype, immediately after the raw data source.
* @summary Reconfigure the dataModel's pipeline for tree view.
* @desc The pipeline is reset starting with either the given `options.dataSource` _or_ the existing pipeline's first data source.
*
* The resulting pipeline addition is shared by all new grids using this data model.
* Then the tree view filter and sorter data sources are added as requested.
*
* Intended to be called on the `TreeView` prototype, before the data model is instanced (which currently happens when the behavior is instanced (which currently happens when the grid is instanced)).
* Finally the tree view data source is added.
*
* @param {object} dataModelPrototype
*/
addPipeTo: function(dataModelPrototype) {
dataModelPrototype.addPipe(newPipe, referencePipe);
},
/**
* @summary Add the tree-view data source into the instance pipeline.
* @desc The tree-view data source is inserted into the pipeline of the given data model instance, immediately after the raw data source.
* This method can operate on either:
* * A data model prototype, which will affect all data models subsequently created therefrom. The prototype must be given in `options.dataModelPrototype`.
* * The current data model instance. In this case, the instance is given its own new pipeline.
*
* If necessary, a private copy of the prototype's `pipeline` array is cloned for use by the instance (unless `shared` is truthy).
*
* Finally, `setData` is called again with `data` to rebuild the pipeline. To avoid this, consider {@link TreeView#addPipeTo}.
*
* @param {object[]} data - Required for the `setData` call.
* @param {boolean} [shared=false] - Do not clone prototype's `pipeline` array. The default is to clone it.
* @param {object} [options]
* @param {object} [options.dataModelPrototype] - Adds the pipes to the given object. If omitted, this must be an instance; adds the pipes to a new "own" pipeline created from the first data source of the instance's old pipeline.
* @param {dataSourcePipelineObject} [options.firstPipe] - Use as first data source in the new pipeline. If omitted, re-uses the existing pipeline's first data source.
*/
addPipe: function(data, shared) {
var behavior = this.grid.behavior,
dataModel = behavior.dataModel;
setPipeline: function(options) {
options = options || {};
if (!shared && !dataModel.hasOwnProperty('pipeline')) {
dataModel.pipeline = dataModel.pipeline.slice();
var amInstance = this instanceof TreeView,
dataModel = options.dataModelPrototype || amInstance && this.grid.behavior.dataModel,
firstPipe = options.firstPipe || dataModel.pipeline[0];
if (!dataModel) {
throw 'Expected dataModel.';
}
dataModel.addPipe(newPipe, referencePipe);
behavior.setData(data);
behavior.shapeChanged();
if (!firstPipe) {
throw 'Expected pipe (data source pipeline descriptor).';
}
if (options.dataModelPrototype) {
// operating on prototype
dataModel.truncatePipeline();
dataModel.addPipe(firstPipe);
} else {
// operating on an instance: create a new "own" pipeline
dataModel.pipeline = [firstPipe];
}
if (options.includeFilter) {
dataModel.addPipe({ type: 'DataSourceGlobalFilter' });
}
if (options.includeSorter) {
dataModel.addPipe({ type: 'DataSourceTreeviewSorter' });
}
dataModel.addPipe({ type: 'DataSourceTreeview', test: isTreeview });
if (amInstance) {
this.grid.behavior.setData();
this.dataSource = dataModel.sources.dataSource;
this.grid.behavior.shapeChanged();
}
},

@@ -74,6 +90,6 @@

dataModel = behavior.dataModel,
dataSource = dataModel.sources.treeview,
dataSource = this.dataSource = dataModel.sources.treeview,
joined = dataSource.setRelation(options),
state = behavior.getPrivateState(),
columnProps = behavior.getColumn(dataSource.treeColumnIndex).getProperties();
columnProps = behavior.getColumn(dataSource.treeColumn.index).getProperties();

@@ -90,10 +106,7 @@ if (joined) {

if (hideIdColumns) {
var columnIndexes = [dataSource.idColumnIndex, dataSource.parentIdColumnIndex];
var columnIndexes = [dataSource.idColumn.index, dataSource.parentIdColumn.index];
columnIndexes.forEach(function(columnIndex) {
var index;
if (behavior.columns.find(function(column, i) {
index = i;
return column.index === columnIndex;
})) {
var index = behavior.getActiveColumnIndex(columnIndex);
if (index !== undefined) {
behavior.columns.splice(index, 1);

@@ -103,3 +116,12 @@ }

}
dataSource.defaultSortColumn = dataSource.getColumnInfo(options.defaultSortColumn, dataSource.treeColumn.name);
// If unsorted, sort by tree column
if (behavior.getSortedColumnIndexes().length === 0) {
var gridIndex = behavior.getActiveColumnIndex(dataSource.defaultSortColumn.index);
this.grid.toggleSort(gridIndex, []);
}
} else {
dataSource.defaultSortColumn = undefined;
columnProps.editable = this.editableWas;

@@ -121,10 +143,10 @@ state.checkboxOnlyRowSelections = this.checkboxOnlyRowSelectionsWas;

* This is the required test function called by the data model's `isDrilldown` method in context. _Do not call directly._
* @param {number} [columnIndex] If given, also checks that the column clicked is the tree column.
* @param {number} [event.dataCell.x] If available, also checks that the column clicked is the tree column.
* @returns {boolean} If the data source is a tree view.
*/
function test(event) {
function isTreeview(event) {
var treeview = this.sources.treeview,
result = !!(treeview && treeview.viewMakesSense());
if (result && event) {
result = event.dataCell.x === treeview.treeColumnIndex;
if (result && event && event.dataCell) {
result = event.dataCell.x === treeview.treeColumn.index;
}

@@ -131,0 +153,0 @@ return result;

{
"name": "fin-hypergrid",
"version": "1.0.7",
"version": "1.0.8",
"description": "Canvas-based high-performance spreadsheet",

@@ -21,6 +21,6 @@ "repository": {

"extend-me": "2.2.4",
"filter-tree": "0.3.33",
"filter-tree": "0.3.34",
"finbars": "1.5.1",
"fincanvas": "1.2.1",
"hyper-analytics": "0.11.4",
"fincanvas": "1.3.0",
"hyper-analytics": "0.11.7",
"list-dragon": "1.3.3",

@@ -27,0 +27,0 @@ "lru-cache": "2.7.0",

@@ -29,11 +29,29 @@ **fin-hypergrid** is an ultra-fast HTML5 grid presentation layer, achieving its speed by rendering (in a canvas tag) only the currently visible portion of your (virtual) grid, thus avoiding the latency and life-cycle issues of building, walking, and maintaining a complex DOM structure.

* Any number of rows and columns
* Grid, column, row, and cell styling
* User-resizeable columns, column-dragging, column picking
* Plug-in-able cell formatters and editors
* Smooth scrolling on both axes
* Supports local (client-side) as well as remote (server-side) data hosting
* Events for all UI manipulations including mouse, keyboard, and programmatic UI changes
* Tree-view (drill-downs) presentation for locally grouped, nested, or aggregated data
| Ultra High Performance || General
|----------------------------|----|----------------------------
| Any number of rows and columns <br> (100k+)| | Cross-browser support
| Infinite, smooth scrolling | | Clipboard copy & paste
| Scrolling via cell | | Localization
| Local (client-side) and remote <br> (server-side) data hosting | | Context menu
| Flexible Data Views & Selection || Look-and-Feel
|----------------------------|----|----------------------------
| Filtering and sorting | | CSS Themes
| Aggregation | | Grid, column, row, and <br> cell styling
| Tree view (drill-downs) and group <br> view | | Custom cell editors
| Inline editing | | Customizable scroll bars
| Column grouping, including <br> multi-level | | Column and row resizing
| Freeze columns and rows | | Column auto-sizing
| Cell range, checkbox, and row <br> selection | | Column dragging
| Keyboard navigation | |
| Available in the OpenFin Container
|--------------------------------------------------------
| CSV export
| Cross app communication
| Cross app docking
| Printing
| Easy deployment
| Cross browser independence
##### Future development

@@ -72,3 +90,3 @@

var grid = new fin.Hypergrid('#fin-grid', { data: data })
var grid = new fin.Hypergrid('#fin-grid', { data: data });

@@ -99,1 +117,5 @@ grid.addProperties({

Hypergrid global configurations can be found [here](http://openfin.github.io/fin-hypergrid/doc/module-defaults.html). Use it for modifying various hypergrid features and property defaults.
### Contributors
Developers interested in contributing to this project should submit pull requests against the `develop` branch.

@@ -37,9 +37,6 @@ /* eslint-env browser */

* @param {Hypergrid} grid
* @param {function|menuItem[]} [schema=derivedSchema] - Passed to behavior constructor. May be:
* * A schema array
* * A function returning a schema array. Called at filter reset time with behavior as context.
* * Omit to generate a basic schema from `this.columns`.
* @param {object} [options] - _(See {@link behaviors.JSON#setData}.)_
* @memberOf Behavior.prototype
*/
initialize: function(grid, schema, dataRows) {
initialize: function(grid, dataRows, options) {
/**

@@ -135,2 +132,17 @@ * @type {Hypergrid}

},
/**
* The "grid index" given a "data index" (or column object)
* @param {Column|number} columnOrIndex
* @returns {undefined|number} The grid index of the column or undefined if column not in grid.
*/
getActiveColumnIndex: function(columnOrIndex) {
var index = columnOrIndex instanceof Column ? columnOrIndex.index : columnOrIndex;
for (var i = 0; i < this.columns.length; ++i) {
if (this.columns[i].index === index) {
return i;
}
}
},
getVisibleColumn: function() {

@@ -656,5 +668,6 @@ return this.deprecated('getVisibleColumn(x)', 'getActiveColumn(x)', '1.0.6', arguments);

* @param {Object} event - all event information
* @return {boolean} Clicked in a drill-down column.
*/
cellClicked: function(cell, event) {
this.dataModel.cellClicked(cell, event);
return this.dataModel.cellClicked(cell, event);
},

@@ -1387,3 +1400,6 @@

toggleSort: function(x, keys) {
this.getActiveColumn(x).toggleSort(keys);
var column = this.getActiveColumn(x);
if (column) {
column.toggleSort(keys);
}
},

@@ -1487,18 +1503,2 @@

},
setGroups: function(arrayOfColumnIndexes) {
this.dataModel.setGroups(arrayOfColumnIndexes);
this.createColumns();
this.changed();
},
setAggregates: function(mapOfKeysToFunctions) {
var self = this;
this.dataModel.setAggregates(mapOfKeysToFunctions);
this.createColumns();
setTimeout(function() {
self.changed();
}, 100);
},
hasHierarchyColumn: function() {

@@ -1505,0 +1505,0 @@ return false;

@@ -11,2 +11,3 @@ /* eslint-env browser */

'header',
'calculator',
'type'

@@ -114,2 +115,26 @@ ];

set calculator(calculator) {
var name = this.name,
filter = this.behavior.grid.getGlobalFilter();
if (filter && filter.schema) {
// Note that calculators are not applied to column schema that are simple string primitives.
var columnSchema = filter.schema.find(function(item) {
return item.name === name;
});
if (columnSchema) {
if (calculator) {
columnSchema.calculator = calculator;
} else if (columnSchema.calculator) {
delete columnSchema.calculator;
}
}
}
this.dataModel.getCalculators()[this.index] = this._calculator = calculator;
},
get calculator() {
return this._calculator;
},
getUnfilteredValue: function(y) {

@@ -116,0 +141,0 @@ return this.dataModel.getUnfilteredValue(this.index, y);

@@ -7,3 +7,2 @@ 'use strict';

var features = require('../features');
var aggregations = require('../Shared.js').analytics.util.aggregations;

@@ -24,10 +23,11 @@ /**

* @param grid - the hypergrid
* @param {undefined|function|menuItem[]} schema - Already consumed by Behavior's {@link Behavior#initialize|initialize}.
* @param {undefined|function|menuItem[]} options.schema - Already consumed by Behavior's {@link Behavior#initialize|initialize}.
* @param {object[]} dataRows - May be:
* * An array of congruent raw data objects
* * A function returning same
* @param {object} [options] - _(See {@link behaviors.JSON#setData}.)_
* @memberOf behaviors.JSON.prototype
*/
initialize: function(grid, schema, dataRows) {
this.setData(dataRows, schema);
initialize: function(grid, dataRows, options) {
this.setData(dataRows, options);
},

@@ -46,9 +46,7 @@

features.ColumnSorting,
features.CellClick,
features.CellEditing,
features.CellClick,
features.OnHover
],
aggregations: aggregations,
createColumns: function() {

@@ -59,2 +57,3 @@ var dataModel = this.dataModel;

var fields = dataModel.getFields();
var calculators = dataModel.getCalculators();
var REGEX_CAMEL_CASE = /([^_A-Z])([A-Z]+)/g;

@@ -64,3 +63,8 @@ this.clearColumns();

var header = headers[index];
var column = this.addColumn({ index: index, header: header });
var calculator = calculators[index];
var column = this.addColumn({
index: index,
header: header,
calculator: calculator
});
this.columnEnum[column.name.replace(REGEX_CAMEL_CASE, '$1_$2').toUpperCase()] = index;

@@ -71,2 +75,5 @@ var properties = column.getProperties();

properties.complexFilter = null;
if (calculator) {
properties.calculator = calculator;
}
}

@@ -86,6 +93,21 @@ },

* @description Set the header labels.
* @param {string[]} headerLabels - The header labels.
* @param {string[]|object} headers - The header labels. One of:
* * _If an array:_ Must contain all headers in column order.
* * _If a hash:_ May contain any headers, keyed by field name, in any order (of course).
*/
setHeaders: function(headerLabels) {
this.dataModel.setHeaders(headerLabels);
setHeaders: function(headers) {
if (headers instanceof Array) {
// Reset all headers
var allColumns = this.allColumns;
headers.forEach(function(header, index) {
allColumns[index].header = header; // setter updates header in both column and data source objects
});
} else if (typeof headers === 'object') {
// Adjust just the headers in the hash
this.allColumns.forEach(function(column) {
if (headers[column.name]) {
column.header = headers[column.name];
}
});
}
},

@@ -108,9 +130,18 @@

* @description Set the data field.
* @param {object[]} dataRows - An array of uniform objects backing the rows in the grid.
* @param {function|object[]} [dataRows] - Array of uniform objects containing the grid data. If omitted, the previous data source will be re-used.
* @param {object} [options]
* @param {function|object} [options.fields] - Array of field names. Passed as 2nd param to `this.dataModel.setData`. If omitted (along with `dataSource`), the previous fields array will be re-used.
* @param {function|object} [options.schema=deriveSchema] - Used in filter instantiation.
*/
setData: function(dataRows, options) {
var self = this,
grid = this.grid;
grid = this.grid,
fields = options && options.fields,
calculators = options && options.calculators;
this.dataModel.setData(dataRows, options);
fields = typeof fields === 'function' ? fields() : fields;
calculators = typeof calculators === 'function' ? calculators() : calculators;
dataRows = typeof dataRows === 'function' ? dataRows() : dataRows;
this.dataModel.setData(dataRows, fields, calculators);
this.createColumns();

@@ -125,2 +156,4 @@

dataRows = dataRows || this.dataModel.source.data;
if (grid.isColumnAutosizing()) {

@@ -215,9 +248,2 @@ setTimeout(function() {

},
getGroups: function() {
return this.dataModel.getGroups();
},
getAvailableGroups: function() {
return this.dataModel.getAvailableGroups();
},
getHiddenColumns: function() {

@@ -224,0 +250,0 @@ return this.dataModel.getHiddenColumns();

'use strict';
//var ListDragon = require('list-dragon');
var Behavior = require('./Behavior');
//var DataModelJSON = require('../dataModels/JSON');
//var features = require('../features');
//var aggregations = require('../local_node_modules/finanalytics').aggregations;

@@ -10,0 +5,0 @@ /**

'use strict';
//var ListDragon = require('list-dragon');
var Behavior = require('./Behavior');
//var DataModelJSON = require('../dataModels/JSON');
//var features = require('../features');
//var aggregations = require('../local_node_modules/finanalytics').aggregations;

@@ -10,0 +5,0 @@ /**

@@ -312,5 +312,7 @@ /* eslint-env browser */

if (error) {
error = '\n' + error;
error = error.replace(/[\n\r]+/g, '\n\n * ');
msg += '\n\nAdditional information about this error:' + error;
if (/[\n\r]/.test(error)) {
error = '\n' + error;
error = error.replace(/[\n\r]+/g, '\n\n * ');
}
msg += '\n\nAdditional information about this error: ' + error;
}

@@ -317,0 +319,0 @@

@@ -34,3 +34,3 @@ /* eslint-env browser */

columnName = this.column.name,
columnFilters = this.grid.getGlobalFilter().columnFilters,
columnFilters = root.columnFilters,
columnFilterSubtree = root.getColumnFilter(columnName) || {},

@@ -163,6 +163,40 @@ columnSchema = root.schema.lookup(columnName) || {};

insertText: function(e) {
// insert the drop-downb text at the insertion point or over the selected text
var start = this.selectionStart,
end = this.selectionEnd,
dropdown = this.dropdown,
operator = dropdown.value,
option = dropdown.options[dropdown.selectedIndex],
optgroup = option.parentElement,
isOperator = !(optgroup.tagName === 'OPTGROUP' && optgroup.className);
this.input.focus();
this.input.setRangeText(this.dropdown.value, this.selectionStart, this.selectionEnd, 'end');
if (start === end && isOperator) {
var parser = this.grid.getGlobalFilter().parserCQL,
cql = this.input.value,
position = parser.getOperatorPosition(cql, this.selectionStart, operator);
start = position.start;
end = position.end;
// prepend space to operator as needed
if (
start > 0 && // not at very beginning? and...
!/\s/.test(cql[start - 1]) // no white space before operator?
) {
operator = ' ' + operator;
}
// append space to operator as needed
if (
end === cql.length || // at very end? or...
!/\s/.test(cql[end]) // no white space after operator?
) {
operator += ' ';
}
}
// insert the drop-down text at the insertion point or over the selected text
this.input.setRangeText(operator, start, end, 'end');
// close the drop-down

@@ -169,0 +203,0 @@ this.toggleDropDown();

@@ -58,3 +58,3 @@ 'use strict';

val = valOrFunc(val, config);
val = valOrFunc(val, config, config.calculator);
val = config.formatValue(val);

@@ -365,6 +365,10 @@

function valOrFunc(vf, config) {
var result = config.isGridColumn && config.isGridRow && (typeof vf)[0] === 'f'
? vf(config.dataRow, config.columnName)
: vf;
function valOrFunc(vf, config, calculator) {
var result = vf;
if (config.isGridColumn && config.isGridRow) {
calculator = (typeof vf)[0] === 'f' && vf || calculator;
if (calculator) {
result = calculator(config.dataRow, config.columnName);
}
}
return result || result === 0 || result === false ? result : '';

@@ -371,0 +375,0 @@ }

@@ -17,5 +17,12 @@ 'use strict';

},
getDataIndex: function(y) {
return 0;
},
setFields: function(arr) {
},
getHeaders: function() {
return [];
},
setHeaders: function(arr) {
},
getColumnCount: function() {

@@ -27,22 +34,27 @@ return 0;

},
getAggregateTotals: function() {
getTopTotals:function(){ //or maybe getGrandTotals
return [];
},
setTopTotals:function(){},
getBottomTotals: function(){
return [];
},
hasAggregates: function() {
return false;
setBottomTotals:function(){},
setData: function(arr) {},
click: function() {},
apply: function() {},
getRow: function() {
return null;
},
hasGroups: function() {
return false;
getValue: function(x, y){
return 0;
},
getRow: function() {
setValue: function(x, y, value){},
get: function() {
return null;
},
set: function() {},
viewMakesSense: function() {
return false;
},
setAggregates: function() {},
setGroupBys: function() {},
groupBys: [],
}
};

@@ -61,5 +73,3 @@

source: nullDataSource,
aggregator: nullDataSource,
globalfilter: nullDataSource,
sortercomposite: nullDataSource
globalfilter: nullDataSource
};

@@ -81,23 +91,2 @@ this.dataSource = undefined;

/**
* @param {number} [columnIndex] If given, also checks that the column clicked is the tree column.
* @returns {boolean}
* @memberOf dataModels.JSON.prototype
*/
hasAggregates: function(event) {
var result = this.sources.aggregator.hasAggregates();
if (result && event) {
result = event.gridCell.x === 0;
}
return result;
},
/**
* @memberOf dataModels.JSON.prototype
* @returns {boolean}
*/
hasGroups: function() {
return this.sources.aggregator.hasGroups();
},
getDataSource: function() {

@@ -140,3 +129,3 @@ return this.deprecated('getDataSource()', 'dataSource', '1.0.7');

}
} else if (this.hasAggregates()) {
} else if (this.isDrillDown()) {
x += 1;

@@ -181,3 +170,6 @@ }

var sortString = this.getSortImageForColumn(x);
if (sortString) { value = sortString + value; }
if (sortString) {
var at = value.lastIndexOf(this.groupHeaderDelimiter) + 1;
value = at ? value.substr(0, at) + sortString + value.substr(at) : sortString + value;
}
} else { // must be filter row

@@ -206,3 +198,3 @@ var filter = this.getGlobalFilter();

}
} else if (this.hasAggregates()) {
} else if (this.isDrillDown()) {
x += 1;

@@ -266,5 +258,4 @@ }

var showTree = this.grid.resolveProperty('showTreeColumn') === true;
var hasAggregates = this.hasAggregates();
var offset = (hasAggregates && !showTree) ? -1 : 0;
return this.sources.aggregator.getColumnCount() + offset;
var offset = (this.isDrillDown() && !showTree) ? -1 : 0;
return this.dataSource.getColumnCount() + offset;
},

@@ -287,3 +278,3 @@

getHeaders: function() {
return this.sources.aggregator.getHeaders();
return this.dataSource && this.dataSource.getHeaders() || [];
},

@@ -315,2 +306,10 @@

/**
* @memberOf dataModels.JSON.prototype
* @returns {string[]}
*/
getCalculators: function() {
return this.dataSource.getCalculators();
},
/** @typedef {object} dataSourcePipelineObject

@@ -328,6 +327,4 @@ * @property {function} DataSource - A `hyper-analytics`-style "data source" constructor.

{ type: 'JSDataSource' },
{ type: 'DataSourceAggregator', test: 'hasAggregates' },
{ type: 'DataSourceGlobalFilter' },
{ type: 'DataSourceSorterComposite' },
{ type: 'DataNodeGroupSorter', parent: 'DataSourceAggregator' }
],

@@ -342,8 +339,20 @@

* Branches are created when a pipe specifies a name in `parent`.
* @param {object[]} dataSource - Array of uniform objects containing the grid data.
* @param {object[]} [dataSource] - Array of uniform objects containing the grid data. Passed as 1st param to constructor of first data source object in the pipeline. If omitted, the previous data source will be re-used.
* @param {string[]} [dataFields] - Array of field names. Passed as 2nd param to constructor of first data source object in the pipeline. If omitted (along with `dataSource`), the previous fields array will be re-used.
* @param {string[]} [dataCalculators] - Array of field names. Passed as 3rd param to constructor of first data source object in the pipeline. If omitted (along with `dataSource`), the previous calculators array will be re-used.
* @memberOf dataModels.JSON.prototype
*/
setData: function(dataSource) {
setData: function(dataSource, dataFields, dataCalculators) {
this.resetSources();
if (!dataSource) {
var source = this.source;
if (!source) {
throw 'Expected dataSource.';
}
dataSource = source.data;
dataFields = source.fields;
dataCalculators = source.calculators;
}
this.pipeline.forEach(function(sources, pipe, index) {

@@ -366,5 +375,4 @@ var DataSource = analytics[pipe.type];

dataSource = pipe.options === undefined
? new DataSource(dataSource)
: new DataSource(dataSource, pipe.options);
dataSource = new DataSource(dataSource, dataFields, dataCalculators);
dataFields = dataCalculators = undefined; // for first data source only

@@ -381,7 +389,16 @@ sources[pipe.name] = dataSource;

/**
* @param {number} [newLength=0]
*/
truncatePipeline: function(newLength) {
this.pipeline.length = newLength || 0;
},
/**
* Add a pipe to the data source pipeline.
* @desc No-op if already added.
* @param {dataSourcePipelineObject} newPipe - The new pipeline pipe.
* @param {string} [referencePipe] - One of:
* * Name of an existing pipeline pipe after which the new pipe will be added. If `null`, inserts at beginning. If not found (or `undefined` or omitted), adds to end.
* @param {dataSourcePipelineObject} newPipe
* @param {string|null|undefined} [afterPipe] - One of:
* * `null` - Inserts at beginning.
* * *string* - Name of an existing pipe _after which_ the new pipe will be added.
* * *else* _(including `undefined` or omitted)_ - Adds to end.
* @memberOf dataModels.JSON.prototype

@@ -421,3 +438,3 @@ */

getTopTotals: function() {
return this.hasAggregates() ? this.dataSource.getGrandTotals() : this.topTotals;
return this.dataSource.getGrandTotals() || this.topTotals;
},

@@ -438,3 +455,3 @@

getBottomTotals: function() {
return this.hasAggregates() ? this.dataSource.getGrandTotals() : this.bottomTotals;
return this.dataSource.getGrandTotals() || this.bottomTotals;
},

@@ -444,55 +461,4 @@

* @memberOf dataModels.JSON.prototype
* @param groups
*/
setGroups: function(groups) {
this.sources.aggregator.setGroupBys(groups);
this.applyAnalytics();
this.grid.fireSyntheticGroupsChangedEvent(this.getGroups());
},
/**
* @memberOf dataModels.JSON.prototype
* @returns {object[]}
*/
getGroups: function() {
var headers = this.getHeaders().slice(0);
var fields = this.getFields().slice(0);
var groupBys = this.sources.aggregator.groupBys;
var groups = [];
for (var i = 0; i < groupBys.length; i++) {
var field = headers[groupBys[i]];
groups.push({
id: groupBys[i],
label: field,
field: fields
});
}
return groups;
},
/**
* @memberOf dataModels.JSON.prototype
* @returns {object[]}
*/
getAvailableGroups: function() {
var headers = this.sources.source.getHeaders().slice(0);
var groupBys = this.sources.aggregator.groupBys;
var groups = [];
for (var i = 0; i < headers.length; i++) {
if (groupBys.indexOf(i) === -1) {
var field = headers[i];
groups.push({
id: i,
label: field,
field: field
});
}
}
return groups;
},
/**
* @memberOf dataModels.JSON.prototype
* @returns {object[]}
*/
getActiveColumns: function() {

@@ -525,14 +491,4 @@ return this.grid.behavior.columns.filter(function(column) {

},
/**
* @memberOf dataModels.JSON.prototype
* @param aggregations
*/
setAggregates: function(aggregations) {
this.sources.aggregator.setAggregates(aggregations);
this.applyAnalytics();
},
/**
* @memberOf dataModels.JSON.prototype
* @returns {boolean}

@@ -542,3 +498,3 @@ */

var showTree = this.grid.resolveProperty('showTreeColumn') === true;
return this.hasAggregates() && this.hasGroups() && showTree;
return this.isDrillDown() && showTree;
},

@@ -549,3 +505,3 @@

*/
applyAnalytics: function(dontApplyAggregator) {
applyAnalytics: function(options) {
selectedDataRowsBackingSelectedGridRows.call(this);

@@ -556,20 +512,11 @@

switch (pipe.type) {
case 'DataSourceAggregator':
if (dontApplyAggregator) {
dataSource = undefined;
}
break;
if (dataSource) {
if (dataSource.sorts) {
dataSource.set(this.getSortedColumnIndexes().slice());
}
case 'DataSourceSorterComposite':
if (sources.aggregator && sources.aggregator.viewMakesSense()) {
dataSource = sources.groupsorter;
}
dataSource.setSorts(this.getPrivateState().sorts);
break;
if (dataSource.apply) {
dataSource.apply(options);
}
}
if (dataSource && dataSource.apply) {
dataSource.apply();
}
}.bind(this, this.sources));

@@ -587,3 +534,3 @@

this.incrementSortState(colIndex, keys);
this.applyAnalytics(true);
this.applyAnalytics({columnSort: true});
},

@@ -597,5 +544,4 @@

unSortColumn: function(columnIndex, deferred) {
var state = this.getPrivateState(),
sorts = state.sorts = state.sorts || [],
sortPosition;
var sorts = this.getSortedColumnIndexes(),
sortPosition, found;

@@ -606,5 +552,23 @@ if (sorts.find(function(sortSpec, index) {

})) {
sorts.splice(sortPosition, 1);
if (sorts.length === 1) {
for (var dataSource = this.dataSource; dataSource; dataSource = dataSource.dataSource) {
if (dataSource.defaultSortColumn) {
found = true;
break;
}
}
}
if (found) {
// Make the sole remaining sorted column the tree column of the "joined" data source
sorts[0] = {
columnIndex: dataSource.defaultSortColumn.index,
direction: 1
};
} else {
sorts.splice(sortPosition, 1);
}
if (!deferred) {
this.applyAnalytics(true);
this.applyAnalytics({columnSort: true});
}

@@ -618,3 +582,5 @@ }

getSortedColumnIndexes: function() {
return (this.getPrivateState().sorts || []).slice();
var state = this.getPrivateState();
state.sorts = state.sorts || [];
return state.sorts;
},

@@ -628,7 +594,4 @@

incrementSortState: function(columnIndex, keys) {
var state = this.getPrivateState(),
sorts = state.sorts = state.sorts || [],
sortPosition,
var sorts = this.getSortedColumnIndexes(),
sortSpec = sorts.find(function(spec, index) {
sortPosition = index;
return spec.columnIndex === columnIndex;

@@ -639,7 +602,10 @@ });

if (keys.indexOf('CTRL') < 0) { sorts.length = 0; }
sorts.unshift({ columnIndex: columnIndex, direction: 1 }); // so make ascending
sorts.unshift({
columnIndex: columnIndex, // so define and...
direction: 1 // ...make ascending
});
} else if (sortSpec.direction > 0) { // was ascending
sortSpec.direction = -1; // so make descending
} else { // was descending
sorts.splice(sortPosition, 1); // so make unsorted
this.unSortColumn(columnIndex, true); // so make unsorted
}

@@ -660,4 +626,4 @@

getSortImageForColumn: function(columnIndex) {
var sorts = this.getPrivateState().sorts || [],
sortPosition,
var sortPosition,
sorts = this.getSortedColumnIndexes(),
sortSpec = sorts.find(function(spec, index) {

@@ -693,9 +659,12 @@ sortPosition = index;

* @param event
* @return {boolean} Clicked in a drill-down column.
* @memberOf dataModels.JSON.prototype
*/
cellClicked: function(cell, event) {
if (this.isDrillDown(event)) {
var clickedInDrillDownColumn = this.isDrillDown(event);
if (clickedInDrillDownColumn) {
var y = event.gridCell.y - this.grid.getHeaderRowCount();
this.toggleRow(y);
}
return clickedInDrillDownColumn;
},

@@ -717,2 +686,3 @@

toggleRow: function(y, expand) {
//TODO: fire a row toggle event
var changed;

@@ -722,3 +692,3 @@ if (this.isDrillDown()) {

if (changed) {
this.applyAnalytics(true);
this.applyAnalytics({rowClick: true});
this.changed();

@@ -737,4 +707,6 @@ }

var headerRowCount = this.grid.getHeaderRowCount();
if (y < headerRowCount && !this.hasAggregates()) {
var topTotals = this.getTopTotals();
var topTotals = this.getTopTotals();
var hasToptotals = !!topTotals.length;
if (y < headerRowCount && !hasToptotals) {
return topTotals[y - (headerRowCount - topTotals.length)];

@@ -745,19 +717,4 @@ }

/**
* @memberOf dataModels.JSON.prototype
* @param {number} y
* @returns {object}
*/
buildRow: function(y) {
var colCount = this.getColumnCount();
var fields = [].concat(this.getFields());
var result = {};
if (this.hasAggregates()) {
result.tree = this.getValue(-2, y);
fields.shift();
}
for (var i = 0; i < colCount; i++) {
result[fields[i]] = this.getValue(i, y);
}
return result;
return this.deprecated('buildRow', 'dataSource', '1.0.8');
},

@@ -781,14 +738,4 @@

/**
* @memberOf dataModels.JSON.prototype
* @param {string} fieldName
* @param {number} y
* @returns {*}
*/
getValueByField: function(fieldName, y) {
var index = this.getFields().indexOf(fieldName);
if (this.hasAggregates()) {
y += 1;
}
return this.dataSource.getValue(index, y);
return this.deprecated('getValueByField', 'dataSource', '1.0.8');
},

@@ -795,0 +742,0 @@

@@ -726,2 +726,8 @@ /* eslint-env browser */

/** Ignore sort interaction (double-click).
* @type {boolean}
* @default
*/
unsortable: false,
};

@@ -728,0 +734,0 @@

@@ -26,11 +26,13 @@ /* eslint-env browser */

// grab the lists from the behavior
this.selectedGroups = {
title: 'Groups',
models: behavior.getGroups()
};
if (behavior.setGroups){
this.selectedGroups = {
title: 'Groups',
models: behavior.getGroups()
};
this.availableGroups = {
title: 'Available Groups',
models: behavior.getAvailableGroups()
};
this.availableGroups = {
title: 'Available Groups',
models: behavior.getAvailableGroups()
};
}

@@ -112,6 +114,7 @@ this.inactiveColumns = {

onClosed: function() {
var behavior = this.grid.behavior,
columns = behavior.columns;
if (this.activeColumns) {
var behavior = this.grid.behavior,
columns = behavior.columns,
tree = columns[0];
var tree = columns[0];

@@ -126,6 +129,2 @@ // TODO: breaking encapsulation; should be using setters and getters on the behavior

});
var groupBys = this.selectedGroups.models.map(function(e) {
return e.id;
});
behavior.dataModel.setGroups(groupBys);

@@ -139,2 +138,9 @@ if (this.sortOnHiddenColumns !== this.wasSortOnHiddenColumns) {

}
if (this.selectedGroups){
var groupBys = this.selectedGroups.models.map(function(e) {
return e.id;
});
behavior.dataModel.setGroups(groupBys);
}
}

@@ -141,0 +147,0 @@ });

@@ -18,2 +18,4 @@ 'use strict';

handleClick: function(grid, event) {
var consumed;
if (

@@ -23,4 +25,6 @@ event.gridCell.y >= grid.behavior.getHeaderRowCount() &&

) {
grid.cellClicked(event);
} else if (this.next) {
consumed = grid.cellClicked(event);
}
if (!consumed && this.next) {
this.next.handleClick(grid, event);

@@ -27,0 +31,0 @@ }

@@ -20,3 +20,8 @@ 'use strict';

var gridCell = event.gridCell;
if (grid.isShowHeaderRow() && gridCell.y === 0 && gridCell.x !== -1) {
if (
grid.isShowHeaderRow() &&
gridCell.y === 0 &&
gridCell.x !== -1 &&
!grid.behavior.getColumnProperties(gridCell.x).unsortable
) {
var keys = event.primitiveEvent.detail.keys;

@@ -36,4 +41,8 @@ grid.toggleSort(gridCell.x, keys);

handleMouseMove: function(grid, event) {
var y = event.gridCell.y;
if (this.isFixedRow(grid, event) && y < 1) {
var gridCell = event.gridCell;
if (
this.isFixedRow(grid, event) &&
gridCell.y < 1 &&
!grid.behavior.getColumnProperties(gridCell.x).unsortable
) {
this.cursor = 'pointer';

@@ -40,0 +49,0 @@ } else {

@@ -47,2 +47,3 @@ 'use strict';

* @param {Feature} nextFeature - this is how we build the chain of responsibility
* @private Not really private but was cluttering up all the feature doc pages.
*/

@@ -79,2 +80,3 @@ setNext: function(nextFeature) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
*/

@@ -92,2 +94,3 @@ handleMouseMove: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
*/

@@ -105,2 +108,3 @@ handleMouseExit: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
*/

@@ -118,2 +122,3 @@ handleMouseEnter: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
*/

@@ -131,2 +136,3 @@ handleMouseDown: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
*/

@@ -144,2 +150,3 @@ handleMouseUp: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
*/

@@ -157,2 +164,3 @@ handleKeyDown: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
*/

@@ -170,2 +178,3 @@ handleKeyUp: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
*/

@@ -183,2 +192,3 @@ handleWheelMoved: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
*/

@@ -196,2 +206,3 @@ handleDoubleClick: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
*/

@@ -209,2 +220,3 @@ handleClick: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
*/

@@ -222,2 +234,3 @@ handleMouseDrag: function(grid, event) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
*/

@@ -233,4 +246,4 @@ handleContextMenu: function(grid, event) {

* @desc toggle the column picker
* @private Not really private but was cluttering up all the feature doc pages.
*/
moveSingleSelect: function(grid, x, y) {

@@ -249,5 +262,3 @@ if (this.next) {

isFixedRow: function(grid, event) {
var gridCell = event.viewPoint;
var isFixed = gridCell.y < grid.getFixedRowCount();
return isFixed;
return event.viewPoint.y < grid.getFixedRowCount();
},

@@ -262,5 +273,3 @@

isFirstFixedRow: function(grid, event) {
var gridCell = event.viewPoint;
var isFixed = gridCell.y < 1;
return isFixed;
return event.viewPoint.y < 1;
},

@@ -275,5 +284,3 @@

isFixedColumn: function(grid, event) {
var gridCell = event.viewPoint;
var isFixed = gridCell.x < grid.getFixedColumnCount();
return isFixed;
return event.viewPoint.x < grid.getFixedColumnCount();
},

@@ -288,6 +295,3 @@

isFirstFixedColumn: function(grid, event) {
var gridCell = event.viewPoint;
var edge = grid.isShowRowNumbers() ? 0 : 1;
var isFixed = gridCell.x < edge;
return isFixed;
return event.viewPoint.x === 0;
},

@@ -302,4 +306,3 @@

isTopLeft: function(grid, event) {
var isTopLeft = this.isFixedRow(grid, event) && this.isFixedColumn(grid, event);
return isTopLeft;
return this.isFixedRow(grid, event) && this.isFixedColumn(grid, event);
},

@@ -312,2 +315,3 @@

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
*/

@@ -328,2 +332,3 @@ setCursor: function(grid) {

* @param {Object} event - the event details
* @private Not really private but was cluttering up all the feature doc pages.
*/

@@ -330,0 +335,0 @@ initializeOn: function(grid) {

@@ -11,3 +11,3 @@ 'use strict';

/**
* @desc Hhandle this event down the feature chain of responsibility.
* @desc Handle this event down the feature chain of responsibility.
* @param {Hypergrid} grid

@@ -25,6 +25,4 @@ * @param {Object} event - the event details

grid.setHoverCell(event.gridCell);
} else {
if (this.next) {
this.next.handleMouseMove(grid, event);
}
} else if (this.next) {
this.next.handleMouseMove(grid, event);
}

@@ -31,0 +29,0 @@ }

@@ -18,3 +18,3 @@ 'use strict';

this.schema = columns.map(function(column) {
return {
var item = {
name: column.name,

@@ -24,2 +24,8 @@ alias: column.header,

};
if (column.calculator) {
item.calculator = column.calculator;
}
return item;
});

@@ -26,0 +32,0 @@ }

@@ -26,3 +26,3 @@ 'use strict';

*
* @param {object} operatorsHash - Hash of valid operators. Each is an object, the only property of interest being `complex` which if truthy means operand may be a list of multiple operands.
* @param {object} operatorsHash - Hash of valid operators.
* @param {object} [options]

@@ -104,6 +104,10 @@ * @param {menuItem[]} [options.schema] - Column schema for column name/alias validation. Throws an error if name fails validation (but see `resolveAliases`). Omit to skip column name validation.

var booleans = cql.match(REGEXP_BOOLS);
return booleans && booleans.map(function(bool) {
return bool.toLowerCase();
});
},
validateBooleans: function(booleans) {
if (booleans) {
var heterogeneousOperator = booleans.find(function(op, i) {
booleans[i] = op.toLowerCase();
return booleans[i] !== booleans[0];

@@ -113,6 +117,5 @@ });

if (heterogeneousOperator) {
throw new ParserCqlError('Expected homogeneous boolean operators. You cannot mix AND, OR, and NOR operators here because the order of operations is ambiguous. Everything after your ' + heterogeneousOperator.toUpperCase() + ' was ignored. Tip: You can group operations with subexpressions but only in the QueryBuilder or by using parentheses in SQL.');
throw new ParserCqlError('Expected homogeneous boolean operators. You cannot mix AND, OR, and NOR operators here because the order of operations is ambiguous.\nTip: In Manage Filters, you can group operations with subexpressions in the Query Builder tab or by using parentheses in the SQL tab.');
}
}
return booleans;

@@ -217,2 +220,61 @@ },

/**
* @summary The position of the operator of the expression under the cursor.
* @param {string} cql - CQL expression under construction.
* @param {number} cursor - Current cursor's starting position (`input.startSelection`)
* @returns {{start: number, end: number}}
*/
getOperatorPosition: function(cql, cursor) {
// first tokenize literals in case they contain booleans...
var literals = [];
cql = tokenizeLiterals(cql, ParserCQL.qt, literals);
// ...then expand tokens but with x's just for length
cql = cql.replace(this.REGEX_LITERAL_TOKENS, function(match, index) {
var length = 1 + literals[index].length + 1; // add quote chars
return Array(length + 1).join('x');
});
var booleans, expressions, position, tabs, end, tab, expression, oldOperator, oldOperatorOffset;
if ((booleans = this.captureBooleans(cql))) {
// boolean(s) found so concatenated expressions
expressions = this.captureExpressions(cql, booleans);
position = 0;
tabs = expressions.map(function(expr, idx) { // get starting position of each expression
var bool = booleans[idx - 1] || '';
position += expr.length + bool.length;
return position;
});
// find beginning of expression under cursor position
tabs.find(function(tick, idx) {
tab = idx;
return cursor <= tick;
});
cursor = tabs[tab - 1] || 0;
end = cursor += (booleans[tab - 1] || '').length;
expression = expressions[tab];
} else {
// booleans not found so single expression
cursor = 0;
end = cql.length;
expression = cql;
}
oldOperatorOffset = expression.search(this.REGEX_OPERATOR);
if (oldOperatorOffset >= 0) {
oldOperator = expression.match(this.REGEX_OPERATOR)[0];
cursor += oldOperatorOffset;
end = cursor + oldOperator.length;
}
return {
start: cursor,
end: end
};
},
/**
* @summary Make a "locked" subexpression definition object from an expression chain.

@@ -239,3 +301,3 @@ * @desc _Locked_ means it is locked to a single field.

var booleans = this.captureBooleans(cql),
var booleans = this.validateBooleans(this.captureBooleans(cql)),
expressions = this.captureExpressions(cql, booleans),

@@ -242,0 +304,0 @@ children = this.makeChildren(columnName, expressions, literals),

@@ -67,2 +67,3 @@ 'use strict';

var link = chain[i],
name = link.match(/\w+/)[0],
actualArgList = regexIsMethod.test(link) ? argList(link) : undefined,

@@ -74,5 +75,5 @@ actualArgs = [];

link = link.match(/(\w+)/)[1];
result = result[link].apply(result, actualArgs);
result = result[name].apply(result, actualArgs);
} else {
result = result[link];
result = result[name]();
}

@@ -79,0 +80,0 @@ }

@@ -809,3 +809,3 @@ /* eslint-env browser */

// For each column...
for (x = loopStart; x < loopLength; x++, clipX += clipWidth) {
for (x = loopStart; x < loopLength; x++) {

@@ -819,3 +819,3 @@ c = visibleCols[x];

// TODO: if extra clip() calls per column affect performance (not the clipping itself which was happening anyway, but the clip calls which set up the clipping), use previous strategy when there is a background color
clipWidth = columnEdges[x + 1] - clipX;
clipWidth = columnEdges[x + 1];
gc.beginPath();

@@ -1030,2 +1030,3 @@ gc.rect(clipX, clipY, clipWidth, clipHeight);

cellProperties.columnName = column.name;
cellProperties.calculator = column.calculator;

@@ -1032,0 +1033,0 @@ cellProperties.value = grid.getValue(c, r);

@@ -10,3 +10,3 @@ /* eslint-env browser */

analytics: require('hyper-analytics'), // npm
//analytics: require('../../hyper-analytics/src'), // developers
//analytics: require('../../hyper-analytics'), // developers

@@ -13,0 +13,0 @@ FilterTree: require('filter-tree'), // npm

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc