Zoom

The GanttSheet chart area can be zoomed in or out to show more or less of the chart.

Description
app.vue
index.html
Copy to CodeMine

Zoom Factor

The zoom factor is a number value that indicates the zoom factor for the timescale. To change it, call the zoom functions of the timescale.

var timescale = ganttsheet.project.timescale;
console.log(timescale.zoomFactor);

Zoom In/Out

You can zoom in/out on the timescale:

var timescale = ganttsheet.project.timescale;
timescale.zoomIn();
timescale.zoomOut();

Zoom Auto

You can also zoom the timescale to a suitable factor according to the labels of ticks on each tiers automatically.

var timescale = ganttsheet.project.timescale;
timescale.zoomAuto();

Zoom To

You can zoom in or out on the timescale to a specific factor.

var timescale = ganttsheet.project.timescale;
var zoomFactor = 2;
timescale.zoomTo(zoomFactor);

The following code zooms the timescale to display the target date range in the viewport. Note that the timescale will adjust to the nearest ticks.

var timescale = ganttsheet.project.timescale;
var startDate = new Date(2022, 1, 5);
var endDate = new Date(2023, 1, 5);
timescale.zoomToRange(startDate, endDate);

Adjust Tier Unit

A boolean value indicates whether to adjust the units of tiers to a suitable value according to the zoom factor or not. This is true by default in the API:

  • timescale.zoomIn(adjustTierUnit);
  • timescale.zoomOut(adjustTierUnit);
  • timescale.zoomTo(zoomFactor, adjustTierUnit);
  • timescale.zoomToRange(startDate, endDate, adjustTierUnit);
