javascript calendar zoom

The calendar component supports switching among defined zoom levels. The zoom feature lets you magnify the calendar grid or apply a different time scale. Zooming is helpful when there are many events of short length which are not easy to read in the default view.

Available since version 2023.1.5547.

Demo

You can test the zoom feature in a live demo:

Defining Zoom Levels

The calendar zoom levels can be defined using zoomLevels property. Each zoom level specifies properties to be applied (properties) and an optional id. You can specify additional properties at the top level (such as name in this case) - they are ignored by the calendar component.

zoomLevels: [
    {
        name: "30-minute cells",
        id: "30min",
        properties: {
            cellDuration: 30,
            cellHeight: 30,
        },
    },
    {
        name: "15-minute cells",
        id: "15min",
        properties:
        {
            cellDuration: 15,
            cellHeight: 20,
        }
    },
    {
        name: "10-minute cells",
        id: "10min",
        properties :{
            cellDuration: 10,
            cellHeight: 20,
        }
    },
]

The properties can be static values like in the previous example. You can also use calculated values by using a function that returns the desired value:

{
    name: "30-minute cells",
    id: "30min",
    properties: {
        cellDuration: (args) => { return 30; },
        cellHeight: 30,
    },
},

Setting the initial zoom level

By default, no zoom level is applied and the current zoom level (zoom.active) is set to -1.

You can set the initial zoom level using the zoom property in the config:

{
  viewType: "Week",
  zoomLevels: [
      {
          name: "30-minute cells",
          id: "30min",
          properties: {
              cellDuration: 30,
              cellHeight: 30,
          },
      },

      // ...

  ],
  zoom: 0
}

Changing the zoom level dynamically

To change the zoom level, you can use the zoom.setActive() method.

This method accepts the zoom level number (zero-based index) as a parameter:

calendar.zoom.setActive(0);

You can also use a zoom level id:

calendar.zoom.setActive("30min");

JavaScript Calendar

This JavaScript Calendar example displays a weekly calendar with a basic configuration. Above the Calendar component, there is a slider control (created using <input type="range"> HTML element) that lets you change the zoom level.

The zoom levels are defined using the zoomLevels property of the options parameter that is passed to the DayPilot.Calendar constructor.

To change the zoom level, you can use dp.zoom.setActive(0) as in this example or dp.update({zoom:0}).

<div class="note">Zoom Level: <input type="range" min="0" max="2" step="1" id="zoomLevel" value="0"/> <span
    id="label">0</span></div>

<div id="dp"></div>

<script>

    const dp = new DayPilot.Calendar("dp", {
        viewType: "Week",
        zoomLevels: [
            {
                name: "30min",
                properties: {
                    cellDuration: 30,
                    cellHeight: 30,
                },

            },
            {
                name: "15min",
                properties:
                {
                    cellDuration: 15,
                    cellHeight: 20,
                }
            },
            {
                name: "10min",
                properties :{
                    cellDuration: 10,
                    cellHeight: 20,
                }
            },
        ]
    });
    dp.init();

    const app = {
        init() {
            document.querySelector("#zoomLevel").addEventListener("input", function(ev) {
                var level = parseInt(this.value);
                app.applyLevel(level);
            });

            app.applyLevel(0)
        },
        applyLevel(level) {
            document.querySelector("#label").innerText = dp.zoomLevels[level].name;
            dp.zoom.setActive(level);
        }
    };
    app.init();


</script>

Angular Calendar

The following example shows how to enable and configure zoom in the Angular Calendar component.

The available zoom levels are defined in the zoomLevels array of the calendarConfig object, which specifies the duration and height of the calendar cells for each zoom level.

To change the current zoom level, simply change the value of this.calendarConfig.zoom and Angular will update the calendar automatically.

import {Component, ViewChild} from "@angular/core";
import {DayPilot, DayPilotCalendarComponent} from "daypilot-pro-angular";

@Component({
  selector: "app-zoomable-calendar",
  template: `
    <div>
      <div class="zoom-level-selector">
        <label for="zoom-level">Zoom level:</label>
        <input
          type="range"
          id="zoom-level"
          min="0"
          [max]="maxZoomLevel"
          step="1"
          [value]="calendarConfig.zoom"
          (input)="zoomChange($event)"
        />
      </div>
      <div>
        <daypilot-calendar
          [config]="calendarConfig"
          #calendarRef
        ></daypilot-calendar>
      </div>
    </div>
  `,
})
export class ZoomableCalendarComponent {
  @ViewChild("calendarRef")
  calendarRef!: DayPilotCalendarComponent;

