Zoom

With SpreadJS you can zoom the worksheet view in and out for varying levels of detail. In addition, the zoom level can be controlled using ViewZooming and ViewZoomed events.

Zoom operations Ctrl + Mousewheel Status bar zoom indicator Double fingers operation, touchable only Use API sheet.zoom(zoomFactor) AllowUserZoom We provide a spread option called allowUserZoom to control whether sheet viewport could be zoomed: Get or set zoom factor through API ViewZooming / ViewZoomed Events In order to intervene in the zooming process on different worksheets / spreads instance, we provide two events: GC.Spread.Sheets.Events.ViewZooming The available arguments in its handler function: sheet: The sheet that triggered the event. sheetName: The sheet's name. newZoomFactor: The new zoom factor, user could make some change to intervene the real zoom action. oldZoomFactor: The old zoom factor. cancel: A value that indicates whether the operation should be canceled. GC.Spread.Sheets.Events.ViewZoomed The available arguments in its handler function: sheet: The sheet that triggered the event. sheetName: The sheet's name. newZoomFactor: The new zoom factor, user could make some change to intervene the real zoom action. oldZoomFactor: The old zoom factor.
import * as React from 'react'; import { createRoot } from 'react-dom/client'; import './styles.css'; import { AppFunc } from './app-func'; import { App } from './app-class'; // 1. Functional Component sample createRoot(document.getElementById('app')).render(<AppFunc />); // 2. Class Component sample // createRoot(document.getElementById('app')).render(<App />);
import * as React from 'react'; import { SpreadSheets, Worksheet } from '@mescius/spread-sheets-react'; import GC from '@mescius/spread-sheets'; import './styles.css'; const useState = React.useState; export function AppFunc() { const [spread, setSpread] = useState(null); const [state, setState] = useState({ useLimit: false, maxZoom: 4, minZoom: 0.25, zoomFactor: 1 }); const initSpread = (spread) => { setSpread(spread); initStatusBar(spread); initEvents(spread); } const setZoomFactor = (value) => { var sheet = spread.getActiveSheet(); if (sheet) { var zoomFactor = parseFloat(value); var maxZoom = parseFloat(state.maxZoom), minZoom = parseFloat(state.minZoom); if (state.useLimit) { if (zoomFactor >= maxZoom) { zoomFactor = maxZoom; } if (zoomFactor <= minZoom) { zoomFactor = minZoom; } } sheet.zoom(zoomFactor); //setState(state=>({...state,...{ zoomFactor: zoomFactor }})); setZoomFactorState(zoomFactor); } } const setZoomFactorState = (zoomFactor) => { setState(state => ({ ...state, ...{ zoomFactor: zoomFactor } })); } const setUseLimit = (value) => { setState(state => ({ ...state, ...{ useLimit: value } })); } const setMaxZoom = (value) => { setState(state => ({ ...state, ...{ maxZoom: value } })); } const setMinZoom = (value) => { setState(state => ({ ...state, ...{ minZoom: value } })); } const initStatusBar = (spread) => { const statusBarDOM = document.getElementById('statusBar'); const statusBar = new GC.Spread.Sheets.StatusBar.StatusBar(statusBarDOM); statusBar.bind(spread); } const initEvents = (spread) => { spread.bind(GC.Spread.Sheets.Events.ViewZooming, (e, args) => { var maxZoom = parseFloat(state.maxZoom), minZoom = parseFloat(state.minZoom); if (state.useLimit) { if (args.newZoomFactor >= maxZoom) { args.newZoomFactor = maxZoom; } if (args.newZoomFactor <= minZoom) { args.newZoomFactor = minZoom; } } //setState({ zoomFactor: args.newZoomFactor }); setZoomFactorState(args.newZoomFactor); }); } return ( <div class="sample-tutorial"> <div class="spread-container"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => initSpread(spread)}> <Worksheet></Worksheet> </SpreadSheets> </div> <div id="statusBar"></div> </div> <PanelFunc setting={state} setZoomFactor={(value) => setZoomFactor(value)} setUseLimit={(value) => setUseLimit(value)} setMaxZoom={(value) => setMaxZoom(value)} setMinZoom={(value) => setMinZoom(value)} ></PanelFunc> </div> ); } function PanelFunc(props) { return ( <div className="options-container"> <div className="options-row"> <label>Slide to zoom active sheet:</label> <div class="input"> <label class="inline-label">0.25</label> <input id="zoomFactor" type="range" name="points" min="0.25" max="4" step="0.01" value={props.setting.zoomFactor} onInput={(e) => { props.setZoomFactor(parseFloat(e.target.value)) }} /> <label class="inline-label">4</label> </div> </div> <div class="option-row"> <input id="useLimit" type="checkbox" checked={props.setting.useLimit} onChange={(e) => { props.setUseLimit(e.target.checked); }} /> <label for="useLimit" class="inline-label">Limit the zoom factor</label> </div> <div class="option-row" style={{ display: props.setting.useLimit ? 'block' : 'none' }}> <label for="maxZoom">The max zoom factor:</label> <input id="maxZoom" type="number" min="0.25" max="4" step="0.1" value={props.setting.maxZoom} onChange={(e) => props.setMaxZoom(parseFloat(e.target.value))} /> </div> <div class="option-row" style={{ display: props.setting.useLimit ? 'block' : 'none' }}> <label for="minZoom">The min zoom factor:</label> <input id="minZoom" type="number" min="0.25" max="4" step="0.1" value={props.setting.minZoom} onChange={(e) => props.setMinZoom(parseFloat(e.target.value))} /> </div> </div> ); }
import * as React from 'react'; import { SpreadSheets, Worksheet } from '@mescius/spread-sheets-react'; import GC from '@mescius/spread-sheets'; import './styles.css'; const Component = React.Component, useState = React.useState; export class App extends Component { constructor(props) { super(props); this.spread = null; this.dataSource = dataSource; this.autoGenerateColumns = false; this.state = { useLimit: false, maxZoom: 4, minZoom: 0.25, zoomFactor: 1 }; } render() { return ( <div class="sample-tutorial"> <div class="spread-container"> <div class="sample-spreadsheets"> <SpreadSheets workbookInitialized={spread => this.initSpread(spread)}> <Worksheet></Worksheet> </SpreadSheets> </div> <div id="statusBar"></div> </div> <Panel setting={this.state} setZoomFactor={(value) => this.setZoomFactor(value)} setUseLimit={(value) => this.setUseLimit(value)} setMaxZoom={(value) => this.setMaxZoom(value)} setMinZoom={(value) => this.setMinZoom(value)} ></Panel> </div> ); } initSpread(spread) { this.spread = spread; this.initStatusBar(); this.initEvents(); } setZoomFactor(value) { let spread = this.spread; var sheet = spread.getActiveSheet(); if (sheet) { var zoomFactor = parseFloat(value); var maxZoom = parseFloat(this.state.maxZoom), minZoom = parseFloat(this.state.minZoom); if (this.state.useLimit) { if (zoomFactor >= maxZoom) { zoomFactor = maxZoom; } if (zoomFactor <= minZoom) { zoomFactor = minZoom; } } sheet.zoom(zoomFactor); this.setState({ zoomFactor: zoomFactor }); } } setUseLimit(value) { this.setState({ useLimit: value }); } setMaxZoom(value) { this.setState({ maxZoom: value }); } setMinZoom(value) { this.setState({ minZoom: value }); } initStatusBar() { var statusBarDOM = document.getElementById('statusBar'); var statusBar = new GC.Spread.Sheets.StatusBar.StatusBar(statusBarDOM); statusBar.bind(this.spread); } initEvents() { this.spread.bind(GC.Spread.Sheets.Events.ViewZooming, (e, args) => { var maxZoom = parseFloat(this.state.maxZoom), minZoom = parseFloat(this.state.minZoom); if (this.state.useLimit) { if (args.newZoomFactor >= maxZoom) { args.newZoomFactor = maxZoom; } if (args.newZoomFactor <= minZoom) { args.newZoomFactor = minZoom; } } this.setState({ zoomFactor: args.newZoomFactor }); }); } } class Panel extends Component { constructor(props) { super(props); } render() { return ( <div className="options-container"> <div className="options-row"> <label>Slide to zoom active sheet:</label> <div class="input"> <label class="inline-label">0.25</label> <input id="zoomFactor" type="range" name="points" min="0.25" max="4" step="0.01" value={this.props.setting.zoomFactor} onInput={(e) => { this.props.setZoomFactor(parseFloat(e.target.value)) }} /> <label class="inline-label">4</label> </div> </div> <div class="option-row"> <input id="useLimit" type="checkbox" checked={this.props.setting.useLimit} onChange={(e) => { this.props.setUseLimit(e.target.checked); }} /> <label for="useLimit" class="inline-label">Limit the zoom factor</label> </div> <div class="option-row" style={{ display: this.props.setting.useLimit ? 'block' : 'none' }}> <label for="maxZoom">The max zoom factor:</label> <input id="maxZoom" type="number" min="0.25" max="4" step="0.1" value={this.props.setting.maxZoom} onChange={(e) => { this.props.setMaxZoom(parseFloat(e.target.value)); }} /> </div> <div class="option-row" style={{ display: this.props.setting.useLimit ? 'block' : 'none' }}> <label for="minZoom">The min zoom factor:</label> <input id="minZoom" type="number" min="0.25" max="4" step="0.1" value={this.props.setting.minZoom} onChange={(e) => { this.props.setMinZoom(parseFloat(e.target.value)); }} /> </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$/en/react/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <script src="$DEMOROOT$/spread/source/data/data.js" type="text/javascript"></script> <!-- SystemJS --> <script src="$DEMOROOT$/en/react/node_modules/systemjs/dist/system.src.js"></script> <script src="systemjs.config.js"></script> <script> System.import('$DEMOROOT$/en/lib/react/license.js').then(function () { System.import('./src/app'); }); </script> </head> <body> <div id="app"></div> </body> </html>
.sample-tutorial { position: relative; height: 100%; overflow: hidden; } .spread-container { width: calc(100% - 280px); height: 100%; overflow: hidden; float: left; } .sample-spreadsheets { width: 100%; height: calc(100% - 30px); } #statusBar { width: 100%; height: 30px; } .inline-label { display: inline-block; } .options-container { float: right; width: 280px; padding: 12px; height: 100%; box-sizing: border-box; background: #fbfbfb; overflow: auto; } .option-row { font-size: 14px; padding: 5px; margin-top: 10px; } label { display: block; margin-bottom: 6px; } input[type=button] { margin-top: 6px; display: block; padding: 4px 6px; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .hide { display: none !important; } .inputbox input { display: inline-block; } #app { height: 100%; }
(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-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/cjs/react.production.js', 'react-dom': 'npm:react-dom/cjs/react-dom.production.js', 'react-dom/client': 'npm:react-dom/cjs/react-dom-client.production.js', 'scheduler': 'npm:scheduler/cjs/scheduler.production.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);