Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[1.1.0 Release]: Integrate major upstream changes into ipydatagrid #239

Merged
merged 20 commits into from
Jul 17, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add more cell merging logic
Signed-off-by: Itay Dafna <[email protected]>
  • Loading branch information
ibdafna committed Jun 22, 2021
commit 8b4c4cb4c69edd43719759cc5dba01520da75f5b
39 changes: 24 additions & 15 deletions js/core/viewbasedjsonmodel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,23 +46,30 @@ export class ViewBasedJSONModel extends MutableDataModel {
// second run: map the index locations generated above to
// the dataset so we have access to the multi index arrays
// only.
let retVal = ArrayUtils.generateDataGridMergedCellLocations(
let mergedColumnLocations = ArrayUtils.generateColMergedCellLocations(
this,
multiIndexArrayLocations,
);
// final run: we need to check that the merging hierarchy makes sense. i.e. we don't
// want to render a merged range below a non-merged range. This function will check
// that this requirement is met. If it is not, we simply render each cell individually
// as if it wasn't grouped.
if (!ArrayUtils.validateMergingHierarchy(retVal)) {
retVal = [];
if (!ArrayUtils.validateMergingHierarchy(mergedColumnLocations)) {
mergedColumnLocations = [];
}
this._mergedCellLocations = retVal;
this._mergedColumnCellLocations = mergedColumnLocations;

// Creating merged cell groups from index locations
this._columnCellGroups = ArrayUtils.generateCellGroups(
this._mergedCellLocations,
// Creating column merged cell groups from index locations
this._columnCellGroups = ArrayUtils.generateColumnCellGroups(
this._mergedColumnCellLocations,
);

// Creating merged row cell groups
let mergedRowLocations = ArrayUtils.generateRowMergedCellLocations(this);
if (!ArrayUtils.validateMergingHierarchy(mergedColumnLocations)) {
mergedRowLocations = [];
}
this._rowCellGroups = ArrayUtils.generateRowCellGroups(mergedRowLocations);
}

/**
Expand Down Expand Up @@ -112,11 +119,15 @@ export class ViewBasedJSONModel extends MutableDataModel {
*/
getMergedSiblingCells(cell: number[]): any[] {
const [row, column] = cell;
if (row < 0 || column < 0 || row >= this._mergedCellLocations.length) {
if (
row < 0 ||
column < 0 ||
row >= this._mergedColumnCellLocations.length
) {
return [];
}

for (const cellGroup of this._mergedCellLocations[row]) {
for (const cellGroup of this._mergedColumnCellLocations[row]) {
for (const rowCell of cellGroup) {
const [rowIndex, columnIndex] = rowCell;
if (row === rowIndex && column == columnIndex) {
Expand Down Expand Up @@ -160,7 +171,7 @@ export class ViewBasedJSONModel extends MutableDataModel {
} else if (region === 'column-header') {
return this._columnCellGroups.length;
} else if (region === 'row-header') {
return 2;
return this._rowCellGroups.length;
}
return 0;
}
Expand All @@ -177,10 +188,7 @@ export class ViewBasedJSONModel extends MutableDataModel {
}

if (region === 'row-header') {
return [
{ r1: 0, c1: 0, r2: 1, c2: 0 },
{ r1: 2, c1: 0, r2: 3, c2: 0 },
][groupIndex];
return this._rowCellGroups[groupIndex];
}

return null;
Expand Down Expand Up @@ -611,7 +619,8 @@ export class ViewBasedJSONModel extends MutableDataModel {

protected _dataset: ViewBasedJSONModel.IData;
protected readonly _transformState: TransformStateManager;
private _mergedCellLocations: any[];
private _mergedColumnCellLocations: any[];
private _rowCellGroups: CellGroup[];
private _columnCellGroups: CellGroup[];
}

Expand Down
56 changes: 37 additions & 19 deletions js/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ export namespace ArrayUtils {
* Returns an array of [mergedCellSiblingGroup]. Each element represents a row of columns.
* The 0th row will be the top level group, and the n-th will be the last.
* @param model the data model.
* @param multiIndexArrayLocations index-based locations of all mutli-index coulmns.
* @param multiIndexArrayLocations index-based locations of all mutli-index columns.
*/
export function generateColMergedCellLocations(
model: any,
multiIndexArrayLocations: number[],
): any[] {
): number[][][][] {
// Terminating if no locations are passed.
if (multiIndexArrayLocations.length === 0) {
return [];
Expand Down Expand Up @@ -73,19 +73,25 @@ export namespace ArrayUtils {
return retArr;
}

export function generateRowMergedCellLocations(dataset: any): any {
/**
* Returns an array of [mergedCellSiblingGroup]. Each element represents a column of rows.
* The 0th row will be the top level group, and the n-th will be the last.
* @param model data model with schema and data fields
* @returns index-based locations of all mutli-index rows.
*/
export function generateRowMergedCellLocations(model: any): number[][][][] {
// Removing internal primary key identifier.
const primaryKey = dataset.schema.primaryKey.slice(
const primaryKey = model._dataset.schema.primaryKey.slice(
0,
dataset.schema.primaryKey.length - 1,
model._dataset.schema.primaryKey.length - 1,
);

// Terminate if we're not dealing with nested row headers.
if (!(primaryKey.length > 1)) {
return [];
}

const data = dataset.data;
const data = model._dataset.data;
const retArr = [];
let curCol = [];

Expand Down Expand Up @@ -114,7 +120,7 @@ export namespace ArrayUtils {
* Checks whether the merged cell ranges conform to a valid hierarchy.
* @param retVal boolean
*/
export function validateMergingHierarchy(retVal: number[][]): boolean {
export function validateMergingHierarchy(retVal: number[][][][]): boolean {
let prevLevelLength;
for (const mergeRange of retVal) {
// First element - setting up the value of prevLevelLength
Expand All @@ -134,6 +140,11 @@ export namespace ArrayUtils {
return true;
}

/**
* Generates a list of merged column cell groups for use in the data model.
* @param indexLists index-based location of merged columns
* @returns CellGroup[]
*/
export function generateColumnCellGroups(
indexLists: number[][][][],
): CellGroup[] {
Expand All @@ -151,22 +162,29 @@ export namespace ArrayUtils {

return columnGroup;
}
}

function generateRowCellGroups(indexLists: number[][][][]): CellGroup[] {
const rowGroup = [];
for (let curCol = 0; curCol < indexLists.length; curCol++) {
for (let groupNum = 0; groupNum < indexLists[curCol].length; groupNum++) {
if (indexLists[curCol][groupNum].length > 1) {
const groupLength = indexLists[curCol][groupNum].length;
const r1 = indexLists[curCol][groupNum][0][0];
const r2 = indexLists[curCol][groupNum][groupLength - 1][0];
rowGroup.push({ r1: r1, c1: curCol, r2: r2, c2: curCol });
/**
* Generates a list of merged row cell groups for use in the data model.
* @param indexLists index-based location of merged rows.
* @returns CellGroup[]
*/
export function generateRowCellGroups(
indexLists: number[][][][],
): CellGroup[] {
const rowGroup = [];
for (let curCol = 0; curCol < indexLists.length; curCol++) {
for (let groupNum = 0; groupNum < indexLists[curCol].length; groupNum++) {
if (indexLists[curCol][groupNum].length > 1) {
const groupLength = indexLists[curCol][groupNum].length;
const r1 = indexLists[curCol][groupNum][0][0];
const r2 = indexLists[curCol][groupNum][groupLength - 1][0];
rowGroup.push({ r1: r1, c1: curCol, r2: r2, c2: curCol });
}
}
}
}

return rowGroup;
return rowGroup;
}
}

// Scalar type
Expand Down