4
votes

Besoin d'afficher les valeurs totales dans le pied de page dans la grille en utilisant angulaire

J'implémente actuellement ag-grid dans mon application angular 7. Je dois inclure le pied de page de chaque groupe que j'ai réalisé. J'aurais maintenant besoin d'afficher le total de EMV (USD) et la colonne de pourcentage comme la capture d'écran ci-dessous. La ligne doit être vide pour chaque cellule à l'exception des deux colonnes mentionnées et les totaux doivent être affichés

entrez la description de l'image ici

Composant

private getColumns(): Array<any> {
        const self = this;
        const definition = [
            { headerName: 'Date', field: 'EvalDate', hide: true },
            { headerName: 'Firm ID', field: 'FirmID', hide: true },
            { headerName: 'Manager Strategy ID', field: 'FirmName', hide: true },
            { headerName: 'Firm', field: 'ManagerStrategyID', hide: true },
            { headerName: 'Manager Strategy', field: 'ManagerStrategyName', hide: false },
            { headerName: 'Fund ID', field: 'ManagerFundID', hide: true },
            { headerName: 'Fund', field: 'ManagerFundName' },
            { headerName: 'Portfolio', field: 'ProductName' },
            {
                headerName: 'As Of', field: 'EvalDate', cellRenderer: (data) => {
                    return data.value ? (new Date(data.value)).toLocaleDateString() : '';
                }
            },
            {
                headerName: 'EMV (USD)', field: 'UsdEmv', valueFormatter: this.currencyFormatter,
                cellRenderer: 'agGroupCellRenderer',
                aggFunc: 'sum',
                cellRendererParams: {
                    footerValueGetter: (params) =>   params.value

                }
            },
            {
                headerName: 'Percent', field: 'GroupPercent', valueFormatter: this.formatPercent,
                cellRenderer: 'agGroupCellRenderer',
                aggFunc: 'sum',
                cellRendererParams: {
                    footerValueGetter: (params) => params.value
                }
            }
        ];
        return definition;
    }


    currencyFormatter(number) {
        // this puts commas into the number eg 1000 goes to 1,000,
        if (!isNaN(number.value)) {
        number = Math.floor(number.value).toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
        number = number === '0' ? '0.00' : number;
        return '$' + number;
        }
    }

     formatPercent(number) {
        if (!isNaN(number.value)) {
            return (number.value * 100).toFixed(2) + '%';
        }
    }

Nouveau code basé sur la réponse proposée

import { Component, Injectable, NgZone, ViewEncapsulation, ViewChild, Input } from '@angular/core';
import { OnInit } from '@angular/core';
import { AllocationsService } from '../services/allocations.service';
import { formatDate } from '@angular/common';
import { GridOptions } from 'ag-grid-community/dist/lib/entities/gridOptions';
import { Comparator } from '../utilities/comparator';
import { ActivatedRoute } from '@angular/router';
import { TestBed } from '@angular/core/testing';


@Component({
    selector: 'mgr-allocations',
    templateUrl: './allocations.component.html'
})


export class AllocationsComponent implements OnInit {

    private Error: string;
    public evalDate: Date;
    private _evalDate: Date;
    public AllocationDetails: any;
    private _ManagerStrategyId: number;
    public GridOptions: GridOptions;
    windowHeight: any;
    offset: number;
    ngZone: any;
    router: any;
    Comparator: Comparator;
    Route: any;

    public get ManagerStrategyId(): number {
        return this._ManagerStrategyId;
    }


    @Input()
    public set ManagerStrategyId(value: number) {
        this._ManagerStrategyId = value;
    }


    constructor(private allocationsService: AllocationsService, private comparator: Comparator,
                private zone: NgZone, private route: ActivatedRoute) {
        this.Comparator = comparator;
        this.Route = route;

        window.onresize = (e) => {
            this.ngZone.run(() => {
                this.windowHeight = window.innerHeight - this.offset;
                setTimeout(() => {
                    if (!this.GridOptions || !this.GridOptions.api) {
                        return;
                    }
                    this.GridOptions.api.sizeColumnsToFit();
                }, 500, true);
            });
        };
    }

    private FormattedDate(dateToFormat: Date): string {
        return formatDate(dateToFormat, 'yyyy/MM/dd', 'en');
    }


    get MissingProductKeys() {
        const  missingProductsTypesNames = this.AllocationDetails.MissingProducts.flat().map(({ProductType}) => ProductType);
        const  uniqueProductTypeNames = new Set(missingProductsTypesNames);
        return  Array.from(uniqueProductTypeNames.values());
    }