Zoom Factor The zoom factor is a number value that indicates the zoom factor for the timescale. To change it, call the zoom functions of the timescale. Zoom In/Out You can zoom in/out on the timescale: Zoom Auto You can also zoom the timescale to a suitable factor according to the labels of ticks on each tiers automatically. Zoom To You can zoom in or out on the timescale to a specific factor. The following code zooms the timescale to display the target date range in the viewport. Note that the timescale will adjust to the nearest ticks. Adjust Tier Unit A boolean value indicates whether to adjust the units of tiers to a suitable value according to the zoom factor or not. This is true by default in the API: timescale.zoomIn(adjustTierUnit); timescale.zoomOut(adjustTierUnit); timescale.zoomTo(zoomFactor, adjustTierUnit); timescale.zoomToRange(startDate, endDate, adjustTierUnit);
<template> <div id="split-view" class="sample-tutorial"> <gc-spread-sheets class="sample-spreadsheets split-content" @workbookInitialized="initSpread"> </gc-spread-sheets> <div class="options-container split-panel"> <div class="option-row option-title">Zoom the ganttsheet chart area.</div> <div class="option-block"> <div class="option-row"> <label class="option-checkbox" id="adjust-tier-unit" v-bind:class="{ active: tierUnit }" @click="changeTierUnit">Adjust Tier Unit</label> <div class="option-info"> * checkbox toggle whether adjust tier unit or not when zoom. It affects the result of zoom in, zoom out, zoom to and zoom to range. </div> </div> </div> <div class="option-block"> <div class="option-row"> <input type="button" id="zoom-auto" class="option-button" value="Zoom Auto" @click="zoomAuto($event)" /> </div> <div class="option-row"> <input type="button" id="zoom-in" class="option-button" value="Zoom In" @click="zoomIn($event)" /> </div> <div class="option-row"> <input type="button" id="zoom-out" class="option-button" value="Zoom Out" @click="zoomOut($event)" /> </div> </div> <div class="option-block"> <div class="option-row input-box"> <label for="zoom-factor">Zoom Factor</label> <input type="text" id="zoom-factor" v-model="zoomFactor" /> <div class="option-info valid">* valid value: number</div> </div> <div class="option-row"> <input type="button" id="zoom-to" class="option-button" value="Zoom To" @click="zoomTo($event)" /> </div> <div class="option-row selection-box"> <label for="zoom-to-type">Demo Range</label> <select id="zoom-to-type" v-model="zoomToType"> <option value="0">Selected Task</option> <option value="1">Entire Project</option> </select> </div> <div class="option-row"> <input type="button" id="zoom-to-range" class="option-button" value="Zoom To Range" @click="zoomToRange($event)" /> </div> </div> </div> </div> </template> <script setup> import GC from "@mescius/spread-sheets"; import { ref } from "vue"; import "@mescius/spread-sheets-tablesheet"; import "@mescius/spread-sheets-ganttsheet"; import "@mescius/spread-sheets-vue"; const spreadRef = ref(null); let myTable = null; let ganttSheet = null; let spread = null; const tierUnit = ref(true); const zoomFactor = ref("1"); const zoomToType = ref("0"); function initSpread(spread) { spread.suspendPaint(); spread.clearSheets(); initDataSource(spread); initGanttSheet(spread); spread.resumePaint(); initSplitView(spread); }; function initDataSource(spread) { var tableName = "Gantt_Id"; var baseApiUrl = getBaseApiUrl(); var apiUrl = baseApiUrl + "/" + tableName; var dataManager = spread.dataManager(); myTable = dataManager.addTable("myTable", { batch: true, remote: { read: { url: apiUrl, }, }, schema: { hierarchy: { type: "Parent", column: "parentId", }, columns: { id: { isPrimaryKey: true }, taskNumber: { dataType: "rowOrder" }, }, }, }); }; function initGanttSheet(spread) { ganttSheet = spread.addSheetTab( 0, "GanttSheet", GC.Spread.Sheets.SheetType.ganttSheet ); var view = myTable.addView("ganttView", [ { value: "taskNumber", caption: "NO.", width: 60 }, { value: "name", caption: "Task Name", width: 200 }, { value: "duration", caption: "Duration", width: 90 }, { value: "predecessors", caption: "Predecessors", width: 120 }, ]); view .fetch() .then(function () { ganttSheet.bindGanttView(view); }) .then(function () { ganttSheet.project.timescale.zoomOut(); }); }; function changeTierUnit() { tierUnit.value = !tierUnit.value; }; function zoomAuto() { ganttSheet.project.timescale.zoomAuto(); syncPanel(ganttSheet); }; function zoomIn() { ganttSheet.project.timescale.zoomIn(tierUnit.value); syncPanel(ganttSheet); }; function zoomOut() { ganttSheet.project.timescale.zoomOut(tierUnit.value); syncPanel(ganttSheet); }; function zoomTo() { let factor = Number(zoomFactor.value); if (!isNaN(factor)) { ganttSheet.project.timescale.zoomTo(factor, tierUnit.value); syncPanel(ganttSheet); } }; function zoomToRange() { let project = ganttSheet.project; if (zoomToType.value === "0") { let task = ganttSheet.getActiveTask(); if (task && task.finish && task.start) { project.timescale.zoomToRange(task.start, task.finish); } } else if (zoomToType.value === "1") { let startDate = Math.min.apply( null, project.tasks .filter(function (t) { return t.start; }) .map(function (t) { return t.start.valueOf(); }) ); let finishDate = Math.max.apply( null, project.tasks .filter(function (t) { return t.finish; }) .map(function (t) { return t.finish.valueOf(); }) ); project.timescale.zoomToRange( new Date(startDate), new Date(finishDate) ); } syncPanel(ganttSheet); }; function syncPanel(ganttSheet) { zoomFactor.value = ganttSheet.project.timescale.zoomFactor; }; function initSplitView(spread) { var host = document.getElementById("split-view"); var content = host.getElementsByClassName("split-content")[0]; var panel = host.getElementsByClassName("split-panel")[0]; new SplitView({ host: host, content: content, panel: panel, refreshContent: function () { spread.refresh(); }, }); } function getBaseApiUrl() { return ( window.location.href.match(/http.+spreadjs\/demos\//)[0] + "server/api" ); } </script> <style scoped> #app { height: 100%; } .sample-tutorial { position: relative; height: 100%; overflow: hidden; } .sample-spreadsheets { width: 100%; height: 100%; overflow: hidden; float: left; } body { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } .option-block { background: #fff; padding: 8px; margin: 12px 0; border-radius: 4px; border: 1px dashed #82bc00; box-shadow: 0px 0 6px 0 rgba(0, 0, 0, 0.1); } .option-block.toggle { border: 1px dotted #f7a711; } .option-row { font-size: 14px; box-sizing: border-box; padding: 4px 0; } .option-title { font-weight: bold; color: #656565; } .option-info { font-size: 12px; color: #919191; margin-top: 6px; font-weight: normal; } .option-info.valid { color: #82bc00; } .option-info.toggle { color: #f7a711; } .option-button { width: 100%; padding: 0; line-height: 20px; background: #82bc00; color: #fff; transition: 0.3s; cursor: pointer; outline: none; border-radius: 4px; box-sizing: border-box; box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3); border: none; } .option-button:hover { background: #82bc00; color: #fff; box-shadow: 0 3px 8px 0 rgba(0, 0, 0, 0.4); } .option-checkbox { background: #fff; border: 1px dashed #f7a711; color: #f7a711; padding: 2px 4px; transition: 0.3s; box-sizing: border-box; cursor: pointer; } .option-checkbox.active { color: #fff; background: #f7a711; box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3); border-radius: 4px; } .selection-box { position: relative; } .selection-box>select { text-align: left; width: 100%; height: 20px; padding: 0; line-height: 20px; background: transparent; border: none; border-bottom: 2px solid #656565; color: #656565; transition: 0.3s; cursor: pointer; outline: none; box-sizing: border-box; } .selection-box>select>option { background: white; } .selection-box>select:focus { border-bottom: 2px solid #82bc00; color: #82bc00; box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.3); } .selection-box>label { position: absolute; cursor: pointer; font-size: 12px; color: #fff; background: #656565; padding: 0 4px; right: 0; top: 6px; box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3); } .input-box { position: relative; } .input-box>input[type=text] { width: 100%; background: transparent; border: none; color: #656565; border-bottom: 2px solid #656565; outline: none; box-sizing: border-box; transition: 0.3s; } .input-box>input[type=text]:focus { color: #82bc00; border-bottom: 2px solid #82bc00; } .input-box>label { cursor: pointer; position: absolute; right: 0; top: 5px; font-size: 12px; color: #fff; background: #656565; padding: 0 4px; box-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.3); } </style>
<!DOCTYPE html> <html style="height:100%;font-size:14px;"> <head> <meta charset="utf-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <title>SpreadJS VUE</title> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/en/vue3/node_modules/@mescius/spread-sheets/styles/gc.spread.sheets.excel2013white.css"> <link rel="stylesheet" type="text/css" href="$DEMOROOT$/spread/source/splitView/splitView.css"> <script src="$DEMOROOT$/en/vue3/node_modules/systemjs/dist/system.src.js"></script> <script src="./systemjs.config.js"></script> <script src="./compiler.js" type="module"></script> <script src="$DEMOROOT$/spread/source/splitView/SplitView.js"></script> <script> var System = SystemJS; System.import("./src/app.js"); System.import('$DEMOROOT$/en/lib/vue3/license.js'); </script> </head> <body> <div id="app"></div> </body> </html>
(function (global) { SystemJS.config({ transpiler: 'plugin-babel', babelOptions: { es2015: true }, paths: { // paths serve as alias 'npm:': 'node_modules/' }, packageConfigPaths: [ './node_modules/*/package.json', "./node_modules/@mescius/*/package.json", "./node_modules/@babel/*/package.json", "./node_modules/@vue/*/package.json" ], map: { 'vue': "npm:vue/dist/vue.esm-browser.js", 'tiny-emitter': 'npm:tiny-emitter/index.js', 'plugin-babel': 'npm:systemjs-plugin-babel/plugin-babel.js', "systemjs-babel-build": "npm:systemjs-plugin-babel/systemjs-babel-browser.js", '@mescius/spread-sheets': 'npm:@mescius/spread-sheets/index.js', '@mescius/spread-sheets-vue': 'npm:@mescius/spread-sheets-vue/index.js', '@mescius/spread-sheets-tablesheet': 'npm:@mescius/spread-sheets-tablesheet/index.js', '@mescius/spread-sheets-ganttsheet': 'npm:@mescius/spread-sheets-ganttsheet/index.js' }, meta: { '*.css': { loader: 'systemjs-plugin-css' }, '*.vue': { loader: "../plugin-vue/index.js" } } }); })(this);