들어가며

지난 강좌에서는 RealPivot의 설치에 대해 배워보았습니다. 이번 강좌에서는 dataProvider의 필드와 피벗 필드를 맵핑하고 피벗 필드의 설정에 대하여 자세히 알아보도록 하겠습니다.

강좌의 내용은 RealPivot의 설치하기를 기준으로 진행 됩니다.

이론

필드 맵핑은 피벗 화면을 구성하는데 필수적인 첫번째 단계 입니다.
가장 기본적인 기능으로는 피벗필드와 RealGridJS dataProvider의 필드를 서로 맵핑하여 리얼그리드에 로드된 데이터를 피벗으로 표시해주는 기능을 합니다. 그 외에 화면에 표시되는 다양한 형태의 포맷을 지정할 수 있습니다. 그러나 필드만 맵핑해서 피벗을 표시할 수는 없습니다. 피벗의 컬럼과 행, 그리고 값에 표시할 필드들을 지정해주는 단계(setPivotFields()를 진행해야 피벗이 표시됩니다.
이 강좌에서는 날짜와 관련된 다양한 형태의 피벗필드를 실습을 통해 확인해보도록 하겠습니다.

다양한 날짜 형태의 지원

RealPivot은 여러 날짜를 다양한 형태로 묶어 표현할 수 있습니다.
기본적인 년, 월, 일을 비롯하여 반기, 분기, 주차, 시간대까지도 지원 합니다.

자세한 내용은 DateValueType 확인하세요.

실습

RealGridJS에 하나의 날짜 필드가 있고 RealPivot에 년도에 대한 분류, 그 안에 분기에 대한 분류로 보여주고 싶다면 피벗 필드는 두 개를 생성해야 합니다. 하나의 피벗 필드로 표현할 수는 없습니다. 먼저 년도만으로 분류된 피벗을 생성해보고 그 후 반기만, 그리고 또 년도와 반기로 이루어진 피벗을 생성해 어떻게 설정해야하는지 확인해보도록 하겠습니다.

  1. 고객사별 판매액을 년 기준으로 분류하여 표시하기 위해 3개의 필드를 설정 합니다.

     pivot.setFieldMapping([{
         name: "CustomerID",
         sourceField: "CustomerID",
         fieldHeader: "고객사",
         valueEnable: false
     }, {
         name: "OrderYear",
         sourceField: "OrderDate",
         dateType: "year",            //년도 기준으로 보여주기 위해 "year"로 설정
         fieldHeader: "영업년도",
         valueEnable: false
     }, {
         name: "UnitPrice",
         sourceField: "UnitPrice",
         fieldHeader: "판매액",
         numberFormat: "#,##0",       //천단위 , 를 표시하기 위해 "#,##0"로 설정 
         labelEnable: false
     }]);
  2. 고객사별 판매액을 년 기준으로 분류하여 피벗으로 표시합니다.

     pivot.setPivotFields({
         columns: [{
             name: "OrderYear",
             direction: "ascending"
         }],
         rows: [{
             name: "CustomerID",
             direction: "ascending"
         }],
         values: [{
             name: "UnitPrice",
             expression: "sum"
         }]
     });
    
     pivot.drawView();
  3. 고객사별 판매액을 반기 기준으로 분류하여 표시하기 위해 3개의 필드를 설정 합니다.

     pivot.setFieldMapping([{
         name: "CustomerID",
         sourceField: "CustomerID",
         fieldHeader: "고객사",
         valueEnable: false
     }, {
         name: "OrderHalf",
         sourceField: "OrderDate",
         dateType: "half",            //반기 기준으로 보여주기 위해 "half"로 설정
         fieldHeader: "영업반기",
         valueEnable: false
     }, {
         name: "UnitPrice",
         sourceField: "UnitPrice",
         fieldHeader: "판매액",
         numberFormat: "#,##0",       //천단위 , 를 표시하기 위해 "#,##0"로 설정 
         labelEnable: false
     }]);
    
     pivot.setPivotFields({
         columns: [{
             name: "OrderHalf",
             direction: "ascending"    
         }],
         rows: [{
             name: "CustomerID",
             direction: "ascending"
         }],
         values: [{
             name: "UnitPrice",
             expression: "sum"
         }]
     });
    
     pivot.drawView();
  4. 상반기/하반기로 분류되었지만 피벗에는 1, 2로 표시됩니다. 이 문제를 해결하기 위해 displayLabels속성을 설정합니다.

     pivot.setFieldMapping([{
         name: "CustomerID",
         sourceField: "CustomerID",
         fieldHeader: "고객사",
         valueEnable: false
     }, {
         name: "OrderHalf",
         sourceField: "OrderDate",
         dateType: "half",            
         fieldHeader: "영업반기",
         valueEnable: false,
         displayLabels: {
             1: "상반기",
             2: "하반기"
         }
     }, {
         name: "UnitPrice",
         sourceField: "UnitPrice",
         fieldHeader: "판매액",
         numberFormat: "#,##0",        
         labelEnable: false
     }]);
    
     pivot.setPivotFields({
         columns: [{
             name: "OrderHalf",
             direction: "ascending"       
         }],
         rows: [{
             name: "CustomerID",
             direction: "ascending"
         }],
         values: [{
             name: "UnitPrice",
             expression: "sum"
         }]
     });
    
     pivot.drawView();
  5. 이번엔 년도/분기별로 표시해보도록 하겠습니다. 소스필드가 OrderDate인 OrderQuarter필드를 추가하고 화면에 분기 표시를 위해 displayLabels를 설정합니다. 그리고 setPivotFields()의 columns 안에 OrderYear, OrderQuarter 두개의 필드를 설정합니다.

     pivot.setFieldMapping([{
         name: "CustomerID",
         sourceField: "CustomerID",
         fieldHeader: "고객사",
         valueEnable: false
     }, {
         name: "OrderYear",
         sourceField: "OrderDate",
         dateType: "year",            
         fieldHeader: "영업년도",
         valueEnable: false        
     }, {    
         name: "OrderQuarter",
         sourceField: "OrderDate",
         dateType: "quarter",            // 분기 기준으로 보여주기 위해 "quarter"로 설정
         fieldHeader: "영업반기",
         valueEnable: false,
         displayLabels: {
             1: "1사분기",
             2: "2사분기",
             3: "3사분기",
             4: "4사분기"
         }
     }, {
         name: "UnitPrice",
         sourceField: "UnitPrice",
         fieldHeader: "판매액",
         numberFormat: "#,##0",        
         labelEnable: false
     }]);
    
     pivot.setPivotFields({
         columns: [{                   
             name: "OrderYear",          // 년도
             direction: "ascending"
         }, {
             name: "OrderQuarter",       // 분기
             direction: "ascending"        
         }],
         rows: [{
             name: "CustomerID",
             direction: "ascending"
         }],
         values: [{
             name: "UnitPrice",
             expression: "sum"
         }]
     });
    
     pivot.drawView();
  6. 결과가 잘 표시됩니다. 그러나 피벗은 데이터 기준으로 표시되기 때문에 특정 분기에 값이 없다면 피벗에 해당 분기는 표시되지 않습니다. (월이나 요일등 다른 조건에서도 같습니다.) 이런 경우 값이 없어도 피벗에 표시해주기 위해서 mustValues 속성을 지원하고 있습니다. 해당 속성에 값이 지정되면 값이 없어도 피벗에는 표시됩니다.

     pivot.setFieldMapping([{
         name: "CustomerID",
         sourceField: "CustomerID",
         fieldHeader: "고객사",
         valueEnable: false
     }, {
         name: "OrderYear",
         sourceField: "OrderDate",
         dateType: "year",            
         fieldHeader: "영업년도",
         valueEnable: false        
     }, {    
         name: "OrderQuarter",
         sourceField: "OrderDate",
         dateType: "quarter",            // 분기 기준으로 보여주기 위해 "quarter"로 설정
         fieldHeader: "영업반기",
         valueEnable: false,
         displayLabels: {
             1: "1사분기",
             2: "2사분기",
             3: "3사분기",
             4: "4사분기"
         }, 
         mustValues: [1, 2, 3, 4]       // 값이 없어도 표시
     }, {
         name: "UnitPrice",
         sourceField: "UnitPrice",
         fieldHeader: "판매액",
         numberFormat: "#,##0",        
         labelEnable: false
     }]);
    
     pivot.setPivotFields({
         columns: [{                   
             name: "OrderYear",          // 년도
             direction: "ascending"
         }, {
             name: "OrderQuarter",       // 분기
             direction: "ascending"        
         }],
         rows: [{
             name: "CustomerID",
             direction: "ascending"
         }],
         values: [{
             name: "UnitPrice",
             expression: "sum"
         }]
     });
    
     pivot.drawView();
  7. 결과가 잘 표시됩니다. 그러나 컬럼sum영역(두번째줄 년도)에 값이 년도로 표시되어 컬럼group영역(첫번째줄 년도)의 값과 중복되어 보이므로 요약으로 표시해보도록 하겠습니다. 년도도 숫자만 보이는 것이 아니라 “1996 년도”로 표시하기 위해 displayFormat도 같이 설정하도록 하겠습니다.

     pivot.setFieldMapping([{
         name: "CustomerID",
         sourceField: "CustomerID",
         fieldHeader: "고객사",
         valueEnable: false
     }, {
         name: "OrderYear",
         sourceField: "OrderDate",
         dateType: "year",            
         fieldHeader: "영업년도",
         valueEnable: false,
         displayFormat: "${value}년도", 
         summaryFormat: "${value}년도요약"        
     }, {    
         name: "OrderQuarter",
         sourceField: "OrderDate",
         dateType: "quarter",            // 분기 기준으로 보여주기 위해 "quarter"로 설정
         fieldHeader: "영업반기",
         valueEnable: false,
         displayLabels: {
             1: "1사분기",
             2: "2사분기",
             3: "3사분기",
             4: "4사분기"
         }, 
         mustValues: [1, 2, 3, 4]       // 값이 없어도 표시
     }, {
         name: "UnitPrice",
         sourceField: "UnitPrice",
         fieldHeader: "판매액",
         numberFormat: "#,##0",        
         labelEnable: false
     }]);
    
     pivot.setPivotFields({
         columns: [{                   
             name: "OrderYear",          // 년도
             direction: "ascending"
         }, {
             name: "OrderQuarter",       // 분기
             direction: "ascending"        
         }],
         rows: [{
             name: "CustomerID",
             direction: "ascending"
         }],
         values: [{
             name: "UnitPrice",
             expression: "sum"
         }]
     });
    
     pivot.drawView();

실행화면

피벗 설정이 완료되지 않은 상태이기 때문에 버튼을 누르기 전까지는 빈 화면만 보입니다.

전체 소스코드

SCRIPT
<link rel="stylesheet" type="text/css" href="css/default_blue.css">
<script type="text/javascript" src="scripts/realgridjs-lic.js"></script>
<script type="text/javascript" src="scripts/realgridjs_eval.1.1.27.min.js"></script>
<script type="text/javascript" src="scripts/realgridjs-api.1.1.27.js"></script>
<script type="text/javascript" src="messages/realpivot-messages.js"></script>
<script type="text/javascript" src="scripts/realpivot_eval.0.9.0.min.js"></script>
<script type="text/javascript" src="scripts/jszip.min.js"></script>

<script>
var pivot;
var dataProvider;

$(document).ready( function(){
    RealGridJS.setRootContext("/script");
    
    dataProvider = new RealGridJS.LocalDataProvider();

    var fields = [{
            fieldName: "OrderID"
        }, {
            fieldName: "CustomerID"
        }, {
            fieldName: "EmployeeID"
        }, {
            fieldName: "OrderDate",
            dataType: "datetime",
            datetimeFormat: "yyyy-MM-dd a hh:mm:ss",
            amText: "오전",
            pmText: "오후"
        }, {
            fieldName: "CompanyName"
        }, {
            fieldName: "Country"
        }, {
            fieldName: "Phone"
        }, {
            fieldName: "ProductName"
        }, {
            fieldName: "QuantityPerUnit"
        }, {
            fieldName: "Quantity",
            dataType: "number"
        }, {
            fieldName: "UnitPrice",
            dataType: "number"
        }];     
    dataProvider.setFields(fields);

    var datas = [{
        "OrderID":"10248",
        "CustomerID":"VINET",
        "CustomerID2":"VINAC",
        "EmployeeID":"5",
        "OrderDate":"1996-01-04 오전 12:00:00",
        "RequiredDate":"1996-08-01 오전 12:00:00",
        "ShippedDate":"1996-07-16 오전 12:00:00",
        "ShipVia":"3",
        "Freight":"32.3800",
        "ShipName":"Vins et alcools Chevalier\r\nVins et alcools Chevalier\r\nVins et alcools Chevalier",
        "ShipAddress":"59 rue de l\u0027Abbaye",
        "ShipCity":"Reims",
        "ShipRegion":null,
        "ShipPostalCode":"51100",
        "ShipCountry":"France",
        "CompanyName":"Vins et alcools Chevalier\r\n",
        "Country":"France",
        "Shipping":"True",
        "SmallFlag":"http://dev.demo.realgrid.net/img/demo/smallflag/fr.png",
        "NormalFlag":"http://dev.demo.realgrid.net/img/demo/normalflag/fr.png",
        "Phone":"26.47.15.10",
        "ProductName":"Queso Cabrales",
        "QuantityPerUnit":"1 kg pkg.",
        "Quantity":"1200",
        "UnitPrice":"14.0000"
    }, {
    ....
    }];

    dataProvider.fillJsonData(datas);

    //년도로 보여주기    
    $("#btnYear").click(function () {
        pivot.setFieldMapping([{
            name: "CustomerID",
            sourceField: "CustomerID",
            fieldHeader: "고객사",
            valueEnable: false
        }, {
            name: "OrderYear",
            sourceField: "OrderDate",
            dateType: "year",            //년도 기준으로 보여주기 위해 "year"로 설정
            fieldHeader: "영업년도",
            valueEnable: false
        }, {
            name: "UnitPrice",
            sourceField: "UnitPrice",
            fieldHeader: "판매액",
            numberFormat: "#,##0",      // 천단위 , 를 표시하기 위해 "#,##0"로 설정 
            labelEnable: false
        }]);

        pivot.setPivotFields({
            columns: [{
                name: "OrderYear",
                direction: "ascending"
            }],
            rows: [{
                name: "CustomerID",
                direction: "ascending"
            }],
            values: [{
                name: "UnitPrice",
                expression: "sum"
            }]
        });

        pivot.drawView();
    });

    //반기로 보여주기    
    $("#btnHalf").click(function () {
        pivot.setFieldMapping([{
            name: "CustomerID",
            sourceField: "CustomerID",
            fieldHeader: "고객사",
            valueEnable: false
        }, {
            name: "OrderHalf",
            sourceField: "OrderDate",
            dateType: "half",            //반기 기준으로 보여주기 위해 "half"로 설정
            fieldHeader: "영업반기",
            valueEnable: false
        }, {
            name: "UnitPrice",
            sourceField: "UnitPrice",
            fieldHeader: "판매액",
            numberFormat: "#,##0",      // 천단위 , 를 표시하기 위해 "#,##0"로 설정 
            labelEnable: false
        }]);

        pivot.setPivotFields({
            columns: [{
                name: "OrderHalf",
                direction: "ascending"
            }],
            rows: [{
                name: "CustomerID",
                direction: "ascending"
            }],
            values: [{
                name: "UnitPrice",
                expression: "sum"
            }]
        });

        pivot.drawView();        
    });    

    //반기로 보여주기    
    $("#btnHalf1").click(function () {
        pivot.setFieldMapping([{
            name: "CustomerID",
            sourceField: "CustomerID",
            fieldHeader: "고객사",
            valueEnable: false
        }, {
            name: "OrderHalf",
            sourceField: "OrderDate",
            dateType: "half",            
            fieldHeader: "영업반기",
            valueEnable: false,
            displayLabels: {
                1: "상반기",
                2: "하반기"
            }
        }, {
            name: "UnitPrice",
            sourceField: "UnitPrice",
            fieldHeader: "판매액",
            numberFormat: "#,##0",        
            labelEnable: false
        }]);

        pivot.setPivotFields({
            columns: [{
                name: "OrderHalf",
                direction: "ascending"       
            }],
            rows: [{
                name: "CustomerID",
                direction: "ascending"
            }],
            values: [{
                name: "UnitPrice",
                expression: "sum"
            }]
        });

        pivot.drawView();
    });        

    //년도,분기로 보여주기    
    $("#btnQuarter").click(function () {
        pivot.setFieldMapping([{
            name: "CustomerID",
            sourceField: "CustomerID",
            fieldHeader: "고객사",
            valueEnable: false
        }, {
            name: "OrderYear",
            sourceField: "OrderDate",
            dateType: "year",            
            fieldHeader: "영업년도",
            valueEnable: false        
        }, {    
            name: "OrderQuarter",
            sourceField: "OrderDate",
            dateType: "quarter",            
            fieldHeader: "영업반기",
            valueEnable: false,
            displayLabels: {
                1: "1사분기",
                2: "2사분기",
                3: "3사분기",
                4: "4사분기"
            }
        }, {
            name: "UnitPrice",
            sourceField: "UnitPrice",
            fieldHeader: "판매액",
            numberFormat: "#,##0",        
            labelEnable: false
        }]);

        pivot.setPivotFields({
            columns: [{                   
                name: "OrderYear",          // 년도
                direction: "ascending"
            }, {
                name: "OrderQuarter",       // 분기
                direction: "ascending"        
            }],
            rows: [{
                name: "CustomerID",
                direction: "ascending"
            }],
            values: [{
                name: "UnitPrice",
                expression: "sum"
            }]
        });

        pivot.drawView();         
    });    

    //년도,분기로 보여주기    
    $("#btnQuarter1").click(function () {
        pivot.setFieldMapping([{
            name: "CustomerID",
            sourceField: "CustomerID",
            fieldHeader: "고객사",
            valueEnable: false
        }, {
            name: "OrderYear",
            sourceField: "OrderDate",
            dateType: "year",            
            fieldHeader: "영업년도",
            valueEnable: false        
        }, {    
            name: "OrderQuarter",
            sourceField: "OrderDate",
            dateType: "quarter",            
            fieldHeader: "영업반기",
            valueEnable: false,
            displayLabels: {
                1: "1사분기",
                2: "2사분기",
                3: "3사분기",
                4: "4사분기"
            },
            mustValues: [1, 2, 3, 4]
        }, { 
            name: "UnitPrice",
            sourceField: "UnitPrice",
            fieldHeader: "판매액",
            numberFormat: "#,##0",        
            labelEnable: false
        }]);

        pivot.setPivotFields({
            columns: [{                   
                name: "OrderYear",          // 년도
                direction: "ascending"
            }, {
                name: "OrderQuarter",       // 분기
                direction: "ascending"        
            }],
            rows: [{
                name: "CustomerID",
                direction: "ascending"
            }],
            values: [{
                name: "UnitPrice",
                expression: "sum"
            }]
        });

        pivot.drawView();         
    });    

    //년도,분기로 보여주기    
    $("#btnQuarter2").click(function () {
        pivot.setFieldMapping([{
            name: "CustomerID",
            sourceField: "CustomerID",
            fieldHeader: "고객사",
            valueEnable: false
        }, {
            name: "OrderYear",
            sourceField: "OrderDate",
            dateType: "year",            
            fieldHeader: "영업년도",
            valueEnable: false, 
            displayFormat: "${value}년도",
            summaryFormat: "${value}년요약"        
        }, {    
            name: "OrderQuarter",
            sourceField: "OrderDate",
            dateType: "quarter",            
            fieldHeader: "영업반기",
            valueEnable: false,
            displayLabels: {
                1: "1사분기",
                2: "2사분기",
                3: "3사분기",
                4: "4사분기"
            },
            mustValues: [1, 2, 3, 4]
        }, { 
            name: "UnitPrice",
            sourceField: "UnitPrice",
            fieldHeader: "판매액",
            numberFormat: "#,##0",        
            labelEnable: false
        }]);

        pivot.setPivotFields({
            columns: [{                   
                name: "OrderYear",          // 년도
                direction: "ascending"
            }, {
                name: "OrderQuarter",       // 분기
                direction: "ascending"        
            }],
            rows: [{
                name: "CustomerID",
                direction: "ascending"
            }],
            values: [{
                name: "UnitPrice",
                expression: "sum"
            }]
        });

        pivot.drawView();         
    });        
    
});     
</script>
HTML
<div id="realpivotDiv" style="width: 100%; height: 500px;"></div>
<p></p>
1. <button type="button" class="btn btn-primary btn-xs" id="btnYear">고객사별 년도로 분류</button> 
2. <button type="button" class="btn btn-primary btn-xs" id="btnHalf">고객사별 반기로 분류(숫자로 표시됨)</button> 
3. <button type="button" class="btn btn-primary btn-xs" id="btnHalf1">고객사별 반기로 분류(상반기,하반기 문자로 표시됨)</button> 
4. <button type="button" class="btn btn-primary btn-xs" id="btnQuarter">고객사별 년/분기로 분류</button> 
5. <button type="button" class="btn btn-primary btn-xs" id="btnQuarter1">고객사별 년/분기로 분류(모든분기표시)</button> 
6. <button type="button" class="btn btn-primary btn-xs" id="btnQuarter2">고객사별 년/분기로 분류(모든분기표시, 요약)</button>