    setGridOptions() {
        this.GridOptions = {
            columnDefs: this.getColumns(),
            enableFilter: true,
             treeData: true,
            enableColResize: true,
            animateRows: true,
            groupDefaultExpanded: 1,
            enableSorting: true,
            suppressCellSelection: true,
            groupIncludeFooter: true,
            getDataPath: function (data) {
                return data.Hierarchy;
            },
            onGridReady: e => {
                if (!e || !e.api) {
                    return;
                }
                e.api.sizeColumnsToFit();
                this.setDefaultSortOrder();
            },
            getRowStyle: (params) => {
                if (params.node.level === 0) {
                    return { 'background-color': '#FCE7D7' };
                }
            },

            autoGroupColumnDef: {
                headerName: 'Manager Strategy', width: 300,
                valueFormatter: uniqueColumn
            },

        };
        function uniqueColumn(params) {

        const startIndex = params.value.indexOf('#');
        if (startIndex === -1) { return params.value; }

        const endIndex = params.value.length;
        return params.value.replace(params.value.substring(startIndex, endIndex), '');

    }
    }

    ngOnInit() {
        this.evalDate = new Date();
        this.setGridOptions();
        this.getAllocationsDetails(this.FormattedDate(this.evalDate));

    }

     getAllocationsDetails(evalDate: string) {
        if (this.ManagerStrategyId != null) {
            this.initGrid();
           //this.GridOptions.api.showLoadingOverlay();
            this.allocationsService.getAllocationsDetails(this.ManagerStrategyId, evalDate)
                .subscribe(data => {
                    this.AllocationDetails = data;
                    this.GridOptions.rowData = this.AllocationDetails.ManagerAllocations;
                    setTimeout(() => {
                      //  this.GridOptions.api.hideOverlay();
                    }, 100, true);
                },
                    err => {
                        this.Error = 'An error has occurred. Please contact BSG';
                    },
                    () => {
                      //  this.GridOptions.api.hideOverlay();
                    });
        }
    }


    public evalDateChanged(value: Date): void {
        this.getAllocationsDetails(this.FormattedDate((value)));
    }

    GridHeight() {
        if (!this.windowHeight) {
            this.windowHeight = window.innerHeight - this.offset + 10;
        }
        return this.windowHeight;
    }


    setDefaultSortOrder() {
        const defaultSortModel = [
            { colId: 'ManagerStrategyName', sort: 'asc' },
            { colId: 'ManagerFundName', sort: 'asc' }
        ];
        this.GridOptions.api.setSortModel(defaultSortModel);
    }

    private initGrid() {
        const self = this;
    }



    private getColumns(): Array<any> {
        const self = this;
        const definition = [
            { headerName: 'Date', field: 'EvalDate', hide: true },
            { headerName: 'Firm ID', field: 'FirmID', hide: true },
            { headerName: 'Manager Strategy ID', field: 'FirmName', hide: true },
            { headerName: 'Firm', field: 'ManagerStrategyID', hide: true },
            { headerName: 'Manager Strategy', field: 'ManagerStrategyName' , hide: false },
            { headerName: 'Fund ID', field: 'ManagerFundID', hide: true },
            { headerName: 'Fund', field: 'ManagerFundName' },
            { headerName: 'Portfolio', field: 'ProductName' },
            { headerName: 'As Of', field: 'EvalDate',   cellRenderer: (data) => {
                return data.value ? (new Date(data.value)).toLocaleDateString() : '';
             } },
            { headerName: 'EMV (USD)', field: 'UsdEmv',  valueFormatter: currencyFormatter },
            { headerName: 'Percent', field: 'GroupPercent', valueFormatter: formatPercent },





        ];
        function currencyFormatter(params) {
            if (!isNaN(params.value)) {
            return '$' + formatNumber(params.value);
            }
        }

        function formatNumber(number) {
            // this puts commas into the number eg 1000 goes to 1,000,
             return Math.floor(number).toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, '$1,');
        }

        function formatPercent(number) {
            if (!isNaN(number.value)) {
            return (number.value * 100).toFixed(2) + '%';
            }
        }
        return definition;
    }
}

Nouvelle capture d'écran

 entrez la description de l'image ici p>


1 commentaires

et veuillez arrêter de partager les captures d'écran, partagez plutôt l'URL plinkr \ stackblitz où tout le monde peut tester votre approche


4 Réponses :


1
votes

Pour chaque définition de colonne, vous pouvez passer un paramètre supplémentaire pour modifier le rendu de la colonne

cellRenderer:'agGroupCellRenderer',
cellRendererParams: {
    footerValueGetter: (params) => 'Text (' + params.value + ')'
},
aggFunc: "sum"

