프로그래밍/wijmo

웹 브라우저에 OLAP 구현하기 - Wijmo

benscript 2025. 9. 21. 15:54

대시보드에서 “월별/국가별로 묶어서 보고 싶다”, “합계·평균·건수 같은 요약을 빨리 보고 싶다”는 요구가 있었습니다. 엑셀 피벗 테이블은 익숙하지만, 웹에서 처음부터 구현하려면 그룹핑/집계/필드 UI/차트 연동까지 일거리가 크더라구요 😭😭

그래서 Wijmo OLAPPure JS로 테스트해봤습니다.


Wijmo 파일 설치/로딩 

아래 방법 중 하나로 시작하면 됩니다

  1. CDN
  2. 로컬 파일
  3. npm 설치 

체험용으론 CDN이 간편했음.

 

(A) 로컬 파일 예시

<!-- 스타일 파일 -->
<link rel="stylesheet" href="wijmo.min.css" />
<!-- 스크립트 파일 -->
<script src="wijmo.min.js"></script>
<script src="wijmo.input.min.js"></script>
<script src="wijmo.grid.min.js"></script>
<script src="wijmo.grid.filter.min.js"></script>
<script src="wijmo.chart.min.js"></script>
<script src="wijmo.olap.min.js"></script>
<!-- 문화권 파일 -->
<script src="wijmo.culture.ko.min.js"></script>

 

(B) npm 예시(Vue  기준)

npm install @mescius/wijmo.vue2.all

 

 

OLAP 모듈 가져오기

import * as wjOlap from '@mescius/wijmo.olap';


자바스크립트 OLAP 예제 

아래는 프레임워크 없이 HTML 한 장에 붙여보는 기본 형태로 PivotPanel에서 필드 드래그하면 PivotGrid, PivotChart가 업데이트되는 샘플입니다.

<!DOCTYPE html>
<html lang="en" >
<head>
  <meta charset="UTF-8">
  <title>Wijmo | OLAP | 간단한 샘플</title>
  <link rel='stylesheet' href='/styles/wijmo.min.css'>
  <link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css'><link rel="stylesheet" href="./style.css">
  <style>
  .wj-pivotgrid {
    max-height: 400px;
    box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
  }

  body {
   margin-bottom: 24pt;
  }
  </style>
</head>
<body>
<div class="container-fluid">
        <div class="row">
            <div class="col-sm-5">
                <p>
                  필드를 드래그 앤 드롭하여 보기를 만들기:
                </p>
                <div id="pivotPanel"></div>
                <p>
                    예를 들어, "구매자" 필드를 "행" 목록에서 "열" 목록으로 드래그합니다.
                </p>

              <p>
               보기 정의는 다음을 사용하여 저장 및 복원할 수 있습니다
                PivotEngine의 <b>viewDefinition</b> 속성:
              </p>
            <button id="saveView" class="btn btn-default">
              뷰 저장
            </button>
            <button id="restoreView" class="btn btn-default">
              뷰 복원
            </button>
            </div>
            <div class="col-sm-7">
                <p>
                    현재 뷰 정의 요약:
                </p>
                <div id="pivotPanelGrid"></div>
                <div id="pivotPanelChart"></div>
            </div>
        </div>
 
</div>

<script src='/controls/wijmo.min.js'></script>
<script src='/controls/wijmo.input.min.js'></script>
<script src='/controls/wijmo.grid.min.js'></script>
<script src='/controls/wijmo.grid.filter.min.js'></script>
<script src='/controls/wijmo.chart.min.js'></script>
<script src='/controls/wijmo.olap.min.js'></script>
<script src="/controls/cultures/wijmo.culture.ko.min.js"></script>

<script>
  document.readyState === 'complete' ? init() : window.onload = init;
