계산된 필드(calculated Fields) 행 추가하기 > 블로그 & Tips

본문 바로가기

계산된 필드(calculated Fields) 행 추가하기

페이지 정보

작성자 GCK루시 작성일 21-02-25 11:50 조회 4,178회 댓글 0건

본문

Wijmo 2020 V3 버전의 새로운 기능 중 하나인 계산된 필드(calculated Fields)는 CollectionView를 이용하여 각 행에 대한 정보를 계산한 새로운 열을 만들 수 있게 해줍니다.

이를 통해, 총합과 같은 자료에 대한 서머리(요약) 행/열을 만들어 더욱 유의미한 데이버 분석을 할 수 있습니다.

해당 포스팅에서는 PureJS와 Wijmo 2020V3를 사용하여, 아래와 같이 기본 계산된 필드에 대한 설명에서 더 나아가 숨김 유무에 따른 ,

열과 행의 총계를 구할 수 있는 데모 또한 설명 드리도록 하겠습니다.

실제로 구현된 화면은 아래와 같으며, 탭을 통해 소스코드를 확인하고 바로 수정해 볼 수 있습니다.

샘플 링크 : https://codepen.io/GrapeCity-Korea/pen/vYyKYxz

참고 : IE11에서 계산된 필드를 사용하려면 https://www.npmjs.com/package/proxy-polyfill과 같은 프록시 폴리필을 포함해야합니다.

기본 데모 튜토리얼 시작하기

  1. 먼저 Wijmo 컨트롤을 사용하기 위해 HTML 파일에 레퍼런스를 추가합니다.

<!-- Wijmo 레퍼런스 (필수) -->
<link
 href="https://cdn.grapecity.com/wijmo/5.20203.766/styles/wijmo.min.css"
 rel="stylesheet"
/>
<script src="https://cdn.grapecity.com/wijmo/5.20203.766/controls/wijmo.min.js"></script>
​
<script src="https://cdn.grapecity.com/wijmo/5.20203.766/controls/wijmo.grid.min.js"></script>

  1. Wijmo 컨트롤을 생성할 'theGrid'라는 id를 가진 div 요소를 생성합니다.

<div id="theGrid"></div>
 
  1. 배열에 각 정보가 담긴 객체를 넣어 CollectionView에 사용할 데이터를 생성합니다.

