Agent-readable demo data

Title
Resource Tree Animation (JavaScript Scheduler) | DayPilot Pro for JavaScript Demo
Tree
DayPilot JavaScript Demo
Catalog root
Default
Description
Expand or collapse a team using the arrow next to its name. Teams contain 1, 3, 10, 30 and 100 resources. Auto duration adjusts the animation duration to the height of the content, between 240 and 550 ms. Settings apply automatically when changed.

Inline demo script 1

const teams = [
            {id: "planning", name: "Planning", count: 1},
            {id: "design", name: "Design", count: 3},
            {id: "development", name: "Development", count: 10},
            {id: "operations", name: "Operations", count: 30},
            {id: "production", name: "Production", count: 100}
        ];
        const start = new DayPilot.Date("2026-09-01");
        const events = [];
        const links = [];
        const resources = teams.map((team, index) => ({
            id: team.id,
            name: team.name + " (" + team.count + (team.count === 1 ? " resource)" : " resources)"),
            expanded: index < 2,
            children: Array.from({length: team.count}, (_, row) => {
                const id = team.id + "-" + row;
                const offset = (row % 4) * 2;
                events.push(
                    {id: id + "-plan", resource: id, text: "Preparation", start: start.addDays(offset + 1), end: start.addDays(offset + 3)},
                    {id: id + "-work", resource: id, text: "Delivery", start: start.addDays(offset + 4), end: start.addDays(offset + 7)}
                );
                links.push({id: id + "-link", from: id + "-plan", to: id + "-work"});
                if (row > 0 && row % 3 === 0) {
                    links.push({id: id + "-handoff", from: team.id + "-" + (row - 1) + "-work", to: id + "-work"});
                }
                return {id, name: team.name + " " + (row + 1)};
            })
        }));
        const dp = new DayPilot.Scheduler("dp", {
            startDate: start, days: 21, scale: "Day", cellWidthSpec: "Auto", cellWidthMin: 30,
            floatingTimeHeaders: false,
            timeHeaders: [{groupBy: "Month"}, {groupBy: "Day", format: "d"}],
            heightSpec: "Max", height: 450,
            rowMarginTop: 2, rowMarginBottom: 2,
            rowHeaderWidth: 230,
            treeEnabled: true,
            treeAnimation: true,
            treeAnimationDuration: "Auto",
            treeAnimationEasing: "standard",
            eventMoveHandling: "Disabled", eventResizeHandling: "Disabled", timeRangeSelectedHandling: "Disabled",
            resources, events, links
        });
        dp.init();

        const app = {
            init() {
                document.getElementById("animation-settings").addEventListener("change", () => {
                    this.apply();
                });
                this.preference = window.matchMedia("(prefers-reduced-motion: reduce)");
                this.preference.addEventListener("change", () => this.showPreference());
                this.showPreference();
                this.showConfiguration();
            },
            showPreference() {
                document.getElementById("motion-preference").hidden =
                    !(dp.treeAnimation === "Auto" && dp.treeAnimationDuration !== 0 && this.preference.matches);
            },
            apply() {
                if (!document.getElementById("animation-settings").reportValidity()) {
                    this.message("Enter valid settings. The previous configuration remains active.", true);
                    return;
                }
                const animation = document.getElementById("animation").value;
                const duration = document.getElementById("duration").value === "Auto" ? "Auto" :
                    Number(document.getElementById("duration").value);
                const easing = document.getElementById("easing").value;
                try {
                    // Animation settings are read at the next tree toggle; no redraw is needed.
                    dp.treeAnimation = animation === "Auto" ? "Auto" : animation === "true";
                    dp.treeAnimationDuration = duration;
                    dp.treeAnimationEasing = easing;
                    this.showPreference();
                    this.showConfiguration();
                    this.message("");
                }
                catch (error) {
                    this.message(error.message, true);
                }
            },
            message(text, error = false) {
                const message = document.getElementById("animation-message");
                message.textContent = text;
                message.hidden = !text;
                message.classList.toggle("error", error);
            },
            showConfiguration() {
                document.getElementById("configuration").textContent = "heightSpec: \"Max\",\n" +
                    "treeEnabled: true,\n" +
                    "treeAnimation: " + JSON.stringify(dp.treeAnimation) + ",\n" +
                    "treeAnimationDuration: " + JSON.stringify(dp.treeAnimationDuration) + ",\n" +
                    "treeAnimationEasing: " + JSON.stringify(dp.treeAnimationEasing);
            }
        };
        app.init();