où params.value est le nom de la colonne


11 commentaires

Où dois-je ajouter ceci? Dans la méthode setgridOptions de définition de colonne. Aussi comment saura-t-il que le total doit être ajouté pour une colonne spécifique


Doit être dans le tableau de définition de la fonction getColumns, regardez la réponse mise à jour pour la deuxième question.


plus de détails sur le pied de page de regroupement, mais je dirais @Tom, vous devez rechercher les lignes épinglées - c'est beaucoup plus facile que la grille alignée (en pied de page) ou en tant que footerValueGetter - car ce n'est pas assez


J'ai essayé ce qui précède dans ma fonction getColumns et il affiche Text (0)


La grille a-t-elle la capacité de totaliser les lignes de cette colonne en utilisant une fonction intégrée


Obtenez une erreur de compilation lorsque j'ajoute aggFunc: "sum". Impossible de trouver le nom aggFunc


Pouvez-vous ajouter le nouveau code utilisé? Il est utilisé sans problème sur l'un des exemples ici


Salut, j'ai réussi à obtenir les totaux, mais comme vous pouvez le voir, j'ai un problème ici. Le total s'affiche à la fois dans l'en-tête et le pied de page. L'en-tête affiche la valeur correcte en utilisant les fonctions respectives, mais le pied de page ne l'est pas. Je dois l'afficher uniquement dans le pied de page.


Pouvez-vous créer un projet sur Stackblitz et le partager pour que je puisse le tester?


J'ai ajouté le stackblitz mais la grille n'apparaît pas probablement en raison de la licence car il n'y a pas d'erreurs. Cela m'était également arrivé dans l'environnement local, mais après avoir appliqué lincekey, cela a fonctionné. Comment le testeriez-vous. Voici le lien. stackblitz.com/edit/angular-qnddf9


J'ai en quelque sorte essayé de remplir les données mais elles ne semblent pas être correctement formatées. stackblitz.com/edit/angular-c6rqpz



1
votes

J'ai trouvé cela plus tôt, grâce auquel vous pouvez utiliser aligné grilles comme pied de page . Ils ont inclus un exemple, vous devriez donc vous y référer.

Un résumé, sur le composant.html, vous devez inclure le composant ag-grid-angular deux fois sur votre modèle, chacun d'eux avec sa propre gridOptions properties

<ag-grid-angular #topGrid [gridOptions]="topOptions"></ag-grid-angular>
<ag-grid-angular #bottomGrid [gridOptions]="bottomOptions".... ></ag-grid-angular>

Et sur votre component.ts, vous définirez vos columnDefs comme d'habitude, ainsi que les gridOptions code respectifs >.

Comme mentionné dans l'exemple sur le lien ci-dessus, l'alignement des deux grilles vous donnera une grille de pied de page alignée verticalement sur votre grille principale. De cette façon, vous pouvez afficher la valeur totale, etc. sur ce pied de page.


0 commentaires

4
votes

Je l'ai fait d'une manière différente:

let pinnedBottomData = this.generatePinnedBottomData();
this.gridApi.setPinnedBottomRowData([pinnedBottomData]);

generatePinnedBottomData(){
    // generate a row-data with null values
    let result = {};

    this.gridColumnApi.getAllGridColumns().forEach(item => {
        result[item.colId] = null;
    });
    return this.calculatePinnedBottomData(result);
}

calculatePinnedBottomData(target:any){
    //list of columns for aggregation
    let columnsWithAggregation = ['age']
    columnsWithAggregation.forEach(element => {
        this.gridApi.forEachNodeAfterFilter((rowNode: RowNode) => {
            if (rowNode.data[element])
                target[element] += Number(rowNode.data[element].toFixed(2));
        });
        if (target[element])
            target[element] = `Age Sum: ${target[element].toFixed(2)}`;
    })
    return target;
}

Démo


0 commentaires

1
votes

Ag Grid a des attributs appelés groupIncludeFooter, groupIncludeTotalFooter. Vous pouvez le consulter sur https: //www.ag-grid. com / javascript-grid-grouping / # grouping-footers

  <ag-grid-angular
      ...
      [groupIncludeFooter]="true"
      [groupIncludeTotalFooter]="true"
      ...
    ></ag-grid-angular>

https://plnkr.co/edit/pBG3to7sebxDC7Yq

J'espère que cela aidera :-)


1 commentaires

Comment appliquer l'aggFunc au chargement de la grille lorsqu'il n'y a pas de regroupement appliqué, la ligne apparaît vide.