Skip to content

Commit

Permalink
support multiple values
Browse files Browse the repository at this point in the history
  • Loading branch information
cherniavskii committed Aug 1, 2023
1 parent b000b90 commit e5e911b
Show file tree
Hide file tree
Showing 8 changed files with 229 additions and 33 deletions.
18 changes: 11 additions & 7 deletions docs/data/data-grid/pivoting/GridPivotingBasic.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,18 @@ import {
} from '@mui/x-data-grid-premium';

const initialRows = [
{ id: 1, product: 'Product 1', type: 'Type A', price: 10 },
{ id: 2, product: 'Product 2', type: 'Type A', price: 12 },
{ id: 3, product: 'Product 3', type: 'Type B', price: 8 },
{ id: 4, product: 'Product 4', type: 'Type C', price: 20 },
{ id: 1, product: 'Product 1', type: 'Type A', price: 10, quantity: 2 },
{ id: 2, product: 'Product 2', type: 'Type A', price: 12, quantity: 3 },
{ id: 3, product: 'Product 3', type: 'Type B', price: 8, quantity: 1 },
{ id: 4, product: 'Product 4', type: 'Type C', price: 20, quantity: 8 },
];

const initialColumns = [{ field: 'product' }, { field: 'type' }, { field: 'price' }];
const initialColumns = [
{ field: 'product' },
{ field: 'type' },
{ field: 'price' },
{ field: 'quantity' },
];

export default function GridPivotingBasic() {
const apiRef = useGridApiRef();
Expand All @@ -23,8 +28,7 @@ export default function GridPivotingBasic() {
pivotModel: {
rows: ['type'],
columns: ['product'],
value: 'price',
aggFunc: 'sum',
values: [{ field: 'price', aggFunc: 'sum' }],
},
});

Expand Down
19 changes: 11 additions & 8 deletions docs/data/data-grid/pivoting/GridPivotingBasic.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,20 @@ import {
GridRowModel,
unstable_useGridPivoting,
} from '@mui/x-data-grid-premium';
import { unstable_useId as useId } from '@mui/utils';

const initialRows: GridRowModel[] = [
{ id: 1, product: 'Product 1', type: 'Type A', price: 10 },
{ id: 2, product: 'Product 2', type: 'Type A', price: 12 },
{ id: 3, product: 'Product 3', type: 'Type B', price: 8 },
{ id: 4, product: 'Product 4', type: 'Type C', price: 20 },
{ id: 1, product: 'Product 1', type: 'Type A', price: 10, quantity: 2 },
{ id: 2, product: 'Product 2', type: 'Type A', price: 12, quantity: 3 },
{ id: 3, product: 'Product 3', type: 'Type B', price: 8, quantity: 1 },
{ id: 4, product: 'Product 4', type: 'Type C', price: 20, quantity: 8 },
];

const initialColumns: GridColDef[] = [
{ field: 'product' },
{ field: 'type' },
{ field: 'price' },
{ field: 'quantity' },
];

export default function GridPivotingBasic() {
Expand All @@ -29,20 +31,21 @@ export default function GridPivotingBasic() {
pivotModel: {
rows: ['type'],
columns: ['product'],
value: 'price',
aggFunc: 'sum',
values: [{ field: 'price', aggFunc: 'sum' }],
},
});

const inputId = useId();

