Virtual scrolling in React Schedule component
27 Jan 202317 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.
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import { ScheduleComponent, ViewsDirective, ViewDirective, ResourcesDirective, ResourceDirective, TimelineMonth, TimelineYear, Resize, DragAndDrop, Inject } from '@syncfusion/ej2-react-schedule';
const App = () => {
const generateStaticEvents = (start, resCount, overlapCount) => {
let data = [];
let id = 1;
for (let i = 0; i < resCount; i++) {
let randomCollection = [];
let random = 0;
for (let j = 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 = 1; k <= 2; k++) {
randomCollection.push(random + k);
}
let startDate = new Date(start.getFullYear(), start.getMonth(), random);
startDate = new Date(startDate.getTime() + (((random % 10) * 10) * (1000 * 60)));
let endDate = new Date(startDate.getTime() + ((1440 + 30) * (1000 * 60)));
data.push({
Id: id,
Subject: 'Event #' + id,
StartTime: startDate,
EndTime: endDate,
IsAllDay: (id % 10) ? false : true,
ResourceId: i + 1
});
id++;
}
}
return data;
}
const eventSettings = { dataSource: generateStaticEvents(new Date(2018, 4, 1), 300, 12) }
const group = { resources: ['Resources'] };
const generateResourceData = (startId, endId, text) => {
let data = [];
let colors = [
'#ff8787', '#9775fa', '#748ffc', '#3bc9db', '#69db7c',
'#fdd835', '#748ffc', '#9775fa', '#df5286', '#7fa900',
'#fec200', '#5978ee', '#00bdae', '#ea80fc'
];
for (let a = startId; a <= endId; a++) {
let n = Math.floor(Math.random() * colors.length);
data.push({
Id: a,
Text: text + ' ' + a,
Color: colors[n]
});
}
return data;
}
return (<ScheduleComponent cssClass='virtual-scrolling' width='100%' height='550px' selectedDate={new Date(2018, 4, 1)} eventSettings={
eventSettings} group={group}>
<ResourcesDirective>
<ResourceDirective field='ResourceId' title='Resource' name='Resources' allowMultiple={true} dataSource={generateResourceData(1, 300, 'Resource')} textField='Text' idField='Id' colorField='Color'>
</ResourceDirective>
</ResourcesDirective>
<ViewsDirective>
<ViewDirective option='TimelineMonth' allowVirtualScrolling={true} isSelected={true} />
<ViewDirective option='TimelineYear' orientation='Vertical' allowVirtualScrolling={true} />
</ViewsDirective>
<Inject services={[TimelineMonth, TimelineYear, Resize, DragAndDrop]} />
</ScheduleComponent>);
}
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);
import * as ReactDOM from 'react-dom';
import * as React from 'react';
import {
ScheduleComponent, ViewsDirective, ViewDirective, ResourcesDirective,
ResourceDirective, TimelineMonth, TimelineYear, Resize, DragAndDrop, Inject, EventSettingsModel, GroupModel
} from '@syncfusion/ej2-react-schedule';
const App = () => {
const 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,
ResourceId: i + 1
});
id++;
}
}
return data;
}
const eventSettings: EventSettingsModel = { dataSource: generateStaticEvents(new Date(2018, 4, 1), 300, 12) };
const group: GroupModel = { resources: ['Resources'] };
const 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;
}
return (
<ScheduleComponent cssClass='virtual-scrolling' width='100%'
height='550px' selectedDate={new Date(2018, 4, 1)}
eventSettings={eventSettings}
group={group} >
<ResourcesDirective>
<ResourceDirective field='ResourceId' title='Resource' name='Resources' allowMultiple={true}
dataSource={generateResourceData(1, 300, 'Resource')}
textField='Text' idField='Id' colorField='Color'>
</ResourceDirective>
</ResourcesDirective>
< ViewsDirective >
<ViewDirective option='TimelineMonth' allowVirtualScrolling={true} isSelected={true} />
<ViewDirective option='TimelineYear' orientation='Vertical' allowVirtualScrolling={true} />
</ViewsDirective>
< Inject services={[TimelineMonth, TimelineYear, Resize, DragAndDrop]} />
</ScheduleComponent>
);
}
const root = ReactDOM.createRoot(document.getElementById('schedule'));
root.render(<App />);
<!DOCTYPE html>
<html lang="en">
<head>
<title>Syncfusion React Schedule</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="description" content="Essential JS 2 for React Components" />
<meta name="author" content="Syncfusion" />
<link href="https://cdn.syncfusion.com/ej2/21.2.3/ej2-base/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/21.2.3/ej2-react-buttons/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/21.2.3/ej2-react-calendars/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/21.2.3/ej2-react-dropdowns/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/21.2.3/ej2-react-inputs/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/21.2.3/ej2-react-navigations/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/21.2.3/ej2-react-popups/styles/material.css" rel="stylesheet" />
<link href="https://cdn.syncfusion.com/ej2/21.2.3/ej2-react-schedule/styles/material.css" rel="stylesheet" />
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/systemjs/0.19.38/system.js"></script>
<link href="index.css" rel="stylesheet" />
<script src="systemjs.config.js"></script>
<style>
#loader {
color: #008cff;
height: 40px;
left: 45%;
position: absolute;
top: 45%;
width: 30%;
}
.e-past-app {
background-color: chocolate !important;
}
.custom-class.e-schedule .e-vertical-view .e-all-day-appointment-wrapper .e-appointment,
.custom-class.e-schedule .e-vertical-view .e-day-wrapper .e-appointment,
.custom-class.e-schedule .e-month-view .e-appointment {
background: green;
}
</style>
<script src="https://cdn.syncfusion.com/ej2/syncfusion-helper.js" type ="text/javascript"></script>
</head>
<body>
<div id='schedule'>
<div id='loader'>Loading....</div>
</div>
</body>
</html>
For now, the virtual loading of resources and events is not supported in
MonthAgenda
,Year
andTimelineYear
(Horizontal Orientation) views.
See Also
You can refer to our React Scheduler feature tour page for its groundbreaking feature representations. You can also explore our React Scheduler example to knows how to present and manipulate data.