Beyond Grids to Heatmaps

Beyond Grids to Heatmaps

1. Background and Problem Situation

The A project had a requirement to implement a 365-day heatmap UI to visualize user activity data on an annual basis.

Initially, I thought simply about the common concept of a 'heatmap' and approached it, so I concluded that utilizing ApexCharts, which was already included in the project, was the most efficient choice.

I believed that reusing the already operating chart library would allow us to avoid adding new dependencies and would also be advantageous in terms of initial development speed.

However, while actually implementing it, I realized that there are clear differences in types and purposes in heatmaps. At first, I thought that if data is simply represented by color, they were all the same heatmap, but in reality, the data model and the rendering method have fundamentally different structures.

Heatmaps can generally be divided into three main types.

The first is a grid-based heatmap commonly used for statistics and analysis.

This method has a clear categorical structure for the X and Y axes and represents the value of specific coordinates with color.

For example, typical forms include usage by time of day, comparative sales by product, and performance comparison by department.

The second is a time-series calendar heatmap that expresses data based on the flow of dates.

A representative example that is similar to the GitHub Contribution Graph, where the date-based flow itself becomes the core data model. It is not just about displaying coordinates; rather, the concept of 'time' is at the center.

The third is a density heatmap used in maps or location-based data.

This is a way to visually represent how much data is concentrated at specific coordinates, and it is commonly used in GIS-related services.

The problem was that ApexCharts is a typical grid heatmap engine.

In other words, while it was optimized for coordinate-based data visualization, it had a structure that was not suitable for a time series calendar heatmap centered around date flow.

At that time, the implementation target was a calendar heatmap that needed to arrange 365 days of data on a weekly basis.

However, ApexCharts does not recognize dates itself and only processes them as simple coordinate data, so I had to manually convert the date data into a form that the chart could understand.

Ultimately, a separate preprocessing logic was needed to map the one year of data to a coordinate system with a structure of 7 rows and 52 columns.

For example, I had to calculate directly which week a specific date corresponds to, what day it is, and where it should be placed on the coordinates. The implementation itself was feasible.

However, the issue was that the design purpose of the library didn't match its actual usage. By forcibly combining the calendar concept with a grid chart engine originally designed for statistical purposes, unnecessary data processing logic was continuously added.

In particular, the amount of exception handling code increased during the process of converting date data into coordinates, and additional logic such as month boundary handling and leap year processing was also required.

In this process, maintenance costs began to arise that exceeded simple UI implementation. With each added feature, both the chart data structure and date calculation logic were simultaneously affected, resulting in a rapid increase in code complexity.

As the project progressed, I began to ponder whether the current implementation method is indeed a sustainable structure in the long term. I realized that simply choosing technology based on its feasibility for implementation could lead to greater costs during the operational phase.

2. Structural limitations encountered during the implementation process of the time series calendar heatmap

Afterwards, there was an opportunity to re-implement the same time-series calendar heatmap using MUI Charts while proceeding with the standardization of the internal UI guide.

Initially, there were high expectations due to the good integration with the MUI ecosystem.

I judged that it would be more favorable than ApexCharts in terms of compatibility with existing design systems.

However, similar structural issues arose again during the actual implementation process.

The most representative example was the implementation of tooltips. According to the design guide, when the mouse is hovered over the heatmap cell, not only the date and value should be displayed, but also the day of the week information.

However, MUI Charts also used a grid-based data model by default, so it only recognized data as simple coordinate values within the chart.

In other words, to display information like 'Saturday, March 15, 2025' in the tooltip, it was necessary to backtrack to determine what actual date the current coordinates corresponded to. This process was much more complicated than expected.

Since the date data had already been converted to a coordinate-based format for chart rendering, it was necessary to perform the reverse calculation to restore coordinates to dates in the tooltip.

Ultimately, the following problem has arisen.

First, the data for rendering charts has started to become separate from the actual business data model.

Second, a reverse data mapping logic has been added for simple UI representation.

Third, even a slight change in the design layout has affected the entire date calculation structure.

In particular, if the month start position or week calculation criteria are changed, there is a possibility that the existing calculation logic could be shaken.