return (
<div style={{ width: '100%' }}>
<input
id="pivot"
id={inputId}
type="checkbox"
checked={isPivot}
onChange={(e) => setIsPivot(e.target.checked)}
/>
<label htmlFor="pivot">Pivot</label>
<label htmlFor={inputId}>Pivot</label>
<div style={{ height: 400, width: '100%' }}>
<DataGridPremium key={isPivot.toString()} {...props} apiRef={apiRef} />
</div>
Expand Down
57 changes: 57 additions & 0 deletions docs/data/data-grid/pivoting/GridPivotingMultipleValues.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import * as React from 'react';
import {
DataGridPremium,
useGridApiRef,
unstable_useGridPivoting,
} from '@mui/x-data-grid-premium';

const initialRows = [
{ id: 1, product: 'Product 1', type: 'Type A', price: 10, quantity: 2 },
{ id: 2, product: 'Product 2', type: 'Type A', price: 12, quantity: 3 },
{ id: 3, product: 'Product 3', type: 'Type B', price: 8, quantity: 1 },
{ id: 4, product: 'Product 4', type: 'Type C', price: 20, quantity: 8 },
];

const initialColumns = [
{ field: 'product' },
{ field: 'type' },
{ field: 'price' },
{ field: 'quantity' },
];

export default function GridPivotingMultipleValues() {
const apiRef = useGridApiRef();

const { isPivot, setIsPivot, props } = unstable_useGridPivoting({
rows: initialRows,
columns: initialColumns,
pivotModel: {
rows: ['type'],
columns: ['product'],
values: [
{ field: 'price', aggFunc: 'sum' },
{ field: 'quantity', aggFunc: 'avg' },
],
},
});

return (
<div style={{ width: '100%' }}>
<input
id="pivot"
type="checkbox"
checked={isPivot}
onChange={(e) => setIsPivot(e.target.checked)}
/>
<label htmlFor="pivot">Pivot</label>
<div style={{ height: 400, width: '100%' }}>
<DataGridPremium
key={isPivot.toString()}
{...props}
apiRef={apiRef}
experimentalFeatures={{ columnGrouping: true }}
/>
</div>
</div>
);
}
15 changes: 15 additions & 0 deletions docs/data/data-grid/pivoting/GridPivotingMultipleValues.preview
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<input
id="pivot"
type="checkbox"
checked={isPivot}
onChange={(e) => setIsPivot(e.target.checked)}
/>
<label htmlFor="pivot">Pivot</label>
<div style={{ height: 400, width: '100%' }}>
<DataGridPremium
key={isPivot.toString()}
{...props}
apiRef={apiRef}
experimentalFeatures={{ columnGrouping: true }}
/>
</div>
62 changes: 62 additions & 0 deletions docs/data/data-grid/pivoting/GridPivotingMultipleValues.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import * as React from 'react';
import {
DataGridPremium,
useGridApiRef,
GridColDef,
GridRowModel,
unstable_useGridPivoting,
} from '@mui/x-data-grid-premium';
import { unstable_useId as useId } from '@mui/utils';

const initialRows: GridRowModel[] = [
{ id: 1, product: 'Product 1', type: 'Type A', price: 10, quantity: 2 },
{ id: 2, product: 'Product 2', type: 'Type A', price: 12, quantity: 3 },
{ id: 3, product: 'Product 3', type: 'Type B', price: 8, quantity: 1 },
{ id: 4, product: 'Product 4', type: 'Type C', price: 20, quantity: 8 },
];

const initialColumns: GridColDef[] = [
{ field: 'product' },
{ field: 'type' },
{ field: 'price' },
{ field: 'quantity' },
];

export default function GridPivotingMultipleValues() {
const apiRef = useGridApiRef();

const { isPivot, setIsPivot, props } = unstable_useGridPivoting({
rows: initialRows,
columns: initialColumns,
pivotModel: {
rows: ['type'],
columns: ['product'],
values: [
{ field: 'price', aggFunc: 'sum' },
{ field: 'quantity', aggFunc: 'avg' },
],
},
});

const inputId = useId();

return (
<div style={{ width: '100%' }}>
<input
id={inputId}
type="checkbox"
checked={isPivot}
onChange={(e) => setIsPivot(e.target.checked)}
/>
<label htmlFor={inputId}>Pivot</label>
<div style={{ height: 400, width: '100%' }}>
<DataGridPremium
key={isPivot.toString()}
{...props}
apiRef={apiRef}
experimentalFeatures={{ columnGrouping: true }}
/>
</div>
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<input
id="pivot"
type="checkbox"
checked={isPivot}
onChange={(e) => setIsPivot(e.target.checked)}
/>
<label htmlFor="pivot">Pivot</label>
<div style={{ height: 400, width: '100%' }}>
<DataGridPremium
key={isPivot.toString()}
{...props}
apiRef={apiRef}
experimentalFeatures={{ columnGrouping: true }}
/>
</div>
2 changes: 2 additions & 0 deletions docs/data/data-grid/pivoting/pivoting.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ Pivoting will allow you to take a columns values and turn them into columns.

{{"demo": "GridPivotingBasic.js", "bg": "inline", "defaultCodeOpen": false}}

{{"demo": "GridPivotingMultipleValues.js", "bg": "inline", "defaultCodeOpen": false}}

## API

- [DataGrid](/x/api/data-grid/data-grid/)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import * as React from 'react';
import { GridColDef, GridRowModel } from '@mui/x-data-grid-pro';
import { GridColDef, GridColumnGroupingModel, GridRowModel } from '@mui/x-data-grid-pro';
import { DataGridPremiumProcessedProps } from '../../../models/dataGridPremiumProps';
import { GridAggregationModel } from '../aggregation';

interface PivotModel {
columns: GridColDef['field'][];
rows: GridColDef['field'][];
value: GridColDef['field'];
aggFunc: string;
values: {
field: GridColDef['field'];
aggFunc: string;
}[];
}

const getPivotedData = ({
Expand All @@ -25,6 +27,7 @@ const getPivotedData = ({
aggregationModel: NonNullable<DataGridPremiumProcessedProps['aggregationModel']>;
getAggregationPosition: NonNullable<DataGridPremiumProcessedProps['getAggregationPosition']>;
columnVisibilityModel: NonNullable<DataGridPremiumProcessedProps['columnVisibilityModel']>;
columnGroupingModel: NonNullable<DataGridPremiumProcessedProps['columnGroupingModel']>;
} => {
const pivotColumns: Map<string, GridColDef> = new Map();
const columnVisibilityModel: DataGridPremiumProcessedProps['columnVisibilityModel'] = {};
Expand All @@ -39,24 +42,58 @@ const getPivotedData = ({

const aggregationModel: GridAggregationModel = {};

const valueField = pivotModel.value;
const columnGroupingModel: GridColumnGroupingModel = [];

const newRows: GridRowModel[] = [];
rows.forEach((row) => {
const newRow = { ...row };
pivotModel.columns.forEach((field) => {
const colValue = row[field];
const mapKey = `${field}-${colValue}`;
if (!pivotColumns.has(mapKey)) {
pivotColumns.set(mapKey, {
field: colValue,
aggregable: true,
availableAggregationFunctions: [pivotModel.aggFunc],
});
aggregationModel[colValue] = pivotModel.aggFunc;
}
delete newRow[field];
newRow[colValue] = newRow[valueField];
});
if (pivotModel.values.length === 1) {
const pivotValue = pivotModel.values[0];
pivotModel.columns.forEach((field) => {
const colValue = row[field];
const mapKey = `${field}-${colValue}`;
if (!pivotColumns.has(mapKey)) {
pivotColumns.set(mapKey, {
field: colValue,
aggregable: true,
availableAggregationFunctions: [pivotValue.aggFunc],
});
aggregationModel[colValue] = pivotValue.aggFunc;
}
delete newRow[field];
newRow[colValue] = newRow[pivotValue.field];
});
} else {
pivotModel.columns.forEach((colGroupField) => {
const colValue = row[colGroupField];
const mapKey = `${colGroupField}-${colValue}`;

const columnGroup: GridColumnGroupingModel[number] = {
groupId: mapKey,
headerName: colValue,
children: [],
};

if (!pivotColumns.has(mapKey)) {
columnGroupingModel.push(columnGroup);

pivotModel.values.forEach((pivotValue) => {
const valueField = pivotValue.field;
const mapValueKey = `${mapKey}-${valueField}`;
pivotColumns.set(mapValueKey, {
field: mapValueKey,
headerName: valueField,
aggregable: true,
availableAggregationFunctions: [pivotValue.aggFunc],
});
aggregationModel[mapValueKey] = pivotValue.aggFunc;
columnGroup.children.push({ field: mapValueKey });
newRow[mapValueKey] = newRow[valueField];
delete newRow[valueField];
});
}
});
}

newRows.push(newRow);
});
Expand All @@ -68,6 +105,7 @@ const getPivotedData = ({
aggregationModel,
getAggregationPosition: () => 'inline',
columnVisibilityModel,
columnGroupingModel,
};
};

Expand Down

0 comments on commit e5e911b

Please sign in to comment.