Overview

  • Learn how to enable the zoom feature of the React Scheduler component.

  • Define your own zoom levels (e.g. from years to hours).

  • Zoom quickly using the “range” HTML input element.

  • Add “Zoom In” and “Zoom Out” buttons to zoom incrementally.

To see an introduction on using the React Scheduler component, please read the React Scheduler Component Tutorial. It explains how to add the Scheduler to your React project and how to configure it to meet your requirements.

To learn how to implement a scheduling calendar with a timeline on the Y axis, please see the React Scheduler with a Vertical Timeline tutorial.

License

Licensed for testing and evaluation purposes. Please see the license agreement included in the sample project. You can use the source code of the tutorial if you are a licensed user of DayPilot Pro for JavaScript.

How to configure the timeline in the React Scheduler?

react scheduler how to configure the timeline

You can configure the timeline displayed by the React Scheduler component using the following properties:

  • The scale property sets the Scheduler grid resolution. The Scheduler will use cells with the selected duration. The following values are supported: "Minute", "Hour", "Day", "Week", "Month", "Year". You can also use "CellDuration" scale and specify the cell duration in minutes using cellDuration property. It is also possible to use a manual timeline mode and define the timeline by specifying individual time cells.

  • The timeHeaders property defines the time groups displayed in the X axis header. There can be multiple rows and it lets you show the time for each of the time columns. The default values are derived from the date/time and you can use your own date/time format defined using the format property. You can also customize the time header cells if needed. That way you get full control over the time header cell content (you can either specify text that will be HTML-escaped automatically or use raw HTML). You can also include additional elements (such as icons, buttons, etc.) using active areas. In React, you can also specify custom content as JSX (see the React Scheduler: Rendering JSX in Time Header and Upper-Left Corner tutorial).

  • The timeline appearance is also affected by the cell size. You can set the cell width in pixels using the cellWidth property.

Example React Scheduler configuration:

import React, {Component} from 'react';
import {DayPilot, DayPilotScheduler} from "daypilot-pro-react";

class Scheduler extends Component {

  constructor(props) {
    super(props);

    this.state = {
      scale: "Day",
      cellWidth: 40,
      timeHeaders: [{groupBy: "Year"}, {groupBy: "Month", format: "MMMM"}, {groupBy: "Day", format: "d"}],
      startDate: DayPilot.Date.today().firstDayOfYear(),
      days: DayPilot.Date.today().daysInYear(),
      // ...
    };
  }

  render() {
    var {...config} = this.state;
    return (
      <div>
        <DayPilotScheduler
          {...config}
        />
      </div>
    );
  }
}

export default Scheduler;

How to change the date range visible in the React Scheduler?

You can use startDate and days properties to change the visible date range. You need to apply the new values by changing the config or using the update() method.

It is also possible to use the infinite scrolling Scheduler mode that will shift the visible date range automatically as you approach the end of the current range.

clickNextYear() {
  const next = this.state.startDate.addYears(1);
  this.setState({
    startDate: next,
    days: next.daysInYear()
  });
}

How to change the React Scheduler timeline dynamically?

You can change the Scheduler timeline by adjusting the configuration properties. The Scheduler will display the new timeline after update:

switchToHourScale() {
  this.setState({
    scale: "Hour",
    cellWidth: 40,
    timeHeaders: [{groupBy: "Month"}, {groupBy: "Day", format: "dddd d"}, {groupBy: "Hour"}],
    startDate: DayPilot.Date.today().firstDayOfWeek(),
    days: 7,    
  });
}

How to configure zoom levels in the React Scheduler?

The React Scheduler component includes a built-in support for switching between different zoom levels.

It helps with switching the timeline to a new resolution:

  • You can set the zoom level number in order to switch to the new zoom level.

  • The Scheduler will apply the zoom level properties and calculate the required values from the current view.

  • The scrollbar position will be adjusted automatically to keep the current date at the specified anchor position (left, middle, right).

First, you need to define the zoom levels using zoomLevels property:

import React, {Component} from 'react';
import {DayPilot, DayPilotScheduler} from "daypilot-pro-react";

class Scheduler extends Component {

