Search results

Virtual Scrolling in JavaScript Schedule control

08 May 2023 / 3 minutes to read

To achieve better performance in the Scheduler when loading a large number of resources and events, we have added virtual scrolling support to load a large set of resources and events instantly as you scroll. You can dynamically load large number of resources and events in the Scheduler by setting true to the allowVirtualScrolling property within the view specific settings. The virtual loading of events is possible in Agenda view, by setting allowVirtualScrolling property to true within the agenda view specific settings.

Source
Preview
index.ts
index.html
Copied to clipboard
import { Schedule, TimelineViews, TimelineMonth, TimelineYear, Resize, DragAndDrop } from '@syncfusion/ej2-schedule';

Schedule.Inject(TimelineViews, TimelineMonth, TimelineYear, Resize, DragAndDrop);

let ownerData: Object[] = generateResourceData(1, 300, 'Resource');
let eventData: Object[] = generateStaticEvents(new Date(2018, 4, 1), 300, 12);
let scheduleObj: Schedule = new Schedule({
    height: '550px', width: '100%',
    currentView: 'TimelineMonth',
    views: [
        { option: 'TimelineMonth', eventTemplate: '#timeline-event-template', allowVirtualScrolling: true },
        { option: 'TimelineYear', orientation: 'Vertical', eventTemplate: '#timeline-event-template', allowVirtualScrolling: true }
    ],
    group: {
        byGroupID: false,
        resources: ['Owners']
    },
    resources: [
        {
            field: 'OwnerId', title: 'Owner',
            name: 'Owners', allowMultiple: true,
            dataSource: ownerData,
            textField: 'Text', idField: 'Id', colorField: 'Color'
        }
    ],
    selectedDate: new Date(2018, 4, 1),
    eventSettings: { dataSource: eventData }
});
scheduleObj.appendTo('#Schedule');

function generateStaticEvents(start: Date, resCount: number, overlapCount: number): Object[] {
    let data: Object[] = [];
    let id: number = 1;
    for (let i: number = 0; i < resCount; i++) {
        let randomCollection: number[] = [];
        let random: number = 0;
        for (let j: number = 0; j < overlapCount; j++) {
            random = Math.floor(Math.random() * (30));
            random = (random === 0) ? 1 : random;
            if (randomCollection.indexOf(random) !== -1 || randomCollection.indexOf(random + 2) !== -1 ||
                randomCollection.indexOf(random - 2) !== -1) {
                random += (Math.max.apply(null, randomCollection) + 10);
            }
            for (let k: number = 1; k <= 2; k++) {
                randomCollection.push(random + k);
            }
            let startDate: Date = new Date(start.getFullYear(), start.getMonth(), random);
            startDate = new Date(startDate.getTime() + (((random % 10) * 10) * (1000 * 60)));
            let endDate: Date = new Date(startDate.getTime() + ((1440 + 30) * (1000 * 60)));
            data.push({
                Id: id,
                Subject: 'Event #' + id,
                StartTime: startDate,
                EndTime: endDate,
                IsAllDay: (id % 10) ? false : true,
                OwnerId: i + 1
            });
            id++;
        }
    }
    return data;
}

function generateResourceData(startId: number, endId: number, text: string): Object[] {
    let data: { [key: string]: Object }[] = [];
    let colors: string[] = [
        '#ff8787', '#9775fa', '#748ffc', '#3bc9db', '#69db7c',
        '#fdd835', '#748ffc', '#9775fa', '#df5286', '#7fa900',
        '#fec200', '#5978ee', '#00bdae', '#ea80fc'
    ];
    for (let a: number = startId; a <= endId; a++) {
        let n: number = Math.floor(Math.random() * colors.length);
        data.push({
            Id: a,
            Text: text + ' ' + a,
            Color: colors[n]
        });
    }
    return data;
}
Copied to clipboard
<!DOCTYPE html>
<html lang="en">

<head>
            
    <title>Schedule Typescript Component</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="description" content="Typescript Schedule Control" />
    <meta name="author" content="Syncfusion" />
    <link href="index.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-base/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-buttons/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-calendars/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-dropdowns/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-inputs/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-navigations/styles/material.css" rel="stylesheet" />
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-popups/styles/material.css" rel="stylesheet" />    
    <link href="//cdn.syncfusion.com/ej2/21.2.3/ej2-schedule/styles/material.css" rel="stylesheet" />
    <script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js" type="text/javascript"></script>
    <script src="systemjs.config.js" type="text/javascript"></script>
    <style>
        .e-schedule .e-timeline-month-view .template-wrap .subject {
            padding: 10px 25px;
        }
    
        .e-schedule .template-wrap {
            width: 100%;
        }

        .e-schedule .e-timeline-year-view .template-wrap .subject {
            padding: 1px 25px;
        }

        .e-schedule .e-more-event-popup .template-wrap .subject {
            padding: 0px 25px;
        }
    
        .e-schedule .e-timeline-month-view .e-resource-left-td {
            width: 150px;
        }
    </style>
    <script id="timeline-event-template" type="text/x-template">
        <div class='template-wrap' style='background:${PrimaryColor}'>
            <div class="subject" style='background:${SecondaryColor};'>${Subject}</div>
        </div>
    </script>
</head>
<body>
    <div id='loader'>LOADING....</div>
        <div id='container'>
                <div id="Schedule"></div>
        </div>
</body>
</html>

Note: For now, the virtual loading of resources and events is not supported in MonthAgenda, Year and TimelineYear (Horizontal Orientation) views.

You can refer to our JavaScript Scheduler feature tour page for its groundbreaking feature representations. You can also explore our JavaScript Scheduler example to knows how to present and manipulate data.

See Also