function getData() {
       return [
          { product: 'Banana', brand: 'Chiquita', unitPrice: 45.95, qty: 12, discount: .08 },
          { product: 'Apple', brand: 'Granny', unitPrice: 65.95, qty: 23, discount: .02 },
          { product: 'Orange', brand: 'Sunkist', unitPrice: 52.95, qty: 16, discount: .04 },
          { product: 'Grape', brand: 'Pinot', unitPrice: 83.95, qty: 8, discount: .0 },
          { product: 'Watermelon', brand: '', unitPrice: 13.95, qty: 14, discount: .05 },
          { product: 'Mango', brand: 'Ganesh', unitPrice: 38.95, qty: 19, discount: .15 },
          { product: 'Applemango', brand: 'Fruits', unitPrice: 90, qty: 2, discount: .05 },
          { product: 'Grape', brand: 'Real', unitPrice: 23, qty: 5, discount: .01 },
          { product: 'Melon', brand: 'Fine One', unitPrice: 100, qty: 8, discount: .03 },
          { product: 'Strawberry', brand: 'Sqize', unitPrice: 85, qty: 14, discount: .02 },
          { product: 'Mango', brand: 'Gane', unitPrice: 38.95, qty: 19, discount: .15 },
];
 
  1. 그 다음, 위에서 만든 getData에서 생성한 데이터 들 중에서, unitPrice와 qty 그리고 discount를 이용하여, 계산된 필드를 만들어 보겠습니다.

    Wijmo의 CollectionView의 속성 중 CalculatedFields를 설정하여 구현할 것이며, CalculatedFields 속성은 사용자가 원하는 방식으로 다양하게 커스터마이징이 가능합니다.

    CalculatedFields 속성을 만드는 데 있어 "함수 기반 표현식""문자열 기반 표현식", 총 2가지 방식을 사용할 수 있습니다.

    먼저, 함수 기반 표현식은 문자열 기반 표현식과 비교하여 아래와 같은 장점이 있습니다.

    1) 디자인 타임 오류 검사와 command completion을 제공

    2) 더 빠른 속도

    3) CSP(cotent-security policy)에 대한 이슈가 없음

    문자열 기반 표현식은 아래와 같은 장점이 있습니다.

    1) 좀 더 높은 간결성

    2)데이터로 저장하고 런타임에 쉽게 변경 가능

    먼저, collectionView 생성시 첫 번째 인자에는 데이터를 위한 getData()를 넣어주고, 그 다음 아래 코스와 같이 calculatedFields 속성을 정의해줍니다.

 function getCalculatedView() {
     return new wijmo.collections.CollectionView(getData(), {
         calculatedFields: {
             // 함수 기반 표현식
             fullName: ($) => [$.brand, $.product].join(' '),
             allCaps: ($) => $.fullName.toUpperCase(),
             totalPrice: ($) => ($.unitPrice * $.qty) * (1 - $.discount),
             tax: ($) => $.totalPrice * 0.12,
             // 문자열 기반 표현식
             fullNameStr: '[$.brand, $.product].join(" ")',
             allCapsStr: '$.fullNameStr.toUpperCase()',
             totalPriceStr: '($.unitPrice * $.qty) * (1 - $.discount)',
             taxStr: '$.totalPriceStr * 0.12',
        }
    });
} 
 

위의 코드를 보면, 함수 기반과 문자열 기반 표현식의 모두에서 볼 수 있는 '$' 인자는 getData()에 있는 데이터 객체를 가르킵니다.

아래에서 각 표현식에 대해 더 자세히 살펴보도록 하겠습니다.

[ join 을 사용한 데이터 합치기 ]

아래 코드는 현재 데이터의 brand 열과 product 열의 값에 join을 사용하여 fullName(fullNameStr)이라는 새로운 열 필드를 만들고 있습니다.

// 함수 기반 표현식
fullName: ($) => [$.brand, $.product].join(' ')
// 문자열 기반 표현식
fullNameStr: '[$.brand, $.product].join(" ")'


[ toUpperCase을 사용한 대문자 변환 ]

해당 코드는 현재 데이터에서 fullName을 toUpperCase() 함수를 통해 대문자로 만들어 주고 있습니다.

// 함수 기반 표현식
allCaps: ($) => $.fullName.toUpperCase()
// 문자열 기반 표현식
allCapsStr: '$.fullNameStr.toUpperCase()'


[ 계산식을 이용한 총합계 계산 ]

데이터의 unitPrice 와 qty 의 곱과 (1-discount)의 값을 곱하여 totalPrice(totalPriceStr) 열을 만듭니다.

// 함수 기반 표현식
totalPrice: ($) => ($.unitPrice * $.qty) * (1 - $.discount)
// 문자열 기반 표현식
totalPriceStr: '($.unitPrice * $.qty) * (1 - $.discount)'


위에서 만든 totalPrice(totalPriceStr)에 0.12를 곱하여 tax(taxStr) 열을 만들어 주고 있습니다.

// 함수 기반 표현식
tax: ($) => $.totalPrice * 0.12,
// 문자열 기반 표현식
taxStr: '$.totalPriceStr * 0.12'


  1. 계산된 필드를 FlexGrid에 바인딩 합니다.

    위의 함수 getCalculatedView() 통해 만들어진 계산된 필드를 포함한 새로운 데이터소스를 itemsSource를 할당하면, 계산된 필드가 있는 FlexGrid를 쉽고 빠르게 생성할 수 있습니다.