  calendarConfig: DayPilot.CalendarConfig = {
    viewType: "Week",
    zoomLevels: [
      {
        name: "30-minute cells",
        id: "30min",
        properties: {
          cellDuration: 30,
          cellHeight: 30,
        },
      },
      {
        name: "15-minute cells",
        id: "15min",
        properties: {
          cellDuration: 15,
          cellHeight: 20,
        },
      },
      {
        name: "10-minute cells",
        id: "10min",
        properties: {
          cellDuration: 10,
          cellHeight: 20,
        },
      },
    ],
    zoom: 0,
    // ...
  };

  get maxZoomLevel(): number {
    // @ts-ignore
    return this.calendarConfig.zoomLevels.length - 1;
  }

  zoomChange(event: any) {
    const targetZoomLevelIndex = parseInt(event.target.value);
    this.calendarConfig.zoom = targetZoomLevelIndex;
  }
}

React Calendar

In the React Calendar component, use the zoomLevels and zoom properties of the config object to enable zooming.

The zoomLevels property holds an array with defined zoom levels and the zoom property sets the active zoom level.

import React, {useRef, useState} from "react";
import {DayPilotCalendar} from "daypilot-pro-react";

const zoomLevels = [
  {
    name: "30-minute cells",
    id: "30min",
    properties: {
      cellDuration: 30,
      cellHeight: 30,
    },
  },
  {
    name: "15-minute cells",
    id: "15min",
    properties: {
      cellDuration: 15,
      cellHeight: 20,
    },
  },
  {
    name: "10-minute cells",
    id: "10min",
    properties: {
      cellDuration: 10,
      cellHeight: 20,
    },
  },
];

const ZoomableCalendar = () => {
  const calendarRef = useRef(null);
  const [zoom, setZoom] = useState(0);
  const [calendarConfig, setCalendarConfig] = useState({
    zoomLevels,
    viewType: "Week",
    // ...
  });

  const zoomChange = (e) => {
    const targetZoomLevelIndex = parseInt(e.target.value);
    setZoom(targetZoomLevelIndex);
  };

  return (
    <div>
      <div className="zoom-level-selector">
        <label htmlFor="zoom-level">Zoom level: </label>
        <input
          type="range"
          id="zoom-level"
          min="0"
          max={zoomLevels.length - 1}
          step="1"
          defaultValue="0"
          onChange={zoomChange}
        />
      </div>
      <div>
        <DayPilotCalendar {...calendarConfig} zoom={zoom} ref={calendarRef}/>
      </div>
    </div>
  );
};

export default ZoomableCalendar;

Vue Calendar

The following Vue example configures zoom for the the Vue Calendar component.

There are 3 zoom levels, defined using the zoomLevels property of the calendarConfig object. The default zoom level is set to the first item (index 0) using the zoom property.

To allow changes the zoom level, there is a slider displayed above the calendar component. When the slider position changes, the component handles the @input event and updates the zoom property of the config. This updates the Vue calendar to display the new zoom level.

<template>
  <div>
    <div class="zoom-level-selector">
      <label for="zoom-level">Zoom level:</label>
      <input
          type="range"
          id="zoom-level"
          min="0"
          :max="calendarConfig.zoomLevels.length - 1"
          step="1"
          :value="calendarConfig.zoom"
          @input="zoomChange"
      />
    </div>
    <div>
      <DayPilotCalendar id="dp" :config="calendarConfig" ref="calendarRef" />
    </div>
  </div>
</template>

<script>
import { ref } from "vue";
import { DayPilotCalendar } from "daypilot-pro-vue";

export default {
  name: "ZoomableCalendar",
  components: { DayPilotCalendar },
  setup() {
    const calendarRef = ref(null);
    const calendarConfig = ref({
      zoomLevels: [
        {
          name: "30-minute cells",
          id: "30min",
          properties: {
            cellDuration: 30,
            cellHeight: 30,
          },
        },
        {
          name: "15-minute cells",
          id: "15min",
          properties: {
            cellDuration: 15,
            cellHeight: 20,
          },
        },
        {
          name: "10-minute cells",
          id: "10min",
          properties: {
            cellDuration: 10,
            cellHeight: 20,
          },
        },
      ],
      zoom: 0,
      viewType: "Week",
      // ...
    });

    const zoomChange = (event) => {
      const targetZoomLevelIndex = parseInt(event.target.value);
      calendarConfig.value.zoom = targetZoomLevelIndex;
    };

    return {
      calendarRef,
      calendarConfig,
      zoomChange,
    };
  },
};
</script>