계층형 카테고리

이 샘플은 데이터 차트에서 계층형 카테고리를 사용하는 방법을 보여 줍니다. 각 시트는 Country > City처럼 중첩 필드로 데이터를 그룹화하여, 지원되는 서로 다른 차트 유형을 다중 수준 카테고리 축과 함께 표시합니다.

데이터 차트는 계층형 카테고리를 지원하며, 이를 통해 직교 좌표계 차트에서 다중 수준 카테고리 축을 사용할 수 있습니다. category 인코딩의 child 속성을 사용하여 중첩 카테고리를 정의합니다. 지원되는 차트 유형에는 세로 막대형, 범위 세로 막대형, 누적 세로 막대형, 100% 기준 누적 세로 막대형, 가로 막대형, 범위 가로 막대형, 누적 가로 막대형, 100% 기준 누적 가로 막대형, 영역형, 범위 영역형, 누적 영역형, 100% 기준 누적 영역형, 꺾은선형, 주식형, OHLC가 포함됩니다. 이 샘플의 각 시트는 이러한 차트 유형 중 하나를 계층형 카테고리 축과 함께 보여 줍니다. 참고: 계층형 카테고리는 축 기반(직교 좌표계) 차트 유형에만 적용됩니다. 원형, 도넛, 선버스트, 트리맵, 깔때기형, 폭포형 같은 비축 차트는 이 기능을 지원하지 않습니다.
window.onload = async () => { const { spread, designer } = createSpreadAndDesigner(); await initDataManager(spread); const DataChartType = GC.Spread.Sheets.DataCharts.DataChartType; const Aggregate = GC.Spread.Sheets.DataCharts.Aggregate; const chartConfigs = [ { name: 'Column', type: DataChartType.column, table: 'Sales', encoding: 'single' }, { name: 'Range Column', type: DataChartType.rangeColumn, table: 'Sales', encoding: 'range' }, { name: 'Stacked Column', type: DataChartType.stackedColumn, table: 'Sales', encoding: 'stacked' }, { name: 'Percent Stacked Column', type: DataChartType.percentStackedColumn, table: 'Sales', encoding: 'stacked' }, { name: 'Bar', type: DataChartType.bar, table: 'Sales', encoding: 'single' }, { name: 'Range Bar', type: DataChartType.rangeBar, table: 'Sales', encoding: 'range' }, { name: 'Stacked Bar', type: DataChartType.stackedBar, table: 'Sales', encoding: 'stacked' }, { name: 'Percent Stacked Bar', type: DataChartType.percentStackedBar, table: 'Sales', encoding: 'stacked' }, { name: 'Area', type: DataChartType.area, table: 'Sales', encoding: 'single' }, { name: 'Range Area', type: DataChartType.rangeArea, table: 'Sales', encoding: 'range' }, { name: 'Stacked Area', type: DataChartType.stackedArea, table: 'Sales', encoding: 'stacked' }, { name: 'Percent Stacked Area', type: DataChartType.percentStackedArea, table: 'Sales', encoding: 'stacked' }, { name: 'Line', type: DataChartType.line, table: 'Sales', encoding: 'single' }, { name: 'Candlestick', type: DataChartType.candlestick, table: 'Stock', encoding: 'ohlc' }, { name: 'OHLC', type: DataChartType.ohlc, table: 'Stock', encoding: 'ohlc' }, ]; spread.setSheetCount(chartConfigs.length); for (let i = 0; i < chartConfigs.length; i++) { const cfg = chartConfigs[i]; const sheet = spread.getSheet(i); sheet.name(cfg.name); addChartToSheet(sheet, cfg, Aggregate); } spread.setActiveSheetIndex(0); spread.getActiveSheet().dataCharts.all()[0].isSelected(true); if (designer) { designer.refresh(); } } function addChartToSheet(sheet, cfg, Aggregate) { const dataChart = sheet.dataCharts.add(cfg.name, 20, 20, 450, 300, cfg.type); let encodings; const hierarchicalCategory = { field: 'Region', child: { field: 'Salesman' } }; const ohlcHierarchicalCategory = { field: 'month', child: { field: 'day' } }; switch (cfg.encoding) { case 'single': encodings = { values: [{ field: 'Sales', aggregate: Aggregate.sum }], category: hierarchicalCategory, }; break; case 'range': encodings = { values: [{ vectors: { upper: { field: 'Sales' }, lower: { field: 'Return' }, }, aggregate: Aggregate.sum, }], category: hierarchicalCategory, }; break; case 'stacked': encodings = { values: [{ field: 'Sales', aggregate: Aggregate.sum }], category: hierarchicalCategory, color: { field: 'Product' }, }; break; case 'ohlc': encodings = { values: [{ vectors: { open: { field: 'open' }, high: { field: 'high' }, low: { field: 'low' }, close: { field: 'close' }, }, }], category: ohlcHierarchicalCategory, }; break; } dataChart.setChartConfig({ tableName: cfg.table, plots: [{ type: cfg.type, encodings: encodings, }], config: { header: { title: cfg.name + ' - Hierarchical Category', padding: { left: 10, right: 10, top: 10, bottom: 10 }, textStyle: { fontSize: 16, alignment: GC.Spread.Sheets.DataCharts.HAlign.left, }, }, }, }); } function createSpreadAndDesigner() { const demoHost = document.getElementById('demo-host'); if (window !== top) { const spread = new GC.Spread.Sheets.Workbook('spread-host', { sheetCount: 1 }); new GC.Spread.Sheets.DataCharts.DataChartConfigPanel('panel-host', spread); return { spread } } else { const designer = new GC.Spread.Sheets.Designer.Designer(demoHost, undefined, undefined, { sheetCount: 1 }); return { designer, spread: designer.getWorkbook(), } } } async function initDataManager(spread) { const dataManager = spread.dataManager(); await dataManager.addTable('Sales', { data: [ { Region: 'East', Salesman: 'Alice', Product: 'Laptop', Sales: 450, Return: 120 }, { Region: 'East', Salesman: 'Alice', Product: 'Phone', Sales: 320, Return: 85 }, { Region: 'East', Salesman: 'Bob', Product: 'Laptop', Sales: 380, Return: 95 }, { Region: 'East', Salesman: 'Bob', Product: 'Phone', Sales: 290, Return: 70 }, { Region: 'East', Salesman: 'Carol', Product: 'Laptop', Sales: 410, Return: 110 }, { Region: 'East', Salesman: 'Carol', Product: 'Phone', Sales: 350, Return: 90 }, { Region: 'West', Salesman: 'Dave', Product: 'Laptop', Sales: 520, Return: 140 }, { Region: 'West', Salesman: 'Dave', Product: 'Phone', Sales: 280, Return: 65 }, { Region: 'West', Salesman: 'Eve', Product: 'Laptop', Sales: 470, Return: 130 }, { Region: 'West', Salesman: 'Eve', Product: 'Phone', Sales: 310, Return: 80 }, { Region: 'West', Salesman: 'Frank', Product: 'Laptop', Sales: 390, Return: 100 }, { Region: 'West', Salesman: 'Frank', Product: 'Phone', Sales: 260, Return: 60 }, { Region: 'North', Salesman: 'Grace', Product: 'Laptop', Sales: 340, Return: 90 }, { Region: 'North', Salesman: 'Grace', Product: 'Phone', Sales: 270, Return: 75 }, { Region: 'North', Salesman: 'Hank', Product: 'Laptop', Sales: 430, Return: 115 }, { Region: 'North', Salesman: 'Hank', Product: 'Phone', Sales: 300, Return: 80 }, { Region: 'South', Salesman: 'Ivy', Product: 'Laptop', Sales: 480, Return: 125 }, { Region: 'South', Salesman: 'Ivy', Product: 'Phone', Sales: 330, Return: 85 }, { Region: 'South', Salesman: 'Jack', Product: 'Laptop', Sales: 360, Return: 95 }, { Region: 'South', Salesman: 'Jack', Product: 'Phone', Sales: 250, Return: 55 }, ], }).fetch(); await dataManager.addTable('Stock', { data: [ { month: 'Jan', day: 'Jan-01', open: 150.00, high: 155.20, low: 148.50, close: 153.80 }, { month: 'Jan', day: 'Jan-02', open: 153.80, high: 157.40, low: 152.10, close: 156.90 }, { month: 'Jan', day: 'Jan-03', open: 156.90, high: 158.60, low: 154.30, close: 155.20 }, { month: 'Jan', day: 'Jan-04', open: 155.20, high: 159.80, low: 154.00, close: 158.50 }, { month: 'Jan', day: 'Jan-05', open: 158.50, high: 162.30, low: 157.20, close: 161.00 }, { month: 'Feb', day: 'Feb-01', open: 161.00, high: 163.50, low: 159.80, close: 162.40 }, { month: 'Feb', day: 'Feb-02', open: 162.40, high: 165.70, low: 161.30, close: 164.80 }, { month: 'Feb', day: 'Feb-03', open: 164.80, high: 166.20, low: 162.50, close: 163.10 }, { month: 'Feb', day: 'Feb-04', open: 163.10, high: 167.90, low: 162.00, close: 167.30 }, { month: 'Feb', day: 'Feb-05', open: 167.30, high: 170.10, low: 166.50, close: 169.20 }, { month: 'Mar', day: 'Mar-01', open: 169.20, high: 172.40, low: 168.00, close: 171.50 }, { month: 'Mar', day: 'Mar-02', open: 171.50, high: 173.80, low: 169.60, close: 170.30 }, { month: 'Mar', day: 'Mar-03', open: 170.30, high: 174.50, low: 169.10, close: 173.90 }, { month: 'Mar', day: 'Mar-04', open: 173.90, high: 176.20, low: 172.30, close: 175.60 }, { month: 'Mar', day: 'Mar-05', open: 175.60, high: 178.00, low: 174.20, close: 176.80 }, ], }).fetch(); }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta name="spreadjs culture" content="ko-kr"> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-designer/styles/gc.spread.sheets.designer.light.min.css"> <link rel="stylesheet" type="text/css" href="styles.css"> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets/dist/gc.spread.sheets.all.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-print/dist/gc.spread.sheets.print.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-shapes/dist/gc.spread.sheets.shapes.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-datacharts-addon/dist/gc.spread.sheets.datacharts.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-tablesheet/dist/gc.spread.sheets.tablesheet.min.js" type="text/javascript"></script> <script src="$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-resources-ko/dist/gc.spread.sheets.resources.ko.min.js"></script> <script src="$DEMOROOT$/spread/source/js/license.js" type="text/javascript"></script> <script> const designerDependencyScripts = [ '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-charts/dist/gc.spread.sheets.charts.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-barcode/dist/gc.spread.sheets.barcode.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-pdf/dist/gc.spread.sheets.pdf.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-pivot-addon/dist/gc.spread.pivot.pivottables.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-slicers/dist/gc.spread.sheets.slicers.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-reportsheet-addon/dist/gc.spread.report.reportsheet.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-ganttsheet/dist/gc.spread.sheets.ganttsheet.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-formula-panel/dist/gc.spread.sheets.formulapanel.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-io/dist/gc.spread.sheets.io.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-designer-resources-ko/dist/gc.spread.sheets.designer.resource.ko.min.js', '$DEMOROOT$/ko/purejs/node_modules/@mescius/spread-sheets-designer/dist/gc.spread.sheets.designer.all.min.js', '$DEMOROOT$/spread/source/js/designer/license.js', ] function appendScriptNode (src) { const script = document.createElement('script'); script.src = src; script.async = false; script.type = 'text/javascript'; document.head.appendChild(script); } if (top === window) { // not in iframe designerDependencyScripts.forEach(appendScriptNode); } </script> <script src="app.js" type="text/javascript"></script> </head> <body> <div class="sample-tutorial"> <div id="demo-host"> <div id="spread-host"></div> <div id="panel-host"></div> </div> </div> </body> </html>
body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .sample-tutorial { position: relative; height: 100%; overflow: hidden; } #demo-host { width: 100%; height: 100%; overflow: hidden; float: left; } #spread-host { position: absolute; top: 0; left: 0; width: calc(100% - 380px); height: 100%; } #panel-host { position: absolute; top: 0; right: 0; width: 380px; height: 100%; }