new wijmo.grid.FlexGrid('#theGrid', {
       alternatingRowStep: 0,
       showMarquee: true,
       selectionMode: 'MultiRange',
       autoGenerateColumns: false,
       headersVisibility: "Column",
       columns: [
           // 데이터 필드
          { binding: 'product', header: '제품' },
          { binding: 'brand', header: '브랜드' },
          { binding: 'unitPrice', header: '단가', format: 'c' },
          { binding: 'qty', header: '수량', format: 'n0' },
          { binding: 'discount', header: '할인', format: 'p0' },
           // 계산된 필드(calculated fields)
          { binding: 'fullName', header: '이름', cssClass: 'calculated' },
          { binding: 'allCaps', header: '대문자', cssClass: 'calculated' },
          { binding: 'totalPrice', header: '총가격', format: 'c', cssClass: 'calculated' },
          { binding: 'tax', header: '세액', format: 'c', cssClass: 'calculated' }
      ],
       itemsSource: getCalculatedView()
  });
}
 

계산된 필드와 드랍다운 튜토리얼

이번 섹션에서는 기본 튜토리얼에서 한 단계 더 나아가 드랍다운과 계산된 필드를 함께 사용하여 값의 숨김 처리를 하는 그리드 튜토리얼에 대해 설명 드리도록 하겠습니다.

아래 샘플은 FlexGrid에서 사용자가 isVisible 컬럼의 값을 Visible(보이기) 또는 inVisible(숨기기)로 선택하면, 선택 옵션에 따라 값을 보여주고 보여지는 값에 따른 자동 계산 필드 만들어 보도록 하겠습니다.

실제로 구현된 화면은 아래와 같으며, 탭을 통해 소스코드를 확인하고 바로 수정해 볼 수 있습니다.

샘플 링크 : https://codepen.io/GrapeCity-Korea/pen/ZEpgEBG?editors=1010


  1. 이번 튜토리얼에서는 추가적으로 드랍다운을 이용하기 때문에, 입력 컨트롤을 위한 라이브러리인 "wijmo.input.min.js" 도 아래와 같이 추가해주세요.

<script src="https://cdn.grapecity.com/wijmo/5.20203.766/controls/wijmo.input.min.js"></script>

  1. Wijmo 컨트롤을 생성할 'theGrid'라는 id를 가진 div 요소를 생성합니다.

<div id="theGrid"></div>

  1. 먼저 getData를 통해 샘플 데이터를 생성해준 뒤, CollectionView에 데이터를 할당합니다. 이후에 계산된 필드를 사용자 정의를 하기 위한 "reCalculated" 함수를 호출합니다.

//랜덤 데이터 생성
function getData() {
 var data = [],
   actions = getActions(); //드랍다운의 "보이기/숨기기" 목록을 위한 배열 생성
 for (var i = 0; i < 10; i++) {
   data.push({
     name: "name" + i,
     isVisible: actions[i % actions.length],
     english: Math.floor(Math.random() * 10),
     maths: Math.floor(Math.random() * 10),
  });
}
   
//collectionView에 데이터 추가
var view = new wijmo.collections.CollectionView(data);
​
// 계산된 필드를 설정하는 함수 호출
reCalculated(view)
​
return view;
}  
​

  1. 여기서 getActions는 "보이기/숨기기"라는 선택을 위한 드랍다운에 보여질 목록 배열을 반환하는 함수입니다. 문자열을 split 함수를 이용하여 반환된 배열을 FlexGrid의 열에 바인딩 하면, 자동으로 dataMap과 바운드되어 드랍다운을 생성하게 됩니다.

// 드랍다운
function getActions(){
 return "visible,inVisible".split(",");
}

  1. reCalculated 함수에서는 전달된 collectionView 객체의 계산된 필드(calculatedFields) 속성을 설정하여, 원하는 필드를 추가하여 줍니다.

    dataItem 변수를 통해, CollectionView에 들어 있는 항목들의 데이터에 접근이 가능합니다.

    해당 함수에서는 dataItem.isVisible의 값이 visible일때, Math 값과 English 값을 보여주고, 이둘을 합진 합친 total(총계값)을 계산하여 보여주는 계산된 필드를 생성하고 collectionVeiw에 할당합니다.

