webdevpuneet.com

ApexCharts Weekly Activity Heatmap (Day × Hour) — Free Snippet

ApexCharts Weekly Activity Heatmap (Day × Hour) · Charts · Plain HTML, CSS & JS · Live preview

CategoryCharts

Copy & paste

Source Code

Requires
<div class="ahm-wrap">
  <div class="ahm-card">
    <div class="ahm-head">
      <div>
        <div class="ahm-title">When do customers message support?</div>
        <div class="ahm-sub">Average conversations started per hour, last 8 weeks</div>
      </div>
      <label class="ahm-tz">Time zone
        <select id="ahmShift">
          <option value="0">UTC</option>
          <option value="-5">New York (UTC−5)</option>
          <option value="1">Berlin (UTC+1)</option>
          <option value="5.5">Mumbai (UTC+5:30)</option>
        </select>
      </label>
    </div>
    <div id="ahmChart"></div>
    <div class="ahm-peak" id="ahmPeak"></div>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

7×24 heatmap grid
Days as series, hours as points.
Monday-first ordering
Series reversed to counter bottom-up stacking.
Fixed colour bands
Named ranges with a stable meaning and a legend.
Correct time-zone shifting
A flat 168-hour week wraps across day boundaries.
Busiest-hour summary
Key insight stated in text.
Uncluttered axis
Every third hour labelled, no rotated text.
Deterministic sample data
Seeded values render identically on each load.
Cell gaps and rounding
White strokes and small radius separate cells.

About this UI Snippet

ApexCharts Day × Hour Heatmap — Finding the Busy Hours in a Week

Screenshot of the ApexCharts Weekly Activity Heatmap (Day × Hour) snippet rendered live

A week of hourly counts is 168 numbers. As a table it is unreadable; as a day-by-hour heatmap the pattern jumps out immediately: the weekday afternoon block, the lunch dip, the quiet weekend. This layout is used for support staffing, posting schedules, server load and store footfall.

Series are rows, points are columns

In an ApexCharts heatmap each series is one row and each { x, y } point is a cell. The snippet builds seven series (days), each with 24 points (hours). ApexCharts stacks series from the bottom up, so the array is reversed to put Monday on top.

Fixed colour ranges instead of shades

By default heatmap cells are shaded relative to the data. That makes colours mean different things after the data changes. Here enableShades: false and colorScale.ranges define four named bands with fixed boundaries. The legend lists them, and "Busy" means 13–20 conversations no matter which time zone you view.

Time zones cross midnight

Converting from UTC to another zone is not a per-row operation. Moving New York five hours back pushes Monday 02:00 UTC into Sunday evening. The snippet flattens the week to 168 hours, shifts every index with wrap-around (((i + shift) % 168 + 168) % 168), and rebuilds the grid. Half-hour zones are rounded to the nearest hour, which is noted as a limitation you may need to handle.

A text summary

The busiest day and hour are computed from the same grid and written under the chart, so the key insight is available without reading colours.

Readable axis labels

Only every third hour is labelled on the x-axis, keeping labels horizontal without collisions.

Step by step

How to Use

  1. 1
    Load ApexChartsInclude apexcharts.min.js from the CDN.
  2. 2
    Paste the snippetA 7-day by 24-hour grid renders with a four-band legend.
  3. 3
    Hover cellsThe tooltip shows the day, hour and count.
  4. 4
    Change time zoneThe grid shifts, wrapping hours into the previous or next day.
  5. 5
    Read the summaryThe busiest hour is stated in text below the chart.
  6. 6
    Load real dataFill BASE[day][hour] with your own UTC counts.

Real-world uses

Common Use Cases

Support staffing schedules
Schedule agents for the hours that actually bring tickets. The weekday-afternoon block and the lunch dip jump out of 168 numbers immediately.
Social posting schedules
Find when an audience is most engaged and plan posts around the busiest hours, with the busiest-hour summary stating the answer directly.
Infrastructure load planning
Spot recurring weekly traffic peaks for capacity planning. Fixed colour bands keep their meaning stable, so a dark cell always represents the same load.
Retail footfall analysis
See visits by weekday and hour, and switch time zone to compare stores. The 168-hour week wraps correctly across day boundaries.
Personal productivity tracking
Visualise when you commit code or do focused work. Monday sits at the top, with the series reversed to counter ApexCharts' bottom-up stacking.
Related: ECharts Calendar Heatmap
For a year-long daily view see ECharts Calendar Heatmap.
Related: Activity Heatmap
A dependency-free take in Activity Heatmap.

Got questions?

Frequently Asked Questions

An array of series, one per row. Each series has a name and a data array of { x, y } points, where x is the column label and y the value. Seven series with 24 points each gives a day-by-hour grid.

ApexCharts draws heatmap series from the bottom of the chart upward. Reversing the array puts the first day, Monday, at the top.

Set plotOptions.heatmap.enableShades to false and define plotOptions.heatmap.colorScale.ranges as objects with from, to, color and name. The names appear in the legend.

Store data in UTC, flatten the week into 168 hourly values, shift each index by the zone offset with modular wrap-around, and rebuild the 7×24 grid. Shifting row by row is wrong, because hours near midnight belong to the neighbouring day.

With hourly buckets a 30-minute offset can't be represented exactly, so this snippet rounds it. For exact results, bucket raw timestamps by local hour after converting them, instead of shifting pre-aggregated hours.