피벗 테이블 항목 슬라이서

SpreadJS 피벗 테이블은 표 슬라이서처럼 사용할 수 있는 항목 슬라이서를 지원합니다.

사용 가능한 모든 속성을 보려면 아래 데모에서 슬라이서를 클릭해 보십시오.

피벗 테이블 항목 슬라이서는 표 슬라이서와 동일하게 SlicerCollection(WorkSheet.slicers)에 의해 관리됩니다. 항목 슬라이서는 모든 필드에 추가할 수 있습니다(Calc 필드 제외). 항목 슬라이서를 변경하는 것은 레이블 필터의 "textItems"를 의미하는 수동 필터를 사용하는 것과 같습니다. 슬라이서 추가 피벗 테이블 항목 슬라이서를 추가하려면 "pt"라는 이름의 피벗 테이블을 만들면 됩니다. initPivotTable의 구체적인 구현 방법은 이 문서 끝 부분에서 확인할 수 있습니다. 그런 다음 "name" 필드에 항목 슬라이서를 추가합니다. 항목 상태 항목을 두 가지 상태로 정의했습니다. selected: 항목이 필터에 의해 선택되었는지 여부. noData: 항목이 다른 필터에 의해 필터링되어 있다면 선택 여부에 관계없이 해당 항목이 적용되지 않음을 의미하며, 이 상태를 noData로 정의했습니다. 이 두 가지 상태가 항목 상태를 구성합니다. 예: "selected && noData" 또는 "unselected && hasData" 슬라이서 사용 그런 다음 slicer_name을 정의할 수 있습니다. 예를 들어 두 개의 열에서 항목을 표시하려는 경우: 항목의 높이를 정의하려는 경우: noData 상태인 항목을 표시하지 않으려는 경우: 피벗 테이블 만들기 샘플 사용자 정의 항목 슬라이서 테마 SpreadJS는 피벗 테이블 항목 슬라이서의 테마를 사용자 정의하는 기능을 지원합니다. 다음 코드를 사용합니다.
import * as React from 'react'; import * as ReactDOM from 'react-dom'; import './styles.css'; import { AppFunc } from './app-func'; import { App } from './app-class'; // 1. Functional Component sample ReactDOM.render(<AppFunc />, document.getElementById('app')); // 2. Class Component sample // ReactDOM.render(<App />, document.getElementById('app'));
import * as React from 'react'; import GC from '@mescius/spread-sheets'; import "@mescius/spread-sheets-shapes"; import "@mescius/spread-sheets-slicers"; import "@mescius/spread-sheets-pivot-addon"; import { SpreadSheets } from '@mescius/spread-sheets-react'; import '@mescius/spread-sheets-resources-ko'; GC.Spread.Common.CultureManager.culture("ko-kr"); import './styles.css'; const useState = React.useState; export function AppFunc() { const [spread, setSpread] = useState(null); const [ptName, setPTName] = useState(''); const initSpread = (spread) => { setSpread(spread); spread.setSheetCount(2); initSheets(spread); let pivotLayoutSheet = spread.getSheet(0); initPivotTable(pivotLayoutSheet); } const initSheets = (spread) => { spread.suspendPaint(); spread.setSheetCount(2); let sheet = spread.getSheet(1); sheet.name("DataSource"); sheet.setRowCount(650); sheet.setColumnWidth(5, 120); sheet.getCell(-1, 5).formatter("YYYY-mm-DD"); sheet.getRange(-1, 4, 0, 1).formatter("$ #,##0"); sheet.setArray(0, 0, pivotSales); let table = sheet.tables.add('tableSales', 0, 0, 637, 6); table.style(GC.Spread.Sheets.Tables.TableThemes["none"]); let sheet0 = spread.getSheet(0); sheet0.name("PivotLayout"); spread.resumePaint(); } const getSource = (sheet, tableSource) => { sheet.name("DataSource"); sheet.setRowCount(1984); sheet.setColumnWidth(0, 120); sheet.getCell(-1, 0).formatter("YYYY-mm-DD"); sheet.getRange(-1, 4, 0, 2).formatter("$ #,##0"); let table = sheet.tables.add('table', 0, 0, 1984, 6); for (let i = 2; i <= 1984; i++) { sheet.setFormula(i - 1, 5, '=D' + i + '*E' + i) } table.style(GC.Spread.Sheets.Tables.TableThemes["none"]); sheet.setArray(0, 0, tableSource); return table.name(); } const initPivotTable = (sheet) => { sheet.setRowCount(1000); let option = { showRowHeader: true, showColumnHeader: true, bandRows: true, bandColumns: true }; let pivotTable = sheet.pivotTables.add("pivotTable", "tableSales", 1, 0, GC.Spread.Pivot.PivotTableLayoutType.outline, GC.Spread.Pivot.PivotTableThemes.medium8.name(), option); pivotTable.suspendLayout(); pivotTable.add("region", "region", GC.Spread.Pivot.PivotTableFieldType.rowField); pivotTable.add("country", "countrys", GC.Spread.Pivot.PivotTableFieldType.rowField); pivotTable.add("city", "city", GC.Spread.Pivot.PivotTableFieldType.rowField); let groupInfo = { originFieldName: "date", dateGroups: [ { by: GC.Pivot.DateGroupType.quarters } ] }; pivotTable.group(groupInfo); pivotTable.add("amount", "amount", GC.Spread.Pivot.PivotTableFieldType.valueField, GC.Pivot.SubtotalType.sum); pivotTable.options.subtotalsPosition = GC.Spread.Pivot.SubtotalsPosition.none; pivotTable.resumeLayout(); pivotTable.autoFitColumn(); setPTName(pivotTable.name()); } return ( <div class="sample-tutorial"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => initSpread(spread)}> </SpreadSheets> </div> <div class="options-container"> <PivotTableItemSlicer spread={spread} ptName={ptName}></PivotTableItemSlicer> </div> </div> ); } const useEffect = React.useEffect; function PivotTableItemSlicer({ spread, ptName }) { const [slicerCount, setSlicerCount] = useState(0); const [state, setState] = useState({ columnCount: 0, showHeader: true, showNoDataItems: false, visuallyNoDataItems: true, showNoDataItemsInLast: true, sortState: 1, selectedField: "region", styleName: "" }); useEffect(() => { if (spread) { initCustomThemes(spread); initSlicers(); bindEvents(); } }, [spread]); const getActiveSlicer = () => { const sheet = spread.getSheet(0); if (!sheet) { return null; } let slicers = sheet.slicers.all(); for (let i = 0; i < slicers.length; i++) { if (slicers[i].isSelected()) { return slicers[i]; } } return null; } const initCustomThemes = (spread) => { const theme1 = new GC.Spread.Sheets.Slicers.SlicerStyle(); theme1.fromJSON(GC.Spread.Sheets.Slicers.SlicerStyles.light1().toJSON()); theme1.name('custom1'); theme1.wholeSlicerStyle(new GC.Spread.Sheets.Slicers.SlicerStyleInfo('rgb(225, 245, 254)')); const theme2 = new GC.Spread.Sheets.Slicers.SlicerStyle(); theme2.fromJSON(GC.Spread.Sheets.Slicers.SlicerStyles.other2().toJSON()); theme2.name('custom2'); const wholeSlicerStyle = new GC.Spread.Sheets.Slicers.SlicerStyleInfo(); wholeSlicerStyle.backColor('#e3f2fd'); theme2.wholeSlicerStyle(wholeSlicerStyle); spread.customSlicerThemes.add(theme1); spread.customSlicerThemes.add(theme2); } const initSlicers = () => { const sheet = spread.getSheet(0); if (!sheet) { return; } let slicer_region = sheet.slicers.add("slicer_region", ptName, "region", GC.Spread.Sheets.Slicers.SlicerStyles.dark2().name(), GC.Spread.Sheets.Slicers.SlicerType.pivotTable); slicer_region.position(new GC.Spread.Sheets.Point(491, 20)); slicer_region.height(210); let slicer_country = sheet.slicers.add("slicer_country", ptName, "country", GC.Spread.Sheets.Slicers.SlicerStyles.light1().name(), GC.Spread.Sheets.Slicers.SlicerType.pivotTable) slicer_country.position(new GC.Spread.Sheets.Point(691, 20)); slicer_country.height(460); slicer_country.showNoDataItems(false); let slicer_city = sheet.slicers.add("slicer_city", ptName, "city", GC.Spread.Sheets.Slicers.SlicerStyles.other2().name(), GC.Spread.Sheets.Slicers.SlicerType.pivotTable); slicer_city.position(new GC.Spread.Sheets.Point(891, 20)); slicer_city.height(320); slicer_city.columnCount(2); } const bindEvents = () => { const sheet = spread.getSheet(0); if (!sheet) { return; } sheet.bind(GC.Spread.Sheets.Events.SlicerChanged, function () { let slicers = sheet.slicers.all(); for (let i = 0; i < slicers.length; i++) { if (slicers[i].isSelected()) { updateSlicerInfo(); break; } } }); } const updateSlicerInfo = () => { const activeSlicer = getActiveSlicer(); if (!activeSlicer) { return; } let slicer = activeSlicer; const slicerStyleName = slicer.style().name().toLowerCase(); const styleName = slicerStyleName.includes('custom') ? slicerStyleName : slicerStyleName.substr(11); setState({ ...state, columnCount: slicer.columnCount(), showHeader: slicer.showHeader(), showNoDataItems: slicer.showNoDataItems(), visuallyNoDataItems: slicer.visuallyNoDataItems(), showNoDataItemsInLast: slicer.showNoDataItemsInLast(), sortState: slicer.sortState(), styleName: styleName }); } const setColumnCount = (v) => { let numberV = parseInt(v, 10); if (!isNaN(numberV)) { setState({ ...state, ...state, columnCount: numberV }); changeProperty("columnCount", numberV); } else { setState({ ...state, ...state, columnCount: null }); } } const changeProperty = (prop, v) => { const activeSlicer = getActiveSlicer(); if (!activeSlicer) { return; } if (v !== null && v !== undefined) { activeSlicer[prop](v); } } const setStyle = () => { const activeSlicer = getActiveSlicer(); if (!activeSlicer) { return; } activeSlicer.style(state.styleName); } const addSlicer = () => { const sheet = spread.getSheet(0); if (!sheet) { return; } sheet.slicers.add(state.selectedField + "_" + slicerCount, ptName, state.selectedField, GC.Spread.Sheets.Slicers.SlicerStyles.light1().name(), GC.Spread.Sheets.Slicers.SlicerType.pivotTable); setSlicerCount(slicerCount => slicerCount + 1); } return ( <div class="options-container"> <div class="block slicer-infos"> <div>Current Selected Slicer Info:</div><br /> <div class="slicer-info"> <label>Column Count:</label> <input class="info-input" type="number" id="columnCount" value={state.columnCount} onChange={e => { setColumnCount(e.target.value) }} /> </div> <div class="slicer-info"> <input type="checkbox" id="showHeader" checked={state.showHeader} onChange={e => { setState({ ...state, showHeader: e.target.checked }); changeProperty("showHeader", e.target.checked) }} /> <label for="showHeader">Display Header</label> </div> <div class="slicer-info"> <input type="checkbox" id="showNoDataItems" checked={!state.showNoDataItems} onChange={e => { setState({ ...state, showNoDataItems: !e.target.checked }); changeProperty("showNoDataItems", !e.target.checked) }} /> <label for="showNoDataItems">Hide Items With No Data</label> </div> <div class="slicer-info"> <input type="checkbox" id="visuallyNoDataItems" checked={state.visuallyNoDataItems} onChange={e => { setState({ ...state, visuallyNoDataItems: e.target.checked }); changeProperty("visuallyNoDataItems", e.target.checked) }} /> <label for="visuallyNoDataItems">Visually Indicate Items With No Data</label> </div> <div class="slicer-info"> <input type="checkbox" id="showNoDataItemsInLast" checked={state.showNoDataItemsInLast} onChange={e => { setState({ ...state, showNoDataItemsInLast: e.target.checked }); changeProperty("showNoDataItemsInLast", e.target.checked) }} /> <label for="showNoDataItemsInLast">Show Items With No Data Last</label> </div> <div class="slicer-info"> <p>Sort State</p> <input type="radio" id="ascending" name="sortState" checked={state.sortState === 1} onChange={e => { setState({ ...state, sortState: e.target.checked ? 1 : 2 }); changeProperty("sortState", 1) }} /> <label for="ascending">Ascending(A to Z)</label><br /> <input type="radio" id="descending" name="sortState" checked={state.sortState === 2} onChange={e => { setState({ ...state, sortState: e.target.checked ? 2 : 1 }); changeProperty("sortState", 2) }} /> <label for="descending">Descending(Z to A)</label><br /> </div> </div> <div class="block"> <div>Add Slicer</div> <br /> <select class="select-list" name="slicerList" id="slicerList" value={state.selectedField} onChange={e => { setState({ ...state, selectedField: e.target.value }) }}> <option value="region">region</option> <option value="country">country</option> <option value="city">city</option> <option value="date">date</option> <option value="amount">amount</option> <option value="id">id</option> </select> <button class="select-button" id="addSlicerBtn" onClick={addSlicer}>Add</button> </div> <div class="block"> <div>Change Current Slicer Style</div> <br /> <div class="slicerStyle"> <select class="select-list" name="slicerStyle" id="slicerStyle" value={state.styleName} onChange={e => { setState({ ...state, styleName: e.target.value }) }}> <option value="light1">light1</option> <option value="light2">light2</option> <option value="light3">light3</option> <option value="light4">light4</option> <option value="light5">light5</option> <option value="light6">light6</option> <option value="dark1">dark1</option> <option value="dark2">dark2</option> <option value="dark3">dark3</option> <option value="dark4">dark4</option> <option value="dark5">dark5</option> <option value="dark6">dark6</option> <option value="other1">other1</option> <option value="other2">other2</option> <option value="custom1">custom1</option> <option value="custom2">custom2</option> </select> <button class="select-button" id="changeStyle" onClick={setStyle}>Change</button> </div> </div> </div> ); }
import * as React from 'react'; import GC from '@mescius/spread-sheets'; import "@mescius/spread-sheets-shapes"; import "@mescius/spread-sheets-slicers"; import "@mescius/spread-sheets-pivot-addon"; import { SpreadSheets } from '@mescius/spread-sheets-react'; import '@mescius/spread-sheets-resources-ko'; GC.Spread.Common.CultureManager.culture("ko-kr"); import './styles.css'; const Component = React.Component; export class App extends Component { constructor(props) { super(props); this.state = { renderChild: false } } render() { return ( <div class="sample-tutorial"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => this.initSpread(spread)}> </SpreadSheets> </div> {this.state.renderChild ? (<div class="options-container"> <PivotTableItemSlicer spread={this.spread} ptName={this.ptName}></PivotTableItemSlicer> </div>) : ""} </div> ); } componentDidMount() { this.setState(() => ({ renderChild: true })) } initSpread(spread) { this.spread = spread; spread.setSheetCount(2); this.initSheets(spread); let pivotLayoutSheet = spread.getSheet(0); this.initPivotTable(pivotLayoutSheet); } initSheets(spread) { spread.suspendPaint(); spread.setSheetCount(2); let sheet = spread.getSheet(1); sheet.name("DataSource"); sheet.setRowCount(650); sheet.setColumnWidth(5, 120); sheet.getCell(-1, 5).formatter("YYYY-mm-DD"); sheet.getRange(-1, 4, 0, 1).formatter("$ #,##0"); sheet.setArray(0, 0, pivotSales); let table = sheet.tables.add('tableSales', 0, 0, 637, 6); table.style(GC.Spread.Sheets.Tables.TableThemes["none"]); let sheet0 = spread.getSheet(0); sheet0.name("PivotLayout"); spread.resumePaint(); } getSource(sheet, tableSource) { sheet.name("DataSource"); sheet.setRowCount(1984); sheet.setColumnWidth(0, 120); sheet.getCell(-1, 0).formatter("YYYY-mm-DD"); sheet.getRange(-1, 4, 0, 2).formatter("$ #,##0"); let table = sheet.tables.add('table', 0, 0, 1984, 6); for (let i = 2; i <= 1984; i++) { sheet.setFormula(i - 1, 5, '=D' + i + '*E' + i) } table.style(GC.Spread.Sheets.Tables.TableThemes["none"]); sheet.setArray(0, 0, tableSource); return table.name(); } initPivotTable(sheet) { sheet.setRowCount(1000); let option = { showRowHeader: true, showColumnHeader: true, bandRows: true, bandColumns: true }; let pivotTable = sheet.pivotTables.add("pivotTable", "tableSales", 1, 0, GC.Spread.Pivot.PivotTableLayoutType.outline, GC.Spread.Pivot.PivotTableThemes.medium8.name(), option); pivotTable.suspendLayout(); pivotTable.add("region", "region", GC.Spread.Pivot.PivotTableFieldType.rowField); pivotTable.add("country", "countrys", GC.Spread.Pivot.PivotTableFieldType.rowField); pivotTable.add("city", "city", GC.Spread.Pivot.PivotTableFieldType.rowField); let groupInfo = { originFieldName: "date", dateGroups: [ { by: GC.Pivot.DateGroupType.quarters } ] }; pivotTable.group(groupInfo); pivotTable.add("amount", "amount", GC.Spread.Pivot.PivotTableFieldType.valueField, GC.Pivot.SubtotalType.sum); pivotTable.options.subtotalsPosition = GC.Spread.Pivot.SubtotalsPosition.none; pivotTable.resumeLayout(); pivotTable.autoFitColumn(); this.ptName = pivotTable.name(); } } class PivotTableItemSlicer extends Component { constructor(props) { super(props); this.state = { columnCount: 0, showHeader: true, showNoDataItems: false, visuallyNoDataItems: true, showNoDataItemsInLast: true, sortState: 1, selectedField: "region", styleName: "" } this.slicerCount = 0; this.activeSlicer = null; this.initCustomThemes(this.props.spread); this.sheet = this.props.spread.getSheet(0); this.initSlicers(); this.bindEvents(); } initCustomThemes(spread) { const theme1 = new GC.Spread.Sheets.Slicers.SlicerStyle(); theme1.fromJSON(GC.Spread.Sheets.Slicers.SlicerStyles.light1().toJSON()); theme1.name('custom1'); theme1.wholeSlicerStyle(new GC.Spread.Sheets.Slicers.SlicerStyleInfo('rgb(225, 245, 254)')); const theme2 = new GC.Spread.Sheets.Slicers.SlicerStyle(); theme2.fromJSON(GC.Spread.Sheets.Slicers.SlicerStyles.other2().toJSON()); theme2.name('custom2'); const wholeSlicerStyle = new GC.Spread.Sheets.Slicers.SlicerStyleInfo(); wholeSlicerStyle.backColor('#e3f2fd'); theme2.wholeSlicerStyle(wholeSlicerStyle); spread.customSlicerThemes.add(theme1); spread.customSlicerThemes.add(theme2); } initSlicers() { let sheet = this.sheet; let ptName = this.props.ptName; let slicer_region = sheet.slicers.add("slicer_region", ptName, "region", GC.Spread.Sheets.Slicers.SlicerStyles.dark2().name(), GC.Spread.Sheets.Slicers.SlicerType.pivotTable); slicer_region.position(new GC.Spread.Sheets.Point(491, 20)); slicer_region.height(210); let slicer_country = sheet.slicers.add("slicer_country", ptName, "country", GC.Spread.Sheets.Slicers.SlicerStyles.light1().name(), GC.Spread.Sheets.Slicers.SlicerType.pivotTable) slicer_country.position(new GC.Spread.Sheets.Point(691, 20)); slicer_country.height(460); slicer_country.showNoDataItems(false); let slicer_city = sheet.slicers.add("slicer_city", ptName, "city", GC.Spread.Sheets.Slicers.SlicerStyles.other2().name(), GC.Spread.Sheets.Slicers.SlicerType.pivotTable); slicer_city.position(new GC.Spread.Sheets.Point(891, 20)); slicer_city.height(320); slicer_city.columnCount(2); } bindEvents() { let self = this; let sheet = this.sheet; sheet.bind(GC.Spread.Sheets.Events.SlicerChanged, function () { let slicers = sheet.slicers.all(); for (let i = 0; i < slicers.length; i++) { if (slicers[i].isSelected()) { self.activeSlicer = slicers[i]; self.updateSlicerInfo(); break; } } }); } updateSlicerInfo() { if (!this.activeSlicer) { return; } let slicer = this.activeSlicer; const slicerStyleName = slicer.style().name().toLowerCase(); const styleName = slicerStyleName.includes('custom') ? slicerStyleName : slicerStyleName.substr(11); this.setState({ columnCount: slicer.columnCount(), showHeader: slicer.showHeader(), showNoDataItems: slicer.showNoDataItems(), visuallyNoDataItems: slicer.visuallyNoDataItems(), showNoDataItemsInLast: slicer.showNoDataItemsInLast(), sortState: slicer.sortState(), styleName: styleName }); } setColumnCount(v) { let numberV = parseInt(v, 10); if (!isNaN(numberV)) { this.setState({ columnCount: numberV }); this.changeProperty("columnCount", numberV); } else { this.setState({ columnCount: null }); } } changeProperty(prop, v) { if (!this.activeSlicer) { return; } if (v !== null && v !== undefined) { this.activeSlicer[prop](v); } } setStyle() { if (!this.activeSlicer) { return; } this.activeSlicer.style(this.state.styleName); } addSlicer() { let sheet = this.sheet; sheet.slicers.add(this.state.selectedField + "_" + this.slicerCount, this.props.ptName, this.state.selectedField, GC.Spread.Sheets.Slicers.SlicerStyles.light1().name(), GC.Spread.Sheets.Slicers.SlicerType.pivotTable); this.slicerCount += 1; } render() { return ( <div class="options-container"> <div class="block slicer-infos"> <div>Current Selected Slicer Info:</div><br /> <div class="slicer-info"> <label>Column Count:</label> <input class="info-input" type="number" id="columnCount" value={this.state.columnCount} onChange={e => { this.setColumnCount(e.target.value) }} /> </div> <div class="slicer-info"> <input type="checkbox" id="showHeader" checked={this.state.showHeader} onChange={e => { this.setState({ showHeader: e.target.checked }); this.changeProperty("showHeader", e.target.checked) }} /> <label for="showHeader">Display Header</label> </div> <div class="slicer-info"> <input type="checkbox" id="showNoDataItems" checked={!this.state.showNoDataItems} onChange={e => { this.setState({ showNoDataItems: !e.target.checked }); this.changeProperty("showNoDataItems", !e.target.checked) }} /> <label for="showNoDataItems">Hide Items With No Data</label> </div> <div class="slicer-info"> <input type="checkbox" id="visuallyNoDataItems" checked={this.state.visuallyNoDataItems} onChange={e => { this.setState({ visuallyNoDataItems: e.target.checked }); this.changeProperty("visuallyNoDataItems", e.target.checked) }} /> <label for="visuallyNoDataItems">Visually Indicate Items With No Data</label> </div> <div class="slicer-info"> <input type="checkbox" id="showNoDataItemsInLast" checked={this.state.showNoDataItemsInLast} onChange={e => { this.setState({ showNoDataItemsInLast: e.target.checked }); this.changeProperty("showNoDataItemsInLast", e.target.checked) }} /> <label for="showNoDataItemsInLast">Show Items With No Data Last</label> </div> <div class="slicer-info"> <p>Sort State</p> <input type="radio" id="ascending" name="sortState" checked={this.state.sortState === 1} onChange={e => { this.setState({ sortState: e.target.checked ? 1 : 2 }); this.changeProperty("sortState", 1) }} /> <label for="ascending">Ascending(A to Z)</label><br /> <input type="radio" id="descending" name="sortState" checked={this.state.sortState === 2} onChange={e => { this.setState({ sortState: e.target.checked ? 2 : 1 }); this.changeProperty("sortState", 2) }} /> <label for="descending">Descending(Z to A)</label><br /> </div> </div> <div class="block"> <div>Add Slicer</div> <br /> <select class="select-list" name="slicerList" id="slicerList" value={this.state.selectedField} onChange={e => { this.setState({ selectedField: e.target.value }) }}> <option value="region">region</option> <option value="country">country</option> <option value="city">city</option> <option value="date">date</option> <option value="amount">amount</option> <option value="id">id</option> </select> <button class="select-button" id="addSlicerBtn" onClick={this.addSlicer.bind(this)}>Add</button> </div> <div class="block"> <div>Change Current Slicer Style</div> <br /> <div class="slicerStyle"> <select class="select-list" name="slicerStyle" id="slicerStyle" value={this.state.styleName} onChange={e => { this.setState({ styleName: e.target.value }) }}> <option value="light1">light1</option> <option value="light2">light2</option> <option value="light3">light3</option> <option value="light4">light4</option> <option value="light5">light5</option> <option value="light6">light6</option> <option value="dark1">dark1</option> <option value="dark2">dark2</option> <option value="dark3">dark3</option> <option value="dark4">dark4</option> <option value="dark5">dark5</option> <option value="dark6">dark6</option> <option value="other1">other1</option> <option value="other2">other2</option> <option value="custom1">custom1</option> <option value="custom2">custom2</option> </select> <button class="select-button" id="changeStyle" onClick={this.setStyle.bind(this)}>Change</button> </div> </div> </div> ); } }
<!doctype html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/ko/react/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/spread/source/data/pivotSales.js" type="text/javascript"></script> <!-- SystemJS --> <script src="$DEMOROOT$/ko/react/node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('$DEMOROOT$/ko/lib/react/license.js').then(function () { System.import('./src/app'); }); </script> </head> <body> <div id="app" style="height: 100%;"></div> </body> </html>
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-spreadsheets { width: calc(100% - 330px); height: 100%; overflow: hidden; float: left; } .options-container { float: right; width: 330px; padding: 12px; height: 100%; box-sizing: border-box; background: #fbfbfb; overflow: auto; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .slicer-info { margin-top: 5px; margin-bottom: 5px; } .block { border: 1px solid gray; padding-left: 5px; padding-top: 10px; padding-bottom: 10px; margin-bottom: 1px; } .select-list { width: 120px; } .select-button { width: 80px; }
(function (global) { System.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true, react: true }, meta: { '*.css': { loader: 'css' } }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, // map tells the System loader where to look for things map: { '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-resources-ko': 'npm:@mescius/spread-sheets-resources-ko/index.js', '@mescius/spread-sheets-shapes': 'npm:@mescius/spread-sheets-shapes/index.js', '@mescius/spread-sheets-slicers': 'npm:@mescius/spread-sheets-slicers/index.js', '@mescius/spread-sheets-pivot-addon': 'npm:@mescius/spread-sheets-pivot-addon/index.js', '@mescius/spread-sheets-react': 'npm:@mescius/spread-sheets-react/index.js', '@grapecity/jsob-test-dependency-package/react-components': 'npm:@grapecity/jsob-test-dependency-package/react-components/index.js', 'react': 'npm:react/umd/react.production.min.js', 'react-dom': 'npm:react-dom/umd/react-dom.production.min.js', 'css': 'npm:systemjs-plugin-css/css.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', 'systemjs-babel-build':'npm:systemjs-plugin-babel/systemjs-babel-browser.js' }, // packages tells the System loader how to load when no filename and/or no extension packages: { src: { defaultExtension: 'jsx' }, "node_modules": { defaultExtension: 'js' }, } }); })(this);