트리 그리드
childItemsPath을 사용한 TreeGrid
Wijmo Grid 컨트롤의 데이터 항목에 children 항목 컬렉션이 포함된 경우 FlexGrid의 childItemsPath를 사용하여 데이터를 트리로 표시할 수 있습니다.
아래 그리드는 그리드를 최상위 사용자 목록에 바인딩하고 childItemsPath 속성을 'children'으로 설정하여 구축되었습니다. 예제 :
import * as wjGrid from '@grapecity/wijmo.grid';// family tree data (homogeneous collection)var family = [{ name: 'Albert', children: [{ name: 'Anton' },{ name: 'Annette' },]},{ name: 'Benjamin', children: [{ name: 'Bridget', children: [{ name: 'Billy' },{ name: 'Bernard' },]},{ name: 'Bella' },{ name: 'Bob' },]},{ name: 'Charlie', children: [{ name: 'Chris' },{ name: 'Connie' },{ name: 'Carrie' },]},{ name: 'Douglas', children: [{ name: 'Dinah' },{ name: 'Donald' }]}];// family treevar familyGrid = new wjGrid.FlexGrid('#familyGrid', {headersVisibility: 'None',childItemsPath: 'children',itemsSource: family});
계층 구조에서는 수준별로 항목 유형이 다르고 하위 항목 속성이 다른 'heterogeneous' 계층 구조도 있습니다.
예를 들어 아래는 'earnings'이 나열하는 'checks'를 갖는 'worker' 객체 컬렉션에 바인딩된 그리드 입니다.:
import * as wjGrid from '@grapecity/wijmo.grid';// workers tree data (heterogeneous collection)var workers = [{name: 'Jack Smith',checks: [{name: 'check1',earnings: [{ name: 'hourly', hours: 30.0, rate: 15.0 },{ name: 'overtime', hours: 10.0, rate: 20.0 },{ name: 'bonus', hours: 5.0, rate: 30.0}]}, {name: 'check2',earnings: [{ name: 'hourly', hours: 20.0, rate: 18.0 },{ name: 'overtime', hours: 20.0, rate: 24.0 }]}]}, {name: 'Jack Smith',checks: [{name: 'check1',earnings: [{ name: 'hourly', hours: 30.0, rate: 15.0 },{ name: 'overtime', hours: 10.0, rate: 20.0 },{ name: 'bonus', hours: 5.0, rate: 30.0 }]}, {name: 'check2',earnings: [{ name: 'hourly', hours: 20.0, rate: 18.0 },{ name: 'overtime', hours: 20.0, rate: 24.0 }]}]}, {name: 'Jane Smith',checks: [{name: 'check1',earnings: [{ name: 'hourly', hours: 30.0, rate: 15.0 },{ name: 'overtime', hours: 10.0, rate: 20.0 },{ name: 'bonus', hours: 5.0, rate: 30.0 }]}, {name: 'check2',earnings: [{ name: 'hourly', hours: 20.0, rate: 18.0 },{ name: 'overtime', hours: 20.0, rate: 24.0 }]}]}];// workers treevar workersGrid = new wjGrid.FlexGrid('#workersGrid', {headersVisibility: 'Column',childItemsPath: ['checks','earnings'],autoGenerateColumns: false,columns: [{ binding: 'name' },{ binding: 'hours', dataType: 'Number' },{ binding: 'rate', dataType: 'Number' }],itemsSource: workers});
XML에 바인딩한 TreeGrid
DOMParser 객체를 사용하여 XML 문자열을 문서 객체로 파싱하고 문서를 반복하여 각각 "products" 배열을 사용하여 "category" 항목이 있는 배열을 빌드합니다.
// get the XML string used as a data sourcefunction getXml() {return '<categories>' +'<category id="0" name="Beverages">' +'<product id="1" name="Chai" price="18" />' +'<product id="2" name="Chang" price="19" />' +'<product id="24" name="Guarana Fantastica" price="4.5" />' +'<product id="34" name="Sasquatch Ale" price="14" />' +'</category>' +'<category id="1" name="Condiments">' +'<product id="3" name="Aniseed Syrup" price="10" />' +'<product id="4" name="Chef Anton\'s Cajun Seasoning" price="22" />' +'<product id="5" name="Chef Anton\'s Gumbo Mix" price="21.35" />' +'<product id="6" name="Grandma\'s Boysenberry Spread" price="25" />' +'<product id="8" name="Northwoods Cranberry Sauce" price="40" />' +'<product id="15" name=" Genen Shouyu" price="15.5" />' +'</category>''</categories>';}// parse an XML document into an arrayfunction getProductsByCategory() {var items = [],parser = new DOMParser(),xml = getXml(),doc = parser.parseFromString(xml, 'application/xml');// get categoriesvar categories = doc.querySelectorAll('category');for (var c = 0; c < categories.length; c++) {var category = categories[c];items.push({id: parseInt(category.getAttribute('id')),name: category.getAttribute('name'),products: []});// get products in this categoryvar products = category.querySelectorAll('product');for (var p = 0; p < products.length; p++) {var product = products[p];items[items.length - 1].products.push({id: parseInt(product.getAttribute('id')),name: product.getAttribute('name'),price: parseFloat(product.getAttribute('price'))})}}// all donereturn items;}
배열이 itemsSource로 사용되었고 childItemsPath 속성은 각 카테고리의 제품을 트리로 표시하는 데 사용됩니다.
import * as wjGrid from '@grapecity/wijmo.grid';var theGrid = new wjGrid.FlexGrid('#theGrid', {autoGenerateColumns: false,columns: [{ binding: 'name', header: 'Name', width: '3*' },{ binding: 'id', header: 'ID', dataType: 'String', width: '*' },{ binding: 'price', header: 'Unit Price', format: 'n2', dataType: 'Number', width: '*' },],headersVisibility: 'Column',childItemsPath: 'products',treeIndent: 25,itemsSource: getProductsByCategory()});
Laze-loading TreeGrid
아래 트리 그리드에서 접힌 노드는 단일 더미 child 노드를 가집니다. 노드가 확장되며 요청 시 더 많은 노드가 로드됩니다.
이것은 'lazy-loading'이라고 알려진 일반적인 패턴입니다.
// create the gridvar theGrid = new wijmo.grid.FlexGrid('#theGrid', {childItemsPath: 'children',headersVisibility: 'Column',groupCollapsedChanged: groupCollapsedChanged,autoGenerateColumns: false,columns: [{binding: 'name',header: 'Customer Name',width: '*'},{binding: 'id',header: 'ID',align: 'center',cssClass: 'id-column'}],itemsSource: getData(),});// start collapsedtheGrid.collapseGroupsToLevel(0);// update row when items are loadedfunction updateRowCount(grid) {document.getElementById('rowCount').textContent = wijmo.Globalize.format(grid.rows.length, 'n0');}updateRowCount(theGrid);// load data when collapse node is expandedfunction groupCollapsedChanged(s, e) {var row = s.rows[e.row],item = row.dataItem;// did we just expand a node with a dummy child?if (!row.isCollapsed &&item.children.length == 1 &&item.children[0].name == '') {// can't lazy load while updating rowsif (s.rows.isUpdating) {row.isCollapsed = true;return;}// replace the dummy child with actual nodesitem.children.length = 0;var cnt = Math.round(Math.random() * 5) + 1;for (var i = 0; i < cnt; i++) {var node = createNode();item.children.push(node);}// refresh the views.collectionView.refresh();// collapse the new item's child itemsfor (var i = row.index + 1; i < s.rows.length; i++) {var childRow = s.rows[i];if (childRow.level <= row.level) {break;}childRow.isCollapsed = true;}// update row countupdateRowCount(s);}}// create/retrieve datafunction getData() {var tree = [];tree.push(createNode());tree.push(createNode());return tree;}var nodeId;function createNode(dummy) {var first = 'Al,Bob,Cal,Dan,Ed,Fred,Greg,Hal,Ian,Jack,Karl,Lou,Moe,Nate,Oleg,Paul,Quincy,Rod,Sue,Uwe,Vic,Walt,Xiu,Yuri,Zack'.split(','),last = 'Adams,Baum,Cole,Dell,Evans,Fell,Green,Hill,Isman,Jones,Krup,Lee,Monk,Nye,Opus,Pitt,Quaid,Riems,Stark,Trell,Unger,Voss,Wang,Xie,Zalm'.split(','),name = dummy ? '' : getOneOf(first) + ' ' + getOneOf(last),children = [];if (!dummy) {children.push(createNode(true));}if (nodeId == null) nodeId = 0;return {id: nodeId++,name: name,children: children};}function getOneOf(arr) {return arr[Math.floor(Math.random() * arr.length)];}
바인딩되지 않은 TreeGrid
바인딩되지 않은 모드에서 작업하려는 경우에도 코드에서 행과 열을 추가하여 트리를 만들 수 있습니다.
배열의 datasource 부터 시작합니다. FlexGrid를 초기화하지만 배열에 바인딩하지는 않습니다.
import * as wjGrid from '@grapecity/wijmo.grid';// workers tree data (heterogeneous collection)var workers = [{name: 'Jack Smith',checks: [{name: 'check1',earnings: [{ name: 'hourly', hours: 30.0, rate: 15.0 },{ name: 'overtime', hours: 10.0, rate: 20.0 },{ name: 'bonus', hours: 5.0, rate: 30.0}]}, {name: 'check2',earnings: [{ name: 'hourly', hours: 20.0, rate: 18.0 },{ name: 'overtime', hours: 20.0, rate: 24.0 }]}]}];// unbound workers treevar uwt = new wjGrid.FlexGrid('#workersGrid', {headersVisibility: 'Column',selectionMode: 'Row',beginningEdit: function(s, e) {var value = e.panel.getCellData(e.row, e.col);if (value == null) {e.cancel = true; // can't edit!}}});
열을 추가하고 속성을 정의합니다.
// unbound workers treevar uwt = new wjGrid.FlexGrid('#workersGrid', {headersVisibility: 'Column',selectionMode: 'Row',beginningEdit: function(s, e) {var value = e.panel.getCellData(e.row, e.col);if (value == null) {e.cancel = true; // can't edit!}}});
배열을 반복하고 그룹 행과 셀을 추가합니다.
// add rowsfor (var w = 0; w < workers.length; w++) {// add workervar worker = workers[w];var row = new wjGrid.GroupRow(worker);row.isReadOnly = false;row.level = 0;uwt.rows.push(row);uwt.setCellData(row.index, 0, worker.name);for (var c = 0; c < worker.checks.length; c++) {// add checkvar check = worker.checks[c];row = new wjGrid.GroupRow(check);row.isReadOnly = false;row.level = 1;uwt.rows.push(row);uwt.setCellData(row.index, 0, check.name);for (var e = 0; e < check.earnings.length; e++) {// add earningvar earning = check.earnings[e];row = new wjGrid.GroupRow(earning);row.isReadOnly = false;row.level = 2;uwt.rows.push(row);uwt.setCellData(row.index, 0, earning.name);uwt.setCellData(row.index, 1, earning.hours);uwt.setCellData(row.index, 2, earning.rate);}}}
다음 섹션으로 넘어가 다양한 트리 그리드 샘플을 확인해보세요.