web-dev-qa-db-ja.com

angularを使用してag-gridのフッターに合計値を表示する必要があります

現在、angular 7アプリケーションにag-gridを実装しています。達成した各グループのフッターを含める必要があります。今、EMV(USD)の合計を表示する必要があります。下のスクリーンショットのようなパーセント列。2つの列を除き、各セルの行は空白で、合計が表示されます。

enter image description here

成分

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;
    }
}

提案された回答に基づく新しいコード

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) + '%';
        }
    }

新しいスクリーンショット

enter image description here

3
Tom

私は別の方法でそれを作りました:

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;
}

Demo

2
un.spike

私はこれを以前に見つけたので、 整列したグリッドをフッターとして を使用できます。彼らは例を含んでいるので、あなたはそれを参照するべきです。

要約すると、component.htmlで、テンプレートにag-grid-angularコンポーネントを2回含める必要があります。それぞれに独自のgridOptionsプロパティがあります

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

そして、あなたのcomponent.tsで、あなたはいつものようにcolumnDefsとそれぞれのgridOptionsを定義します。

上記のリンクの例で述べたように、2つのグリッドを揃えると、メイングリッドに垂直に揃えられたフッターグリッドが作成されます。これにより、そのフッターに合計値などを表示できます。

1
wentjun

列定義ごとに、追加のパラメーターを渡して、列のレンダリング方法を変更できます

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

ここで、params.valueは列名です

0
Ghanima