//
function init() {
    //
    // initialize pivot engine
    var ngPanel = new wijmo.olap.PivotEngine({
        itemsSource: getData(),
        valueFields: ['Amount'],
        rowFields: ['Buyer', 'Type'] // summarize amounts
    });
    ngPanel.fields.getField('Amount').format = 'c0'; // customize field
    //
    // 피벗 패널 표시
    var pivotPanel = new wijmo.olap.PivotPanel('#pivotPanel', {
        itemsSource: ngPanel
    });
    //
    // 요약 표시
    var pivotPanelGrid = new wijmo.olap.PivotGrid('#pivotPanelGrid', {
        itemsSource: ngPanel
    });
    var pivotPanelChart = new wijmo.olap.PivotChart('#pivotPanelChart', {
        itemsSource: ngPanel,
        showTitle: false,
        showLegend: 'Auto'
    });
    //
    // 뷰 저장/복원
    document.getElementById('saveView').addEventListener('click', function () {
        if (ngPanel.isViewDefined) {
            localStorage.viewDefinition = ngPanel.viewDefinition;
        }
    });
    document.getElementById('restoreView').addEventListener('click', function () {
        if (localStorage.viewDefinition) {
            ngPanel.viewDefinition = localStorage.viewDefinition;
        }
    });
}

function getData() {
    var yr = new Date().getFullYear();
    return [{
            date: new Date(yr, 0, 1),
            buyer: 'Mom',
            type: 'Fuel',
            amount: 74
        },
        {
            date: new Date(yr, 0, 15),
            buyer: 'Mom',
            type: 'Food',
            amount: 235
        },
        {
            date: new Date(yr, 0, 17),
            buyer: 'Dad',
            type: 'Sports',
            amount: 20
        },
        {
            date: new Date(yr, 0, 21),
            buyer: 'Kelly',
            type: 'Books',
            amount: 125
        },
        {
            date: new Date(yr, 1, 2),
            buyer: 'Mom',
            type: 'Food',
            amount: 235
        },
        {
            date: new Date(yr, 1, 20),
            buyer: 'Kelly',
            type: 'Music',
            amount: 20
        },
        {
            date: new Date(yr, 1, 25),
            buyer: 'Kelly',
            type: 'Tickets',
            amount: 125
        },
    ];
}

</script>

</body>
</html>


체감상: 필드 드래그 → 요약 반영 흐름이 바로 보여서, 직관적이었습니다.

 

결과화면

좋았던 점

  • 실사용 UI가 그대로: 행/열/값/필터 슬롯이 엑셀 감성이어서 학습 부담이 낮음.
  • 집계 체감 속도: 수천 건 단위에선 즉각 반응. 조회/시도/변경 사이클이 빠름.
  • 구성 저장/복원: engine.viewDefinition 하나로 저장/불러오기가 되어 사용자별 뷰 고정이 쉬움.
  • PureJS, React, Vue, Angular 지원: 프레임워크 제약없이 사용 가능.

아쉬웠던 점 / 주의

  • 스타일 커스터마이징: 기본은 무난. 다만 브랜드 가이드 맞춤(합계 강조, 소계 라인 등)은 CSS 손이 조금 감.
  • 문서 탐색: 키워드(예: viewDefinition, deferUpdate, PivotField.filter)를 알고 보면 쉬운데, 초반엔 검색 키워드가 감이 안 올 수 있음.

작은 팁

  • **여러 옵션 변경 시 deferUpdate**로 감싸기 → 재계산 최소화.
  • 필드 포맷 미리 정의(통화/퍼센트 등) → 보고서 퀄리티 개선.
  • PivotChart는 요약 뷰로 두고, 디테일은 PivotGrid에서 확인하는 흐름이 자연스러웠음.

결론 한 줄

웹에서 데이터 분석을 기능을 구현하고 싶을 때, PureJS로도 셋업이 가볍게 할 수 있고 커스터마이징은 설계가 조금 필요하지만, 보편적인 분석/요약 요구에는 충분히 실용적이었습니다~😀😀

'프로그래밍 > wijmo' 카테고리의 다른 글

퍼포먼스 좋은 데이터 그리드 UI - Wijmo  (0) 2025.09.10