  constructor(props) {
    super(props);

    this.state = {
      zoomLevels: [
        {
          name: "Days",
          properties: {
            scale: "Day",
            cellWidth: 40,
            timeHeaders: [{groupBy: "Year"}, {groupBy: "Month", format: "MMMM"}, {groupBy: "Day", format: "d"}],
            startDate: args => args.date.firstDayOfYear(),
            days: args => args.date.daysInYear(),
          }
        },
        {
          name: "Half-Days",
          properties: {
            scale: "CellDuration",
            cellDuration: 720,
            cellWidth: 40,
            timeHeaders: [{groupBy: "Month"}, {groupBy: "Day", format: "ddd d"}, {groupBy: "Cell", format: "tt"}],
            startDate: args => args.date.firstDayOfMonth(),
            days: args => args.date.daysInMonth(),
          }
        },
        {
          name: "Hours",
          properties: {
            scale: "Hour",
            cellWidth: 40,
            timeHeaders: [{groupBy: "Month"}, {groupBy: "Day", format: "dddd d"}, {groupBy: "Hour"}],
            startDate: args => args.date.firstDayOfWeek(),
            days: args => 7,
          }
        },
        {
          name: "15-Minute Cells",
          properties: {
            scale: "CellDuration",
            cellDuration: 15,
            cellWidth: 40,
            timeHeaders: [{groupBy: "Day", format: "dddd MMMM d, yyyy"}, {groupBy: "Hour"}, {groupBy: "Cell"}],
            startDate: args => args.date.getDatePart(),
            days: args => 1,
          }
        },
      ],
      // ...
    };
  }

  render() {
    var {...config} = this.state;
    return (
      <div>
        <DayPilotScheduler
          {...config}
        />
      </div>
    );
  }
}

export default Scheduler;

The zoom level object has the following structure:

  • Each zoom level items can contain arbitrary properties at the top level (we use a name property to specify the zoom level name).

  • The properties property specifies the value that will be applied to the Scheduler when switching to this zoom level.

The properties can be either static (e.g. scale: "Hour") or calculated (startDate: args => args.date.firstDayOfWeek()). The calculated properties let you use dynamic values based on the Scheduler state and/or the date at the anchor position (args.date).

How to set the initial zoom level?

You can specify the initial zoom level using zoom property:

constructor(props) {
  super(props);

  this.state = {
    zoom: 0,
    // ...
  };
}

How to set the zoom anchor?

You can specify the zoom anchor (the date/time reference position in the viewport that the will remain the same after switching the timeline to the new zoom level) using zoomLevel property:

constructor(props) {
  super(props);

  this.state = {
    zoomAnchor: "middle",
    // ...
  };
}

How to zoom using “range” HTML input element?

react scheduler how to zoom using the range html input element

You can set the zoom level using a range HTML input control:

<input type="range" min="0" max="3" step="1" value={this.state.zoom} onChange={ev => this.changeZoomLevel()} ref={el => this.zoom = el} />

We need to bind the range element value to the current zoom level (this.state.zoom).

Changing the range element fires onChange event. We will use this event to set the corresponding zoom level:

changeZoomLevel() {
  const value = parseInt(this.zoom.value, 10);
  this.setState({
    zoom: value
  });
}

This is how the “range” HTML input element can be integrated with the Scheduler:

import React, {Component} from 'react';
import {DayPilot, DayPilotScheduler} from "daypilot-pro-react";

class Scheduler extends Component {

  constructor(props) {
    super(props);

    this.state = {
      zoom: 0,
      zoomPosition: "middle",
      zoomLevels: [
        // ...
      ],
    };
  }

  changeZoomLevel() {
    const value = parseInt(this.zoom.value, 10);
    this.setState({
      zoom: value
    });
  }

  render() {
    var {...config} = this.state;
    return (
      <div>
        
        <input type="range" min="0" max="3" step="1" value={this.state.zoom} onChange={ev => this.changeZoomLevel()} ref={el => this.zoom = el} />
        
        <DayPilotScheduler
          {...config}
          ref={component => {
            this.scheduler = component && component.control;
          }}
        />
      </div>
    );
  }
}

export default Scheduler;

How to zoom in?

react scheduler timeline zoom in

The “plus” button JSX:

<button id="zoom-in" onClick={ev => this.timelineZoomIn()}>
  <svg style={{width: "16px", height: "16px"}}><use href={"icons/daypilot.svg#plus-2"} /></svg>
</button>

The timelineZoomIn() method updates the Scheduler zoom level to zoom out:

timelineZoomIn() {
  const current = this.state.zoom;
  const max = this.state.zoomLevels.length - 1;
  const zoom = Math.min(max, current + 1);
  this.setState({
    zoom
  });
}

How to zoom out?

react scheduler timeline zoom out

The “minus” button JSX:

<button id="zoom-out" onClick={ev => this.timelineZoomOut()}>
  <svg style={{width: "16px", height: "16px"}}><use href={"icons/daypilot.svg#minus-2"} /></svg>
</button>

The timelineZoomOut() method updates the Scheduler zoom level to zoom out:

timelineZoomIn() {
  const current = this.state.zoom;
  const max = this.state.zoomLevels.length - 1;
  const zoom = Math.min(max, current + 1);
  this.setState({
    zoom
  });
}