Merge Cells
The Cell Merge feature allows you to combine adjacent cells into a single, larger cell, much like Excelโs merge functionality. This feature is particularly useful for creating headers that span multiple columns or rows and for visually grouping related data within your grid.
const cellMerge = [{ row: 1, column: 1, rowSpan: 2, colSpan: 2, rowType: 'rgRow', colType: 'rgCol' }]Source code
TypeScript ts
// src/components/cell-merge/CellMerged.ts
import { defineCustomElements } from '@revolist/revogrid/loader';
defineCustomElements(); // Define the custom element
import { useRandomData, currentTheme } from '../composables/useRandomData';
import {
CellMergePlugin,
ColumnStretchPlugin,
type MergeData,
} from '@revolist/revogrid-pro';
const { isDark } = currentTheme();
const { createRandomData } = useRandomData();
const initialCellMerge: MergeData[] = [
{ row: 1, column: 0, rowSpan: 3, colSpan: 1, rowType: 'rgRow', colType: 'rgCol' },
{ row: 1, column: 1, rowSpan: 3, colSpan: 1, rowType: 'rgRow', colType: 'rgCol' },
{ row: 4, column: 2, rowSpan: 3, colSpan: 1, rowType: 'rgRow', colType: 'rgCol' },
];
const mergedCell: MergeData = {
row: 1,
column: 1,
rowSpan: 2,
colSpan: 2,
rowType: 'rgRow',
colType: 'rgCol',
};
export function load(parentSelector: string) {
const parent = document.querySelector(parentSelector);
if (!parent) {
return;
}
const button = document.createElement('button');
button.className = 'rv-btn mb-2';
button.textContent = 'Merge Cell';
const lineBreak = document.createElement('br');
const grid = document.createElement('revo-grid');
grid.source = createRandomData(100);
// Define columns
grid.columns = [
{
name: '๐ ID',
prop: 'id',
},
{
name: '๐ Fruit',
prop: 'name',
},
{
name: '๐ฐ Price',
prop: 'price',
},
];
// Define plugin
grid.plugins = [CellMergePlugin, ColumnStretchPlugin];
grid.stretch = 'all';
(grid as HTMLRevoGridElement & { cellMerge: MergeData[] }).cellMerge = initialCellMerge;
button.addEventListener('click', () => {
(grid as HTMLRevoGridElement & { cellMerge: MergeData[] }).cellMerge = [mergedCell];
});
grid.theme = isDark() ? 'darkMaterial' : 'material';
grid.hideAttribution = true;
parent.append(button, lineBreak, grid);
}
Vue vue
// src/components/cell-merge/CellMerged.vue
<template>
<div>
<button
class="rv-btn mb-2"
@click="addCellMerge"
>
Merge Cell
</button>
<br />
<VGrid
:theme="isDark ? 'darkMaterial' : 'material'"
:columns="columns"
:source="rows"
:plugins="plugins"
stretch="all"
:cell-merge="cellMerge"
hide-attribution
/>
</div>
</template>
<script setup lang="ts">
import { ref, shallowRef } from 'vue';
import { VGrid } from '@revolist/vue3-datagrid';
import { CellMergePlugin, ColumnStretchPlugin, type MergeData } from '@revolist/revogrid-pro';
import { currentThemeVue, useRandomData } from '../composables/useRandomData';
const { isDark } = currentThemeVue();
const { createRandomData } = useRandomData();
const columns = ref([
{ name: '๐ ID', prop: 'id' },
{ name: '๐ Fruit', prop: 'name' },
{ name: '๐ฐ Price', prop: 'price' },
]);
const plugins = ref([CellMergePlugin, ColumnStretchPlugin]);
const rows = ref(createRandomData(100));
const cellMerge = shallowRef<MergeData[]>([
{ row: 1, column: 0, rowSpan: 3, colSpan: 0, rowType: 'rgRow', colType: 'rgCol' },
{ row: 1, column: 1, rowSpan: 3, colSpan: 0, rowType: 'rgRow', colType: 'rgCol' },
{ row: 4, column: 2, rowSpan: 3, colSpan: 0, rowType: 'rgRow', colType: 'rgCol' },
]);
const addCellMerge = () => {
cellMerge.value = [{
row: 1,
column: 1,
rowSpan: 2,
colSpan: 2,
rowType: 'rgRow',
colType: 'rgCol',
}];
};
</script>
React tsx
// src/components/cell-merge/CellMerged.tsx
import { useState, useMemo } from 'react';
import { RevoGrid, type DataType } from '@revolist/react-datagrid';
import {
CellMergePlugin,
ColumnStretchPlugin,
type MergeData,
} from '@revolist/revogrid-pro';
import { useRandomData, currentTheme } from '../composables/useRandomData';
const { isDark } = currentTheme();
const { createRandomData } = useRandomData();
const initialCellMerge: MergeData[] = [
{ row: 1, column: 0, rowSpan: 3, colSpan: 1, rowType: 'rgRow', colType: 'rgCol' },
{ row: 1, column: 1, rowSpan: 3, colSpan: 1, rowType: 'rgRow', colType: 'rgCol' },
{ row: 4, column: 2, rowSpan: 3, colSpan: 1, rowType: 'rgRow', colType: 'rgCol' },
];
const mergedCell: MergeData = {
row: 1,
column: 1,
rowSpan: 2,
colSpan: 2,
rowType: 'rgRow',
colType: 'rgCol',
};
function CellMerged() {
const [source] = useState<DataType[]>(createRandomData(100));
const [cellMerge, setCellMerge] = useState<MergeData[]>(initialCellMerge);
const columns = useMemo(
() => [
{ name: '๐ ID', prop: 'id' },
{ name: '๐ Fruit', prop: 'name' },
{ name: '๐ฐ Price', prop: 'price' },
],
[]
);
const handleMergeClick = () => {
setCellMerge([mergedCell]);
};
return (
<div>
<button className="rv-btn mb-2" onClick={handleMergeClick}>
Merge Cell
</button>
<br />
<RevoGrid
columns={columns}
source={source}
stretch="all"
cellMerge={cellMerge}
hide-attribution
theme={isDark() ? 'darkMaterial' : 'material'}
plugins={[CellMergePlugin, ColumnStretchPlugin]}
/>
</div>
);
}
export default CellMerged;
Angular ts
// src/components/cell-merge/CellMergedAngular.ts
import {
Component,
ElementRef,
ViewChild,
ViewEncapsulation,
type AfterViewInit,
type OnInit,
} from '@angular/core';
import { RevoGrid } from '@revolist/angular-datagrid';
import {
CellMergePlugin,
ColumnStretchPlugin,
type MergeData,
} from '@revolist/revogrid-pro';
import { useRandomData, currentTheme } from '../composables/useRandomData';
const initialCellMerge: MergeData[] = [
{ row: 1, column: 0, rowSpan: 3, colSpan: 1, rowType: 'rgRow', colType: 'rgCol' },
{ row: 1, column: 1, rowSpan: 3, colSpan: 1, rowType: 'rgRow', colType: 'rgCol' },
{ row: 4, column: 2, rowSpan: 3, colSpan: 1, rowType: 'rgRow', colType: 'rgCol' },
];
const mergedCell: MergeData = {
row: 1,
column: 1,
rowSpan: 2,
colSpan: 2,
rowType: 'rgRow',
colType: 'rgCol',
};
@Component({
selector: 'cell-merge-grid',
standalone: true,
imports: [RevoGrid],
template: `
<button
class="rv-btn mb-2"
(click)="mergeCells()">Merge Cell</button>
<br />
<revo-grid
#grid
[columns]="columns"
[source]="source"
stretch="all"
[hideAttribution]="true"
[theme]="theme"
[plugins]="plugins"
style="min-height: 400px;"
></revo-grid>`,
encapsulation: ViewEncapsulation.None,
})
export class CellMergeGridComponent implements OnInit, AfterViewInit {
@ViewChild('grid', { read: ElementRef }) gridElement!: ElementRef<HTMLRevoGridElement & {
cellMerge: MergeData[];
}>;
theme = currentTheme().isDark() ? 'darkMaterial' : 'material';
source = useRandomData().createRandomData(100);
cellMerge = initialCellMerge;
columns = [
{ name: '๐ ID', prop: 'id' },
{ name: '๐ Fruit', prop: 'name' },
{ name: '๐ฐ Price', prop: 'price' },
];
plugins = [CellMergePlugin, ColumnStretchPlugin];
ngOnInit() {
// Initial setup if necessary
}
ngAfterViewInit() {
this.gridElement.nativeElement.cellMerge = this.cellMerge;
}
mergeCells() {
this.cellMerge = [mergedCell];
this.gridElement.nativeElement.cellMerge = this.cellMerge;
}
}
Why Use Cell Merge?
Section titled โWhy Use Cell Merge?โCell Merge is a powerful tool that can help you:
- Create Merged Headers: Design headers that span across several columns or rows, making it easier to categorize and organize related data.
- Group Data Visually: Highlight or group related data by merging cells, which improves the readability and interpretability of your grid.
Example Use Cases
Section titled โExample Use Casesโ- Merged Headers: Combine cells to create a single header that covers multiple columns. This is ideal for providing overarching categories or labels for grouped columns.
- Data Grouping: Use cell merging to visually segment related data or to emphasize specific sections of your grid.
How It Works
Section titled โHow It WorksโThe Cell Merge feature enables you to specify which cells should be merged into a larger cell. This larger cell will span across multiple columns and/or rows. The content of the merged cell will be centrally displayed, enhancing the layout of your grid.
Since this is a Pro feature, ensure that you have access to the Pro version of RevoGrid to utilize this functionality.
// fixing render for multiframework