function reCalculated(view) {
 view.calculatedFields = {
   total: function (dataItem) {
     if (dataItem.isVisible=== "visible"){
       return dataItem.maths +  dataItem.english;
    }
  },
   mathVal: function(dataItem){
     if (dataItem.isVisible=== "visible"){
       return dataItem.maths;
    }
  },
   englishVal: function(dataItem){
     if (dataItem.isVisible=== "visible"){
       return dataItem.english;
    }
  },
}
}

  1. itemsSource()에 getData()를 통해 생성된 CollectionView 객채를 바인딩여 데이터를 추가합니다. 더불어 각 열의 자동 총계 계산 행을 위해서 columns의 aggregate 속성을 "Sum"으로 지정해줍니다. 또한, 셀 편집이 끝날 때 발생하는 cellEditEnded 이벤트를 통해 숨김 처리 유무가 바뀌거나 셀의 값이 변경될 때 reCalculated 함수를 호출해 그리드 뷰의 값을 업데이트 해줍니다.

var grid = new wijmo.grid.FlexGrid("#theGrid", {
 columns: [
  { binding: "name", header: "Name" },
  { binding: "isVisible", header: "isVisible", dataMap: getActions() },
  { binding: "englishVal", header: "English", aggregate: "Sum" },
  { binding: "mathVal", header: "Maths", aggregate: "Sum" },
   //계산된 필드를 위한 합계 컬럼
  {
     isReadOnly: true,
     header: "Total",
     binding: "total",
     aggregate: "Sum",
  },
],
 autoGenerateColumns: false,
 itemsSource: getData(),
   //셀의 편집이 끝날 때 이벤트 발생
 cellEditEnded:function(grid,e){
reCalculated(grid.collectionView)
}
});
​

  1. 마지막으로 English, Maths 과 Total 값을 열 기준으로 계산된 합계 값을 보여주기위한 Footer 행을 추가하기 위해 columnFooters에 새 GroupRow()을 넣어줍니다. setCellData를 통해 그리드의 총합을 나타나는 기호를 지정하여 가시성을 높여 줍니다.

initGrid(grid);
​
function initGrid(grid) {
 // 총계 행 추가 (aggregate 속성을 통해 자동 계산)
 grid.columnFooters.rows.push(new wijmo.grid.GroupRow());
 grid.bottomLeftCells.setCellData(0, 0, "Σ");
}

위의 과정을 통해 숨김 처리 유무에 따른 행과 열에 대한 총합을 계산하고 보여주는 튜토리얼을 끝 맞췄습니다!

개발 편의성을 위해 새롭게 추가된 "계산된 필드"를 통해서, 매출분석, 원가계산, 재고계산, 회계분석, 계측값분석 등 다양한 데이터 분석을 위한 솔루션 개발에 응용해 보시기를 기대합니다.

  • 페이스북으로 공유
  • 트위터로  공유
  • 구글플러스로 공유
  • 카카오톡으로 보내기

댓글목록

등록된 댓글이 없습니다.

그레이프시티 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기

태그

인기글

더보기
  • 인기 게시물이 없습니다.
그레이프시티 홈페이지를 통해 제품에 대해서 더 자세히 알아 보세요!
홈페이지 바로가기
이메일 : sales-kor@grapecity.com | 전화 : 1670-0583 | 경기도 안양시 동안구 시민대로 230, B-703(관양동, 아크로타워) 그레이프시티(주) 대표자 : 허경명 | 사업자등록번호 : 123-84-00981 | 통신판매업신고번호 : 2013-경기안양-00331 Copyright ⓒ 2022 GrapeCity inc.