This was not simply a matter of screen implementation, but an issue directly related to operational stability.

There was no guarantee that the existing workaround logic would work correctly when the chart library version was updated. This was because changes in the internal rendering structure of the library could easily break custom logic.

In this way, we judged that excessive customization, which deviates from the original design purpose of the library, is likely to lead to technical debt.

Especially from an operational perspective, I thought that it was more important to consider whether it could be maintained a year from now than whether it can be implemented right now. Focusing only on initial development speed and choosing to maintain the existing stack could actually lead to increased long-term maintenance costs.

3. Review and selection process for a dedicated time series heatmap library

After identifying the structural limitations of existing grid-based chart libraries, we began to separately review dedicated time series heatmap libraries focused on date data.

The most important criteria we considered are as follows.

First, it was whether the library internally understands date data by default.

Second, it was whether the tooltip can naturally handle date and day information.

Thirdly, whether it reliably supports responsive layouts.

Fourthly, how seamlessly it can integrate with the company's common design system.

As a result of comparing several candidates, we concluded that react-activity-calendar is the most suitable choice.

This library has a structure specialized for timeline calendar heatmaps in the style of GitHub Contribution.

In other words, since the date itself is at the center of the data model, almost no separate coordinate transformation logic was needed.

It was a significant advantage that simply providing the date data allowed the internal engine to automatically perform weekly batching and cell position calculations.

There was no need to manually calculate 'which week it is', 'which day it is', and 'where it should be located' like in the old method.

Additionally, the tooltip configuration was much simpler. Since it already maintained a date-based data structure internally, it could use the date and day information directly without additional calculations.

As a result, we were able to eliminate most of the existing bypass calculation logic.

This meant that the data structure itself has been significantly improved to be much more intuitive, not just a reduction in code length.

4. Responsive Handling and Design System Integration

Another key reason for choosing react-activity-calendar was its responsive handling method. Unlike typical chart libraries that often require manually calculating and passing the width and height based on the parent container size.

In particular, in cell-based UIs, it often happens that cell sizes and gaps need to be recalculated separately according to changes in browser size.

However, react-activity-calendar automatically handled these calculations with its internal engine. It maintained the layout while automatically repositioning cell sizes and gaps when the browser size changed. Thanks to this structure, there was no need to implement a separate calculation logic based on ResizeObserver.

As a result, the responsive handling code itself has been greatly simplified.

Also, the styling handling method was very satisfactory. Most existing chart libraries required customization that forced the overriding of CSS classes.

However, this approach strongly relies on the internal class structure of the library, which can easily break with version changes.

On the other hand, react-activity-calendar provided a declarative style structure based on the theme object.

In other words, since color tokens could be injected directly in the form of objects, we were able to connect seamlessly with the internal common UI system, vizend-ui.

Especially in projects that use a design token-based structure, this declarative theme approach has acted as a significant advantage in terms of maintenance.

5. Summary

The process of transitioning to the new heatmap library carried more significance than just a simple UI component replacement. Initially, I thought it would be efficient to reuse as many libraries as possible that were already included in the existing project.

However, in the actual implementation process, I experienced that if the purpose of the library's design does not align with the essence of the data model, maintenance costs can be significantly higher than expected.

In particular, the time series calendar heatmap had a completely different data structure compared to simple coordinate-based charts. Since the date itself is the core data model, forcing it into a simple coordinate-based transformation can lead to an increase in technical debt in the long run.

In the end, what matters is not 'whether it can be implemented currently' but 'how stable it can be maintained in the operational environment.'

After switching to react-activity-calendar, we were able to remove most unnecessary preprocessing and reverse calculation logic, greatly improving both data reliability and code readability.

We were also able to secure a much more stable structure in terms of responsive processing and the integration of the design system.

This experience made me realize once again that in choosing technologies, it is essential to consider not only the mere support for functionalities but also how well the nature of the data model and the design philosophy of the library align.

[Reference Material]

• MUI X Heatmap Documentation

https://mui.com/x/react-charts/heatmap/

• ApexCharts React Heatmap Demos

https://apexcharts.com/react-chart-demos/heatmap-charts/

KKAMJJING

Site footer