Skip to content

Commit 93be7a5

Browse files
Rasmus LundsgaardmartinRenou
authored andcommitted
fix for the issue of merging nested rows
Signed-off-by: Rasmus Lundsgaard <[email protected]>
1 parent 825a02a commit 93be7a5

File tree

6 files changed

+115
-5
lines changed

6 files changed

+115
-5
lines changed

js/core/viewbasedjsonmodel.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,13 @@ export class ViewBasedJSONModel extends MutableDataModel {
6060

6161
// Creating merged row cell groups
6262
let mergedRowLocations = ArrayUtils.generateRowMergedCellLocations(this);
63-
if (!ArrayUtils.validateMergingHierarchy(mergedColumnLocations)) {
63+
if (!ArrayUtils.validateMergingHierarchy(mergedRowLocations)) {
6464
mergedRowLocations = [];
6565
}
66-
this._rowCellGroups = ArrayUtils.generateRowCellGroups(mergedRowLocations);
66+
this._mergedRowCellLocations = mergedRowLocations;
67+
this._rowCellGroups = ArrayUtils.generateRowCellGroups(
68+
this._mergedRowCellLocations,
69+
);
6770
}
6871

6972
/**
@@ -606,6 +609,7 @@ export class ViewBasedJSONModel extends MutableDataModel {
606609
protected _dataset: DataSource;
607610
protected readonly _transformState: TransformStateManager;
608611
private _mergedColumnCellLocations: any[];
612+
private _mergedRowCellLocations: any[];
609613
private _rowCellGroups: CellGroup[];
610614
private _columnCellGroups: CellGroup[];
611615
}

js/utils.ts

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,22 @@ export namespace ArrayUtils {
9898
const retArr = [];
9999
let curCol = [];
100100

101-
let prevVal = undefined;
102101
for (let i = 0; i < primaryKey.length; i++) {
102+
let prevVal = undefined;
103103
let curMergedRange: any = [];
104104
for (let j = 0; j < dataset.length; j++) {
105105
const curVal = data[primaryKey[i]][j];
106-
if (curMergedRange.length == 0 || prevVal == curVal) {
106+
// if (curMergedRange.length == 0 || prevVal == curVal) {
107+
const [parentGroupStart, parentGroupEnd] = getParentGroupPosition(
108+
retArr,
109+
j,
110+
i,
111+
);
112+
if (
113+
curMergedRange.length == 0 || (prevVal == curVal) &&
114+
curMergedRange[0][0] >= parentGroupStart &&
115+
j <= parentGroupEnd
116+
) {
107117
curMergedRange.push([j, i]);
108118
} else {
109119
curCol.push(curMergedRange);
@@ -119,6 +129,33 @@ export namespace ArrayUtils {
119129
return retArr;
120130
}
121131

132+
/**
133+
* Returns [startRow, endRow] of parent column at the same row position.
134+
* The 0th row will be the top level group, and the n-th will be the last.
135+
* @param retArr array of merge cellgroups in all previous columns
136+
* @param rowNum current row number
137+
* @param colNum current column number
138+
* @returns.[startRow, endRow] of previous column
139+
*/
140+
function getParentGroupPosition(
141+
retArr: any,
142+
rowNum: number,
143+
colNum: number,
144+
): number[] {
145+
if (colNum === 0) {return [0, rowNum]};
146+
for (let i = 0; i < retArr[colNum-1].length; i++) {
147+
// iterate mergegroups of previous row
148+
const curMergedGroup = retArr[colNum-1][i];
149+
const curMergedGroupLen = curMergedGroup.length;
150+
const firstRow = curMergedGroup[0][0];
151+
const lastRow = curMergedGroup[curMergedGroupLen - 1][0];
152+
if (rowNum >= firstRow && rowNum <= lastRow) {
153+
return [firstRow!, lastRow!];
154+
}
155+
}
156+
return [];
157+
}
158+
122159
/**
123160
* Checks whether the merged cell ranges conform to a valid hierarchy.
124161
* @param retVal boolean
25.1 KB
Loading
25.2 KB
Loading
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"id": "30354eb9",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"import numpy as np\n",
11+
"import pandas as pd\n",
12+
"import ipydatagrid as g\n",
13+
"\n",
14+
"np.random.seed(1)\n",
15+
"\n",
16+
"# merging of lower level row headers\n",
17+
"col_top_level = [\n",
18+
" \"VeryLongValueFactors\",\n",
19+
" \"VeryLongValueFactors\",\n",
20+
" \"Even Longer Momentum Factors\",\n",
21+
" \"Even Longer Momentum Factors\",\n",
22+
"]\n",
23+
"col_bottom_level = [\"Factor_A\", \"Factor_B\", \"Factor_C\", \"Factor_D\"]\n",
24+
"# Rows\n",
25+
"row_top_level = [\"Sector 1\", \"Sector 1\", \"Sector 2\", \"Sector 2\", \"Sector 3\"]\n",
26+
"row_bottom_level = [\"Security A\", \"Security B\", \"Security C\", \"Security C\", \"Security C\"]\n",
27+
"\n",
28+
"nested_df = pd.DataFrame(\n",
29+
" np.random.randn(5, 4).round(4),\n",
30+
" columns=pd.MultiIndex.from_arrays([col_top_level, col_bottom_level]),\n",
31+
" index=pd.MultiIndex.from_arrays(\n",
32+
" [row_top_level, row_bottom_level], names=(\"Sector\", \"Ticker\")\n",
33+
" ),\n",
34+
")\n",
35+
"\n",
36+
"nested_grid = g.DataGrid(\n",
37+
" nested_df,\n",
38+
" base_column_size=80,\n",
39+
" base_column_header_size=35,\n",
40+
" base_row_header_size=80,\n",
41+
" layout={\"height\": \"180px\"}\n",
42+
")\n",
43+
"\n",
44+
"nested_grid"
45+
]
46+
}
47+
],
48+
"metadata": {
49+
"kernelspec": {
50+
"display_name": "Python 3 (ipykernel)",
51+
"language": "python",
52+
"name": "python3"
53+
},
54+
"language_info": {
55+
"codemirror_mode": {
56+
"name": "ipython",
57+
"version": 3
58+
},
59+
"file_extension": ".py",
60+
"mimetype": "text/x-python",
61+
"name": "python",
62+
"nbconvert_exporter": "python",
63+
"pygments_lexer": "ipython3",
64+
"version": "3.12.2"
65+
}
66+
},
67+
"nbformat": 4,
68+
"nbformat_minor": 5
69+
}

ui-tests-ipw8/tests/notebooks/datagrid_nested_hierarchies_update.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@
130130
"name": "python",
131131
"nbconvert_exporter": "python",
132132
"pygments_lexer": "ipython3",
133-
"version": "3.9.9"
133+
"version": "3.10.13"
134134
}
135135
},
136136
"nbformat": 4,

0 commit comments

Comments
 (0)