Calendar
Below is an example of a company calendar for use of tracking off days and work days.
Legend
Bars
- Weekend Day
- Planning Day
- Release Day
- Holiday
- Event Day
- Vacation Day
Stats
- Workdays: Any day that is not a weekend, holiday, vacation day. Includes event days.
- Offdays: Any day that is a holiday, weekend, or vacation day but is not an event day.
- Planning Days: Preparation for project development cycle.
- Release Days: Preparation for project releases.
- Holidays: Any day that is a holiday.
- Event Days: Any day that is an event day.
- Vacation Days: Any day that is a vacation day.
Months
January
January Stats
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
February
February Stats
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
March
March Stats
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
April
April Stats
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
May
May Stats
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
June
June Stats
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
July
July Stats
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
August
August Stats
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
September
September Stats
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
October
October Stats
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
November
November Stats
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
December
December Stats
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
Quarter Stats
Q1 (January - March)
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
Q2 (April - June)
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
Q3 (July - September)
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
Q4 (October - December)
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
Year Stats
- Total Days:
- Work Days:
- Off Days:
- Weekdays Total:
- Weekdays On:
- Weekdays Off:
- Weekend Days:
- Holidays:
- Vacation Days:
- Event Days:
- Planning Days:
- Development Days:
- Release Days:
Code
HTML
<section>
<div id="legend" class="legend">
<h2>Legend</h2>
<h3>Bars</h3>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><span class="bar weekend"></span> Weekend Day</li>
<li><span class="bar planning"></span> Planning Day</li>
<li><span class="bar release"></span> Release Day</li>
<li><span class="bar holiday"></span> Holiday</li>
<li><span class="bar event"></span> Event Day</li>
<li><span class="bar vacation"></span> Vacation Day</li>
</ul>
<h3>Stats</h3>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><b>Workdays:</b> Any day that is not a weekend, holiday, vacation day. Includes event days.</li>
<li><b>Offdays:</b> Any day that is a holiday, weekend, or vacation day but is not an event day.</li>
<li><span class="bar planning"></span> <b>Planning Days:</b> Preparation for project development cycle.</li>
<li><span class="bar release"></span> <b>Release Days:</b> Preparation for project releases.</li>
<li><span class="bar holiday"></span> <b>Holidays:</b> Any day that is a holiday.</li>
<li><span class="bar event"></span> <b>Event Days:</b> Any day that is an event day.</li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> Any day that is a vacation day.</li>
</ul>
</div>
</section>
<!-- <section>
<div class="controls">
<h2>Controls</h2>
<p>
<button id="prevYear" title="Go to the previous year">< Prev</button>
<button id="currentYearButton" title="Go to the current year"><span id="currentYear"></span></button>
<button id="nextYear" title="Go to the next year">Next ></button>
<span style="display: inline-block;">
<span>Start Day:</span>
<select id="startDaySelect">
<option value="0">Sunday</option>
<option value="1">Monday</option>
<option value="2">Tuesday</option>
<option value="3">Wednesday</option>
<option value="4">Thursday</option>
<option value="5">Friday</option>
<option value="6">Saturday</option>
</select>
</span>
</p>
</div>
</section> -->
<section id="calendar">
<h2>Months</h2>
<h3>January</h3>
<div id="January-table">
<table class="month-table"></table>
</div>
<details>
<summary>January Stats</summary>
<div id="January-stats" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Total Days:</b> <span class="monthTotaldays"></span></li>
<li><b>Work Days:</b> <span class="monthWorkdays"></span></li>
<li><b>Off Days:</b> <span class="monthOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Weekdays Total:</b> <span class="monthWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="monthWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="monthWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="monthWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="monthHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="monthVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="monthEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="monthPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="monthDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="monthReleaseDays"></span></li>
</ul>
</div>
</details>
<h3>February</h3>
<div id="February-table">
<table class="month-table"></table>
</div>
<details>
<summary>February Stats</summary>
<div id="February-stats" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Total Days:</b> <span class="monthTotaldays"></span></li>
<li><b>Work Days:</b> <span class="monthWorkdays"></span></li>
<li><b>Off Days:</b> <span class="monthOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Weekdays Total:</b> <span class="monthWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="monthWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="monthWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="monthWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="monthHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="monthVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="monthEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="monthPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="monthDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="monthReleaseDays"></span></li>
</ul>
</div>
</details>
<h3>March</h3>
<div id="March-table">
<table class="month-table"></table>
</div>
<details>
<summary>March Stats</summary>
<div id="March-stats" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Total Days:</b> <span class="monthTotaldays"></span></li>
<li><b>Work Days:</b> <span class="monthWorkdays"></span></li>
<li><b>Off Days:</b> <span class="monthOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Weekdays Total:</b> <span class="monthWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="monthWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="monthWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="monthWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="monthHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="monthVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="monthEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="monthPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="monthDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="monthReleaseDays"></span></li>
</ul>
</div>
</details>
<h3>April</h3>
<div id="April-table">
<table class="month-table"></table>
</div>
<details>
<summary>April Stats</summary>
<div id="April-stats" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Total Days:</b> <span class="monthTotaldays"></span></li>
<li><b>Work Days:</b> <span class="monthWorkdays"></span></li>
<li><b>Off Days:</b> <span class="monthOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Weekdays Total:</b> <span class="monthWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="monthWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="monthWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="monthWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="monthHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="monthVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="monthEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="monthPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="monthDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="monthReleaseDays"></span></li>
</ul>
</div>
</details>
<h3>May</h3>
<div id="May-table">
<table class="month-table"></table>
</div>
<details>
<summary>May Stats</summary>
<div id="May-stats" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Total Days:</b> <span class="monthTotaldays"></span></li>
<li><b>Work Days:</b> <span class="monthWorkdays"></span></li>
<li><b>Off Days:</b> <span class="monthOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Weekdays Total:</b> <span class="monthWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="monthWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="monthWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="monthWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="monthHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="monthVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="monthEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="monthPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="monthDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="monthReleaseDays"></span></li>
</ul>
</div>
</details>
<h3>June</h3>
<div id="June-table">
<table class="month-table"></table>
</div>
<details>
<summary>June Stats</summary>
<div id="June-stats" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Total Days:</b> <span class="monthTotaldays"></span></li>
<li><b>Work Days:</b> <span class="monthWorkdays"></span></li>
<li><b>Off Days:</b> <span class="monthOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Weekdays Total:</b> <span class="monthWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="monthWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="monthWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="monthWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="monthHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="monthVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="monthEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="monthPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="monthDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="monthReleaseDays"></span></li>
</ul>
</div>
</details>
<h3>July</h3>
<div id="July-table">
<table class="month-table"></table>
</div>
<details>
<summary>July Stats</summary>
<div id="July-stats" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Total Days:</b> <span class="monthTotaldays"></span></li>
<li><b>Work Days:</b> <span class="monthWorkdays"></span></li>
<li><b>Off Days:</b> <span class="monthOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Weekdays Total:</b> <span class="monthWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="monthWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="monthWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="monthWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="monthHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="monthVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="monthEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="monthPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="monthDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="monthReleaseDays"></span></li>
</ul>
</div>
</details>
<h3>August</h3>
<div id="August-table">
<table class="month-table"></table>
</div>
<details>
<summary>August Stats</summary>
<div id="August-stats" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Total Days:</b> <span class="monthTotaldays"></span></li>
<li><b>Work Days:</b> <span class="monthWorkdays"></span></li>
<li><b>Off Days:</b> <span class="monthOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Weekdays Total:</b> <span class="monthWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="monthWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="monthWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="monthWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="monthHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="monthVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="monthEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="monthPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="monthDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="monthReleaseDays"></span></li>
</ul>
</div>
</details>
<h3>September</h3>
<div id="September-table">
<table class="month-table"></table>
</div>
<details>
<summary>September Stats</summary>
<div id="September-stats" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Total Days:</b> <span class="monthTotaldays"></span></li>
<li><b>Work Days:</b> <span class="monthWorkdays"></span></li>
<li><b>Off Days:</b> <span class="monthOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Weekdays Total:</b> <span class="monthWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="monthWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="monthWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="monthWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="monthHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="monthVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="monthEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="monthPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="monthDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="monthReleaseDays"></span></li>
</ul>
</div>
</details>
<h3>October</h3>
<div id="October-table">
<table class="month-table"></table>
</div>
<details>
<summary>October Stats</summary>
<div id="October-stats" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Total Days:</b> <span class="monthTotaldays"></span></li>
<li><b>Work Days:</b> <span class="monthWorkdays"></span></li>
<li><b>Off Days:</b> <span class="monthOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Weekdays Total:</b> <span class="monthWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="monthWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="monthWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="monthWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="monthHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="monthVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="monthEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="monthPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="monthDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="monthReleaseDays"></span></li>
</ul>
</div>
</details>
<h3>November</h3>
<div id="November-table">
<table class="month-table"></table>
</div>
<details>
<summary>November Stats</summary>
<div id="November-stats" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Total Days:</b> <span class="monthTotaldays"></span></li>
<li><b>Work Days:</b> <span class="monthWorkdays"></span></li>
<li><b>Off Days:</b> <span class="monthOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Weekdays Total:</b> <span class="monthWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="monthWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="monthWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="monthWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="monthHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="monthVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="monthEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="monthPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="monthDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="monthReleaseDays"></span></li>
</ul>
</div>
</details>
<h3>December</h3>
<div id="December-table">
<table class="month-table"></table>
</div>
<details>
<summary>December Stats</summary>
<div id="December-stats" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Total Days:</b> <span class="monthTotaldays"></span></li>
<li><b>Work Days:</b> <span class="monthWorkdays"></span></li>
<li><b>Off Days:</b> <span class="monthOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><b>Weekdays Total:</b> <span class="monthWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="monthWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="monthWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="monthWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="monthHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="monthVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="monthEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4 month-stats">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="monthPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="monthDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="monthReleaseDays"></span></li>
</ul>
</div>
</details>
</section>
<section>
<h2>Quarter Stats</h2>
<h3>Q1 (January - March)</h3>
<div id="Q1" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><b>Total Days:</b> <span class="quarterTotaldays"></span></li>
<li><b>Work Days:</b> <span class="quarterWorkdays"></span></li>
<li><b>Off Days:</b> <span class="quarterOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><b>Weekdays Total:</b> <span class="quarterWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="quarterWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="quarterWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="quarterWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="quarterHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="quarterVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="quarterEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="quarterPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="quarterDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="quarterReleaseDays"></span></li>
</ul>
</div>
<h3>Q2 (April - June)</h3>
<div id="Q2" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><b>Total Days:</b> <span class="quarterTotaldays"></span></li>
<li><b>Work Days:</b> <span class="quarterWorkdays"></span></li>
<li><b>Off Days:</b> <span class="quarterOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><b>Weekdays Total:</b> <span class="quarterWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="quarterWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="quarterWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="quarterWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="quarterHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="quarterVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="quarterEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="quarterPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="quarterDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="quarterReleaseDays"></span></li>
</ul>
</div>
<h3>Q3 (July - September)</h3>
<div id="Q3" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><b>Total Days:</b> <span class="quarterTotaldays"></span></li>
<li><b>Work Days:</b> <span class="quarterWorkdays"></span></li>
<li><b>Off Days:</b> <span class="quarterOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><b>Weekdays Total:</b> <span class="quarterWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="quarterWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="quarterWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="quarterWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="quarterHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="quarterVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="quarterEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="quarterPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="quarterDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="quarterReleaseDays"></span></li>
</ul>
</div>
<h3>Q4 (October - December)</h3>
<div id="Q4" class="div--content content--inset content-overflow">
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><b>Total Days:</b> <span class="quarterTotaldays"></span></li>
<li><b>Work Days:</b> <span class="quarterWorkdays"></span></li>
<li><b>Off Days:</b> <span class="quarterOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><b>Weekdays Total:</b> <span class="quarterWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span class="quarterWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span class="quarterWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span class="quarterWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span class="quarterHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span class="quarterVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span class="quarterEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span class="quarterPlanningDays"></span></li>
<li><b>Development Days:</b> <span class="quarterDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span class="quarterReleaseDays"></span></li>
</ul>
</div>
</section>
<section>
<h2>Year Stats</h2>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><b>Total Days:</b> <span id="yearTotaldays"></span></li>
<li><b>Work Days:</b> <span id="yearWorkdays"></span></li>
<li><b>Off Days:</b> <span id="yearOffdays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><b>Weekdays Total:</b> <span id="yearWeekdaysTotal"></span></li>
<li><b>Weekdays On:</b> <span id="yearWeekdaysOn"></span></li>
<li><b>Weekdays Off:</b> <span id="yearWeekdaysOff"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><span class="bar weekend"></span> <b>Weekend Days:</b> <span id="yearWeekends"></span></li>
<li><span class="bar holiday"></span> <b>Holidays:</b> <span id="yearHolidays"></span></li>
<li><span class="bar vacation"></span> <b>Vacation Days:</b> <span id="yearVacationDays"></span></li>
<li><span class="bar event"></span> <b>Event Days:</b> <span id="yearEventDays"></span></li>
</ul>
<hr>
<ul class="list--columns col-default-1 col-phone-2 col-tablet-3 col-desktop-small-4">
<li><span class="bar planning"></span> <b>Planning Days:</b> <span id="yearPlanningDays"></span></li>
<li><b>Development Days:</b> <span id="yearDevelopmentDays"></span></li>
<li><span class="bar release"></span> <b>Release Days:</b> <span id="yearReleaseDays"></span></li>
</ul>
</section>
CSS
table {
width: 100%;
/* border-collapse: collapse; */
border-collapse: separate;
border-spacing: 0px;
overflow: visible;
table-layout: fixed; /* Ensures columns are the same width */
}
table th, table td {
box-sizing: border-box;
padding: 0px;
border: 1px solid #ddd;
border: 1px solid #ffffff55;
text-align: center;
position: relative;
height: 50px;
}
table tr.blank-row, table tr.blank-row:hover {
background-color: transparent;
}
.controls {
margin-bottom: 10px;
text-align: center;
}
.blank {
background-color: transparent;
color: transparent;
border: none;
}
.weekend {
background-color: #f0f0f033;
border: 1px solid #ffffff99;
}
.today {
background-color: #ffeb3b77;
border: 3px solid #ffeb3b;
color: #fff;
font-weight: bold;
}
.cell-content {
display: flex;
flex-direction: column;
justify-content: flex-end;
height: 100%;
position: relative;
}
.bar {
height: 12px;
}
:not(.month-table) .bar {
display: inline-block;
width: 24px;
margin-right: 10px;
}
.month-table .bar {
width: 100%;
}
.bar.planning {
background-color: #c700c7;
}
.bar.release {
background-color: #a5652a;
}
.bar.holiday {
background-color: #ffd700;
}
.bar.event {
background-color: #90ee90;
}
.bar.vacation {
background-color: #87cefa;
}
.bar.weekend {
background-color: #f0f0f088;
}
.tooltip {
background-color: black;
color: #fff;
border-radius: 6px;
bottom: 110%;
bottom: calc(100% + 4px);
left: 50%;
width: 100%;
width: calc(100% + 32px);
opacity: 0;
padding: 6px;
pointer-events: none;
position: absolute;
text-align: center;
transform: translateX(-50%);
transition: opacity 0.3s;
/* visibility: hidden; */
white-space: normal;
word-wrap: break-word;
z-index: 1;
}
.bar:hover > .tooltip, .cell-content:hover > .tooltip {
/* visibility: visible; */
opacity: 1;
}
JS
document.addEventListener("DOMContentLoaded", function() {
const today = new Date();
let currentYear = new Date().getFullYear();
let startDayOfWeek = 0;
const calendarContainer = document.querySelector("#calendar");
const currentYearSpan = document.getElementById("currentYear");
const currentYearButton = document.getElementById("currentYearButton");
const startDaySelect = document.getElementById("startDaySelect");
const prevYearButton = document.getElementById("prevYear");
const nextYearButton = document.getElementById("nextYear");
const monthNames = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
const dayNames = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
let monthTables = {};
let monthStats = {};
monthNames.forEach(monthName => {
monthTables[monthName] = document.querySelector(`#${monthName}-table .month-table`);
monthStats[monthName] = {
monthTotaldays: document.querySelector(`#${monthName}-stats .monthTotaldays`),
monthWorkdays: document.querySelector(`#${monthName}-stats .monthWorkdays`),
monthOffdays: document.querySelector(`#${monthName}-stats .monthOffdays`),
monthHolidays: document.querySelector(`#${monthName}-stats .monthHolidays`),
monthEventDays: document.querySelector(`#${monthName}-stats .monthEventDays`),
monthVacationDays: document.querySelector(`#${monthName}-stats .monthVacationDays`),
monthWeekends: document.querySelector(`#${monthName}-stats .monthWeekends`),
monthWeekdaysTotal: document.querySelector(`#${monthName}-stats .monthWeekdaysTotal`),
monthWeekdaysOn: document.querySelector(`#${monthName}-stats .monthWeekdaysOn`),
monthWeekdaysOff: document.querySelector(`#${monthName}-stats .monthWeekdaysOff`),
monthPlanningDays: document.querySelector(`#${monthName}-stats .monthPlanningDays`),
monthReleaseDays: document.querySelector(`#${monthName}-stats .monthReleaseDays`),
monthDevelopmentDays: document.querySelector(`#${monthName}-stats .monthDevelopmentDays`),
};
});
const holidays = [
{ rule: 'fixed', date: '01-01', name: 'New Year\'s Day' },
{ rule: 'nthWeekdayOfMonth', month: 0, nth: 3, weekday: 1, name: 'Martin Luther King Jr. Day' },
{ rule: 'nthWeekdayOfMonth', month: 1, nth: 3, weekday: 1, name: 'President\'s Day' },
{ rule: 'fixed', date: '02-14', name: 'Valentine\'s Day' },
{ rule: 'fixed', date: '02-29', name: 'Leap Year Day' },
{ rule: 'fixed', date: '03-17', name: 'St. Patrick\'s Day' },
{ rule: 'lastWeekdayOfMonth', month: 4, weekday: 1, name: 'Memorial Day' },
{ rule: 'fixed', date: '04-20', name: 'Earth Day' },
{ rule: 'nthWeekdayOfMonth', month: 4, nth: 2, weekday: 0, name: 'Mother\'s Day' },
{ rule: 'fixed', date: '07-04', name: 'Independence Day' },
{ rule: 'nthWeekdayOfMonth', month: 5, nth: 3, weekday: 0, name: 'Father\'s Day' },
{ rule: 'nthWeekdayOfMonth', month: 7, nth: 1, weekday: 0, name: 'International Friendship Day' },
{ rule: 'nthWeekdayOfMonth', month: 8, nth: 1, weekday: 1, name: 'Labor Day' },
{ rule: 'fixed', date: '10-31', name: 'Halloween' },
{ rule: 'fixed', date: '11-11', name: 'Veteran\'s Day' },
{ rule: 'nthWeekdayOfMonth', month: 10, nth: 4, weekday: 4, name: 'Thanksgiving Day' },
{ rule: 'fixed', date: '12-24', name: 'Christmas Eve' },
{ rule: 'fixed', date: '12-25', name: 'Christmas Day' },
{ rule: 'fixed', date: '12-31', name: 'New Year\'s Eve' }
];
const events = [
{ start: '2024-04-15', end: '2024-04-19', name: 'Company Retreat' }
];
const vacations = [
{ start: '01-01', end: '01-03', name: 'Q4 Vacation (Part 2)' },
{ start: '06-23', end: '06-30', name: 'Q2 Vacation (Part 1)' },
{ start: '07-01', end: '07-07', name: 'Q2 Vacation (Part 2)' },
{ start: '12-19', end: '12-31', name: 'Q4 Vacation (Part 1)' }
];
function getHolidayDate(year, holiday) {
if (holiday.rule === 'fixed') {
return new Date(year, parseInt(holiday.date.split('-')[0]) - 1, parseInt(holiday.date.split('-')[1]));
} else if (holiday.rule === 'nthWeekdayOfMonth') {
let date = new Date(year, holiday.month, 1);
let weekdayCount = 0;
while (true) {
if (date.getDay() === holiday.weekday) {
weekdayCount++;
if (weekdayCount === holiday.nth) {
return date;
}
}
date.setDate(date.getDate() + 1);
}
} else if (holiday.rule === 'lastWeekdayOfMonth') {
let date = new Date(year, holiday.month + 1, 0);
while (date.getDay() !== holiday.weekday) {
date.setDate(date.getDate() - 1);
}
return date;
}
}
let planningDays = [];
function calculatePlanningDays(year) {
planningDays = [];
function isHoliday(date) {
return holidays.some(holiday => getHolidayDate(year, holiday).toISOString().split('T')[0] === date.toISOString().split('T')[0]);
}
function isVacation(date) {
return vacations.some(vacation => {
let vacationStart = new Date(`${year}-${vacation.start}`);
let vacationEnd = new Date(`${year}-${vacation.end}`);
return vacationStart.toISOString().split('T')[0] <= date.toISOString().split('T')[0] && date.toISOString().split('T')[0] <= vacationEnd.toISOString().split('T')[0];
});
}
function getFirstNWorkdays(year, month, n) {
let date = new Date(year, month, 1);
const workdays = [];
while (workdays.length < n) {
if (date.getDay() !== 0 && date.getDay() !== 6 && !isHoliday(date) && !isVacation(date)) {
workdays.push(date.toISOString().split('T')[0]);
}
date.setDate(date.getDate() + 1);
}
return workdays;
}
const quarters = [
{ name: 'Q1 Planning', months: [0, 1, 2] },
{ name: 'Q2 Planning', months: [3, 4, 5] },
{ name: 'Q3 Planning', months: [6, 7, 8] },
{ name: 'Q4 Planning', months: [9, 10, 11] }
];
quarters.forEach(quarter => {
const firstMonth = quarter.months[0];
const planningDaysArray = getFirstNWorkdays(year, firstMonth, 10);
planningDaysArray.forEach(day => planningDays.push({ start: day, end: day, name: quarter.name }));
});
}
calculatePlanningDays(currentYear);
let releases = [];
function calculateReleaseDays(year) {
releases = [];
function isHoliday(date) {
return holidays.some(holiday => getHolidayDate(year, holiday).toISOString().split('T')[0] === date.toISOString().split('T')[0]);
}
function isVacation(date) {
return vacations.some(vacation => {
let vacationStart = new Date(`${year}-${vacation.start}`);
let vacationEnd = new Date(`${year}-${vacation.end}`);
return vacationStart.toISOString().split('T')[0] <= date.toISOString().split('T')[0] && date.toISOString().split('T')[0] <= vacationEnd.toISOString().split('T')[0];
});
}
function getLastNWorkdays(year, month, n) {
let date = new Date(year, month + 1, 0);
const workdays = [];
while (workdays.length < n) {
if (date.getDay() !== 0 && date.getDay() !== 6 && !isHoliday(date) && !isVacation(date)) {
workdays.unshift(date.toISOString().split('T')[0]);
}
date.setDate(date.getDate() - 1);
}
return workdays;
}
const quarters = [
{ name: 'Q1 Release', months: [0, 1, 2] },
{ name: 'Q2 Release', months: [3, 4, 5] },
{ name: 'Q3 Release', months: [6, 7, 8] },
{ name: 'Q4 Release', months: [9, 10, 11] }
];
quarters.forEach(quarter => {
const lastMonth = quarter.months[quarter.months.length - 1];
const releaseDays = getLastNWorkdays(year, lastMonth, 10);
releaseDays.forEach(day => releases.push({ start: day, end: day, name: quarter.name }));
});
}
calculateReleaseDays(currentYear);
function updateStats(year, monthIndex) {
let totalDays = 0;
let workdays = 0;
let offdays = 0;
let holidaysCount = 0;
let eventDays = 0;
let vacationDays = 0;
let weekends = 0;
let weekdaysTotal = 0;
let weekdaysOn = 0;
let weekdaysOff = 0;
let planningDaysCount = 0;
let releaseDays = 0;
let developmentDays = 0;
let firstDayOfMonth = new Date(year, monthIndex, 1);
let lastDayOfMonth = new Date(year, monthIndex + 1, 0);
let date = firstDayOfMonth;
while (date <= lastDayOfMonth) {
let isWeekend = (date.getDay() === 0 || date.getDay() === 6);
let isHoliday = holidays.some(holiday => {
let holidayDate = getHolidayDate(year, holiday);
return holidayDate.getMonth() === monthIndex && date.getDate() === holidayDate.getDate();
});
let isVacation = vacations.some(vacation => {
let vacationStart = new Date(`${year}-${vacation.start}`);
let vacationEnd = new Date(`${year}-${vacation.end}`);
return vacationStart.toISOString().split('T')[0] <= date.toISOString().split('T')[0] && date.toISOString().split('T')[0] <= vacationEnd.toISOString().split('T')[0];
});
let isEvent = events.some(event => {
let eventStart = new Date(event.start);
let eventEnd = new Date(event.end);
return eventStart.toISOString().split('T')[0] <= date.toISOString().split('T')[0] && date.toISOString().split('T')[0] <= eventEnd.toISOString().split('T')[0];
});
let isPlanningDay = planningDays.some(planning => planning.start === date.toISOString().split('T')[0]);
if (isPlanningDay) {
planningDaysCount++; // Add this line
}
let isRelease = releases.some(release => {
let releaseStart = new Date(release.start);
let releaseEnd = new Date(release.end);
return releaseStart.toISOString().split('T')[0] <= date.toISOString().split('T')[0] && date.toISOString().split('T')[0] <= releaseEnd.toISOString().split('T')[0];
});
let isDevelopmentDay = !isWeekend && !isHoliday && !isEvent && !isRelease && !isVacation && !isPlanningDay; // Add this line
if (isDevelopmentDay) {
developmentDays++; // Add this line
}
totalDays++;
if (!isWeekend) {
weekdaysTotal++;
if (!isHoliday && !isVacation) {
weekdaysOn++;
} else if (!isEvent) {
weekdaysOff++;
}
}
if (isEvent) {
eventDays++;
}
if (!isWeekend && !isHoliday && !isVacation) {
workdays++;
} else if (!isEvent) {
offdays++;
}
if (isWeekend) weekends++;
if (isHoliday) holidaysCount++;
if (isVacation) vacationDays++;
if (isRelease) releaseDays++;
date.setDate(date.getDate() + 1);
}
return { totalDays, workdays, offdays, holidaysCount, eventDays, vacationDays, weekends, weekdaysTotal, weekdaysOn, weekdaysOff, planningDaysCount, releaseDays, developmentDays };
}
function updateYearStats(year) {
let yearTotalDays = 0;
let yearWorkdays = 0;
let yearOffdays = 0;
let yearHolidays = 0;
let yearEventDays = 0;
let yearVacationDays = 0;
let yearWeekends = 0;
let yearWeekdaysTotal = 0;
let yearWeekdaysOn = 0;
let yearWeekdaysOff = 0;
let yearPlanningDays = 0;
let yearReleaseDays = 0;
let yearDevelopmentDays = 0;
monthNames.forEach((monthName, monthIndex) => {
let stats = updateStats(year, monthIndex);
yearTotalDays += stats.totalDays;
yearWorkdays += stats.workdays;
yearOffdays += stats.offdays;
yearHolidays += stats.holidaysCount;
yearEventDays += stats.eventDays;
yearVacationDays += stats.vacationDays;
yearWeekends += stats.weekends;
yearWeekdaysTotal += stats.weekdaysTotal;
yearWeekdaysOn += stats.weekdaysOn;
yearWeekdaysOff += stats.weekdaysOff;
yearPlanningDays += stats.planningDaysCount;
yearReleaseDays += stats.releaseDays;
yearDevelopmentDays += stats.developmentDays;
});
let isLeapYear = (year % 4 === 0 && year % 100 !== 0) || (year % 400 === 0);
let leapYearText = isLeapYear ? " (Leap Year)" : "";
document.getElementById("yearTotaldays").textContent = `${yearTotalDays}${leapYearText}`;
document.getElementById("yearWorkdays").textContent = yearWorkdays;
document.getElementById("yearOffdays").textContent = yearOffdays;
document.getElementById("yearHolidays").textContent = yearHolidays;
document.getElementById("yearEventDays").textContent = yearEventDays;
document.getElementById("yearVacationDays").textContent = yearVacationDays;
document.getElementById("yearWeekends").textContent = yearWeekends;
document.getElementById("yearWeekdaysTotal").textContent = yearWeekdaysTotal;
document.getElementById("yearWeekdaysOn").textContent = yearWeekdaysOn;
document.getElementById("yearWeekdaysOff").textContent = yearWeekdaysOff;
document.getElementById("yearPlanningDays").textContent = yearPlanningDays;
document.getElementById("yearReleaseDays").textContent = yearReleaseDays;
document.getElementById("yearDevelopmentDays").textContent = yearDevelopmentDays;
}
function updateQuarterStats(year) {
const quarters = [
{ name: 'Q1', months: [0, 1, 2] },
{ name: 'Q2', months: [3, 4, 5] },
{ name: 'Q3', months: [6, 7, 8] },
{ name: 'Q4', months: [9, 10, 11] }
];
quarters.forEach(quarter => {
let totalDays = 0;
let workdays = 0;
let offdays = 0;
let holidays = 0;
let eventDays = 0;
let releaseDays = 0;
let vacationDays = 0;
let planningDays = 0;
let developmentDays = 0;
let weekends = 0;
let weekdaysTotal = 0;
let weekdaysOn = 0;
let weekdaysOff = 0;
quarter.months.forEach(monthIndex => {
let stats = updateStats(year, monthIndex);
totalDays += stats.totalDays;
workdays += stats.workdays;
offdays += stats.offdays;
holidays += stats.holidaysCount;
eventDays += stats.eventDays;
releaseDays += stats.releaseDays;
vacationDays += stats.vacationDays;
planningDays += stats.planningDaysCount;
developmentDays += stats.developmentDays;
weekends += stats.weekends;
weekdaysTotal += stats.weekdaysTotal;
weekdaysOn += stats.weekdaysOn;
weekdaysOff += stats.weekdaysOff;
});
document.querySelector(`#${quarter.name} .quarterTotaldays`).textContent = totalDays;
document.querySelector(`#${quarter.name} .quarterWorkdays`).textContent = workdays;
document.querySelector(`#${quarter.name} .quarterOffdays`).textContent = offdays;
document.querySelector(`#${quarter.name} .quarterHolidays`).textContent = holidays;
document.querySelector(`#${quarter.name} .quarterEventDays`).textContent = eventDays;
document.querySelector(`#${quarter.name} .quarterReleaseDays`).textContent = releaseDays;
document.querySelector(`#${quarter.name} .quarterVacationDays`).textContent = vacationDays;
document.querySelector(`#${quarter.name} .quarterPlanningDays`).textContent = planningDays;
document.querySelector(`#${quarter.name} .quarterDevelopmentDays`).textContent = developmentDays;
document.querySelector(`#${quarter.name} .quarterWeekends`).textContent = weekends;
document.querySelector(`#${quarter.name} .quarterWeekdaysTotal`).textContent = weekdaysTotal;
document.querySelector(`#${quarter.name} .quarterWeekdaysOn`).textContent = weekdaysOn;
document.querySelector(`#${quarter.name} .quarterWeekdaysOff`).textContent = weekdaysOff;
});
}
function generateCalendar(year) {
currentYearSpan.textContent = year;
updateYearStats(year);
updateQuarterStats(year);
if (year === new Date().getFullYear()) {
currentYearButton.title = "Go to today";
} else {
currentYearButton.title = "Go to the current year";
}
monthNames.forEach((monthName, monthIndex) => {
const monthTable = monthTables[monthName];
const {
monthTotaldays,
monthWorkdays,
monthOffdays,
monthHolidays,
monthEventDays,
monthVacationDays,
monthWeekends,
monthWeekdaysTotal,
monthWeekdaysOn,
monthWeekdaysOff,
monthPlanningDays,
monthReleaseDays,
monthDevelopmentDays,
} = monthStats[monthName];
const thead = document.createElement("thead");
const tbody = document.createElement("tbody");
monthTable.innerHTML = "";
monthTable.appendChild(thead);
monthTable.appendChild(tbody);
const theadRow = document.createElement("tr");
for (let i = 0; i < 7; i++) {
const th = document.createElement("th");
th.textContent = dayNames[(i + startDayOfWeek) % 7];
theadRow.appendChild(th);
}
thead.appendChild(theadRow);
let firstDayOfMonth = new Date(year, monthIndex, 1);
let lastDayOfMonth = new Date(year, monthIndex + 1, 0);
let date = firstDayOfMonth;
let row = tbody.insertRow();
// Add empty cells for days before the first day of the month
for (let i = 0; i < (firstDayOfMonth.getDay() - startDayOfWeek + 7) % 7; i++) {
let cell = row.insertCell();
cell.classList.add("blank");
}
while (date <= lastDayOfMonth) {
if (row.cells.length >= 7) {
row = tbody.insertRow();
}
let cell = row.insertCell();
cell.innerHTML = `<div class="cell-content">${date.getDate()}</div>`;
cell.dataset.date = date.toISOString().split('T')[0];
let cellContent = cell.querySelector(".cell-content");
if (date.getDay() === 0 || date.getDay() === 6) {
cell.classList.add('weekend');
}
if (date.toDateString() === today.toDateString()) {
cell.classList.add('today');
let todayTooltip = document.createElement("div");
todayTooltip.classList.add("tooltip");
todayTooltip.textContent = "Today";
cellContent.appendChild(todayTooltip);
}
holidays.forEach(holiday => {
let holidayDate = getHolidayDate(year, holiday);
if (holidayDate.toISOString().split('T')[0] === cell.dataset.date) {
let bar = document.createElement("div");
bar.classList.add('bar', 'holiday');
bar.innerHTML = `<div class="tooltip">${holiday.name}</div>`;
cellContent.appendChild(bar);
}
});
vacations.forEach(vacation => {
let vacationStart = new Date(`${year}-${vacation.start}`);
let vacationEnd = new Date(`${year}-${vacation.end}`);
if (vacationStart.toISOString().split('T')[0] <= cell.dataset.date && cell.dataset.date <= vacationEnd.toISOString().split('T')[0]) {
let bar = document.createElement("div");
bar.classList.add('bar', 'vacation');
bar.innerHTML = `<div class="tooltip">${vacation.name}</div>`;
cellContent.appendChild(bar);
}
});
const event = events.find(event => new Date(event.start).toISOString().split('T')[0] <= cell.dataset.date && cell.dataset.date <= new Date(event.end).toISOString().split('T')[0]);
if (event) {
let bar = document.createElement("div");
bar.classList.add('bar', 'event');
bar.innerHTML = `<div class="tooltip">${event.name}</div>`;
cellContent.appendChild(bar);
}
const planning = planningDays.find(planning => planning.start === cell.dataset.date);
if (planning) {
let bar = document.createElement("div");
bar.classList.add('bar', 'planning');
bar.innerHTML = `<div class="tooltip">${planning.name}</div>`;
cellContent.appendChild(bar);
}
const release = releases.find(release => release.start === cell.dataset.date);
if (release) {
let bar = document.createElement("div");
bar.classList.add('bar', 'release');
bar.innerHTML = `<div class="tooltip">${release.name}</div>`;
cellContent.appendChild(bar);
}
date.setDate(date.getDate() + 1);
}
// Add empty cells for days after the last day of the month
while (row.cells.length < 7) {
let cell = row.insertCell();
cell.classList.add("blank");
}
// Calculate the total number of rows needed based on the assumption the first day of the month is on a Saturday
let totalDays = lastDayOfMonth.getDate();
let firstDay = firstDayOfMonth.getDay();
let totalCells = 6 + totalDays; // Assume the first day is on a Saturday
let totalRows = Math.ceil(totalCells / 7);
// Ensure there are the required number of rows
while (tbody.rows.length < totalRows) {
row = tbody.insertRow();
for (let i = 0; i < 7; i++) {
let cell = row.insertCell();
cell.classList.add("blank");
}
}
// Add the blank-row class to entirely blank rows
for (let i = 0; i < tbody.rows.length; i++) {
let isBlankRow = true;
for (let j = 0; j < tbody.rows[i].cells.length; j++) {
if (!tbody.rows[i].cells[j].classList.contains("blank")) {
isBlankRow = false;
break;
}
}
if (isBlankRow) {
tbody.rows[i].classList.add("blank-row");
}
}
// Update month stats
let stats = updateStats(year, monthIndex);
monthTotaldays.textContent = stats.totalDays;
monthWorkdays.textContent = stats.workdays;
monthOffdays.textContent = stats.offdays;
monthHolidays.textContent = stats.holidaysCount;
monthEventDays.textContent = stats.eventDays;
monthVacationDays.textContent = stats.vacationDays;
monthWeekends.textContent = stats.weekends;
monthWeekdaysTotal.textContent = stats.weekdaysTotal;
monthWeekdaysOn.textContent = stats.weekdaysOn;
monthWeekdaysOff.textContent = stats.weekdaysOff;
monthPlanningDays.textContent = stats.planningDaysCount;
monthReleaseDays.textContent = stats.releaseDays;
monthDevelopmentDays.textContent = stats.developmentDays;
});
}
prevYearButton.addEventListener("click", function() {
currentYear--;
generateCalendar(currentYear);
});
nextYearButton.addEventListener("click", function() {
currentYear++;
generateCalendar(currentYear);
});
currentYearButton.addEventListener("click", function() {
// Scroll to today's cell
const todayCell = document.querySelector('.today');
if (todayCell) {
todayCell.scrollIntoView({ behavior: 'smooth', block: 'center' });
} else {
currentYear = new Date().getFullYear();
generateCalendar(currentYear);
}
});
startDaySelect.addEventListener("change", function() {
startDayOfWeek = parseInt(this.value);
generateCalendar(currentYear);
});
generateCalendar(currentYear);
});