티스토리 뷰

dev/vue

vue ag Grid 합계 지정 하기

동큐 2020. 7. 28. 10:50

안녕하세요. 

 

이전에 agGrid에 대한 기초와 컬럼 서식 정의에 대해 설명드렸는데

https://dong-queue.tistory.com/58

 

Vue ag-Grid : 컬럼 서식 정의

이전에 Vue에서 ag-Grid를 설치 사용하는 법에 대해 간략하게 적어보았습니다. https://dong-queue.tistory.com/57 Vue에서 ag-Grid 사용하기 안녕하세요. 이번에는 강력한 무료 data grid 도구인 AG grid를 Vue에..

dong-queue.tistory.com

이번에는 ag grid에서 합계를 지정하는 방법에 대해 적어보겠습니다.

 

우선 예제는 이전과 동일합니다.

<template>
  <input type="text" @keyup="onQuickFilterChanged"/>
  <ag-grid-vue 
    style="width: 100%; height: 70vh; min-height: 300px" // 그리드 가로 , 세로 사이즈 설정
    class="ag-theme-balham" // 그리드 테마 설정
    :gridOptions="gridOptions" // 그리드 옵션
    :columnDefs="columnDefs" // 헤더 및 컬럼 속성 정의
    :rowData="rowData" // 데이터 값
  />
</template>

<script>
  import {AgGridVue} from 'ag-grid-vue'
  export default {
    components: {
      AgGridVue
    },
    data () {
      return {
      gridOptions: null,
      rowData: []
    },
    computed: {
      // 그리드 header명과, 매핑되는 data attribute, column type과 width, column id 등을 지정 가능합니다.
      // computed에 선언하지 않고 data에서도 선언 가능합니다.
      columnDefs () {
        return [
          {headerName: 'Make', field: 'make'},
          {headerName: 'Model', field: 'model'},
          {headerName: 'Grade', field: 'grade'},
          {headerName: 'Price', field: 'price'},
          {headerName: 'Stock', field: 'qty'}
        ]
      }
    },
    beforeMount () {
      // 그리드에 적용가능한 여러가지 옵션 사항을 설정합니다.
      this.GridOptions = {
         enableColResize: true,
         enableSorting: true,
         enableFilter: true,
         animateRows: false
      }
    },
    created () {
      makeData ()
    },
    methods: {
      makeData () {
        this.rowData = [
          {make: '현대', model: '아반떼', grade: '준중형', price: 2000, qty: 1},
          {make: '현대', model: '산타페', grade: '중형', price: 3500, qty: 1},
          {make: '현대', model: '소나타', grade: '중형', price: 3000, qty: 2},
          {make: '현대', model: '그랜저', grade: '준대형', price: 4000, qty: 3},
          {make: '기아', model: 'K3', grade: '준중형',price: 2000, qty: 2},
          {make: '기아', model: 'K5', grade: '중형', price: 3000, qty: 3},
          {make: '기아', model: 'K7', grade: '준대형', price: 4000, qty: 2}
        ]
      },
      onQuickFilterChanged (event) {
        this.gridOptions.api.setQuickFilter(event.target.value)
      }
    }
  }
</script>

그리드 형태는 아래와 같습니다.

Make Model Grade Price Stock
현대 아반떼 준중형 2000 1
현대 산타페 중형 3500 1
현대 소나타 중형 3000 2
현대 그랜저 준대형 4000 3
기아 K3 준중형 2000 2
기아 K5 중형 3000 3
기아 K7 준대형 4000 2

이제 합계행을 추가해 보겠습니다.

<script>
export default {
........
  beforeMount () {
  // 그리드에 적용가능한 여러가지 옵션 사항을 설정합니다.
    this.GridOptions = {
      defaultColDef: {
        sortable: true,
        filter: true,
        resizable: true
      },
      animateRows: false,
      pinnedBottomRowData: [
        {make: '합계', model: null, grade: null, price: null, qty: 0}
      ]
    }  
  },
}
</script>

위와 같이 gridOptions에 piinedBottomRowData 를 추가할 경우 예상 결과는 아래와 같습니다.

Make Model Grade Price Stock
현대 아반떼 준중형 2000 1
현대 산타페 중형 3500 1
현대 소나타 중형 3000 2
현대 그랜저 준대형 4000 3
기아 K3 준중형 2000 2
기아 K5 중형 3000 3
기아 K7 준대형 4000 2
합계       0

그리드의 데이터가 고정되어 있다면 선언할때 값을 넣어주면 되겠지만,

대부분의 경우는 데이터를 DB나 외부에서 가져오게 되므로 데이터를 가져왔을때 합계를 다시 계산해 주어야 합니다.

<script>
export default {
......
  methods: {
    makeData () {
      this.rowData = [
        {make: '현대', model: '아반떼', grade: '준중형', price: 2000, qty: 1},
        {make: '현대', model: '산타페', grade: '중형', price: 3500, qty: 1},
        {make: '현대', model: '소나타', grade: '중형', price: 3000, qty: 2},
        {make: '현대', model: '그랜저', grade: '준대형', price: 4000, qty: 3},
        {make: '기아', model: 'K3', grade: '준중형',price: 2000, qty: 2},
        {make: '기아', model: 'K5', grade: '중형', price: 3000, qty: 3},
        {make: '기아', model: 'K7', grade: '준대형', price: 4000, qty: 2}
      ]
      let sum = [{
        make: '합계',
        model: null,
        grade: null,
        price: null
        qty: this.rowData.reduce((prev, next) => {prev + next.qty})
      }]
      this.gridOptions.api.setPinnedBottomRowData(sum)
    },
......
}
</script>

위와 같이 데이터를 가져온 후 sum을 계산하고 계산된 sum을 agGrid api인 setPinnedBottomRowData를 실행하여 넣어줍니다.

Make Model Grade Price Stock
현대 아반떼 준중형 2000 1
현대 산타페 중형 3500 1
현대 소나타 중형 3000 2
현대 그랜저 준대형 4000 3
기아 K3 준중형 2000 2
기아 K5 중형 3000 3
기아 K7 준대형 4000 2
합계       14

일단 기본적인 합계 계산은 끝났습니다.

 

근데 다시 처음 예제를 'onQuickFilterChanged' event 가 마음에 걸리네요. filter가 변경되었을 때 합계도 같이 변경해 주고 싶다면 어떻게 해야 할까요?

<script>
export default {
  methods: {
    onQuickFilterChanged (event) {
      this.gridOptions.api.setQuickFilter(event.target.value)
      let sum = {
        make: '합계',
        qty: 0
      }
      this.gridOptions.api.forEachNodeAfterFilter((node) => {
        sum.qty += node.data.qty
      })
      this.gridOptions.api.setPinnedBottomRowData(sum)
    }
  }
}
<script>

위의 'forEachNodeAfterFilter' 는 Array의 forEach와 비슷하지만 grid의 filter가 적용된 데이터만을 대상으로 한다는 차이가 있습니다. callback data는 node라 불리는데 node는 grid에서 보이는 한 행이라고 생각하시면 되고, node에는 컬럼 정의와 data, index 등 여러 정보들이 포함되어 있습니다. 

여기서는 qty 값이 필요하므로 node.data.qty 로 접근하여 값을 뽑아내었습니다.

 

이제 적용후 필터값을 입력해 보면 합계도 같이 변하는 것을 확인 할 수 있습니다.

 

감사합니다. 

댓글