首先有很多成熟的heatmap封装直接调用就好,不需要重复造轮子。
但从零打造一个heatmap,可以少很多条条框框,按照自己的想法去个性化定制,同时也是对相关知识的复习。
我能想到的有三种方案可以实现这个需要
我们先采用原生纯html的方式来实现,这样的技术债务最少。也是目前最有思路的方式,后面可以考虑用别的方式重构,也可以作为学习相应技术的素材。
首先我们知道的是heatmap就是大小相同颜色深浅不同的格子的组合,通过颜色的变化来表达数据的分布情况。 热力图根据名字最初应该是用于展示热力温度的变化情况。 比如在一张地图上,通过对不同区域进行着色,能够直观的观察到哪些区域温度更热或者更冷。
当然延申出来的场景有很多,对于前端来说,可以通过统计网页鼠标经常滑动点击的区域,判断用户的注意力容易集中在那块,然后在热区放置重要的信息。
对github用户来说,最直观的就是github个人主页上那显眼的深深浅浅的绿色小格子了。他是基于日期的,每一天带代表一个格子,深深浅浅的绿色代表了当天的commit数量,可以很直观的观察到牛马一段时间范围类的贡献大小。
我的目标是实现一个按年度统计每日阅读情况的热力图。
能基于现有技术栈实现一个和整体风格一致的热力图, 并且能随着网站的主题调整而色彩变化,支持响应式,比如在手机上垂直显示,在电脑端横向显示。
本文的代码目前包含创建一个基本的github风格横向热力图。
得到的结果如下

但这个grid仅仅是53*7的矩阵,并没有和日期对应起来,我们需要根据实际情况掐头去尾,将星期数据和实际的格子对应起来。
moment 时间库来处理日期:将年度数据按照周存储成二维数组。
Array.from() 生成的数组替换成实际日期数组
有了这个基本的grid后,在对应的cell中渲染不同的背景颜色就好了,一般来说根据数据的值分成几个区间,每个区间对应样式。
比如说我这儿根据每日阅读的时间等分成5等分,每个区间对应一个tailwind的class。 这里也可以根据数据的不同采用不同的策略来给数据分组。
需要注意的一点是tailwind是在构建的时候生成类名的,所以无法检测到动态生成的类名,所以
bg-${color}-${value}这种写法是无效的。
clsx 将className合并就好了。代码中的summarys是一个对象数组,结构如下:

使用 Shadcn 的 tooltip 给每个cell增加tooltip.
先将cell提取成单独的组件
随后将其用tooltip包裹起来,并修改默认样式,,不要忘了处理不需要tooltip的单元格
这样一个类似于github的热力图主体部分就基本完成了

首先在heatmap组件上方添加月份信息 使用grid布局,利用 moment.months() 来获取月份信息,需要注意localization
其次使用类似的方法加上星期数据
最终成品如下:

从零开始实现一个heatmap虽无必要,但却也可以享受技术DIY带来的乐趣,对于掌握前端基础知识大有裨益。
在搭建过程中,不仅需要考虑实际数据的组织形式,还需要考虑日期的计算匹配,同时也是对Grid布局和tailwind的一次复习,更是对shadcn组件的一次实践。
首先有很多成熟的heatmap封装直接调用就好,不需要重复造轮子。
但从零打造一个heatmap,可以少很多条条框框,按照自己的想法去个性化定制,同时也是对相关知识的复习。
我能想到的有三种方案可以实现这个需要
我们先采用原生纯html的方式来实现,这样的技术债务最少。也是目前最有思路的方式,后面可以考虑用别的方式重构,也可以作为学习相应技术的素材。
首先我们知道的是heatmap就是大小相同颜色深浅不同的格子的组合,通过颜色的变化来表达数据的分布情况。 热力图根据名字最初应该是用于展示热力温度的变化情况。 比如在一张地图上,通过对不同区域进行着色,能够直观的观察到哪些区域温度更热或者更冷。
当然延申出来的场景有很多,对于前端来说,可以通过统计网页鼠标经常滑动点击的区域,判断用户的注意力容易集中在那块,然后在热区放置重要的信息。
对github用户来说,最直观的就是github个人主页上那显眼的深深浅浅的绿色小格子了。他是基于日期的,每一天带代表一个格子,深深浅浅的绿色代表了当天的commit数量,可以很直观的观察到牛马一段时间范围类的贡献大小。
我的目标是实现一个按年度统计每日阅读情况的热力图。
能基于现有技术栈实现一个和整体风格一致的热力图, 并且能随着网站的主题调整而色彩变化,支持响应式,比如在手机上垂直显示,在电脑端横向显示。
本文的代码目前包含创建一个基本的github风格横向热力图。
得到的结果如下

但这个grid仅仅是53*7的矩阵,并没有和日期对应起来,我们需要根据实际情况掐头去尾,将星期数据和实际的格子对应起来。
moment 时间库来处理日期:将年度数据按照周存储成二维数组。
Array.from() 生成的数组替换成实际日期数组
有了这个基本的grid后,在对应的cell中渲染不同的背景颜色就好了,一般来说根据数据的值分成几个区间,每个区间对应样式。
比如说我这儿根据每日阅读的时间等分成5等分,每个区间对应一个tailwind的class。 这里也可以根据数据的不同采用不同的策略来给数据分组。
需要注意的一点是tailwind是在构建的时候生成类名的,所以无法检测到动态生成的类名,所以
bg-${color}-${value}这种写法是无效的。
clsx 将className合并就好了。代码中的summarys是一个对象数组,结构如下:

使用 Shadcn 的 tooltip 给每个cell增加tooltip.
先将cell提取成单独的组件
随后将其用tooltip包裹起来,并修改默认样式,,不要忘了处理不需要tooltip的单元格
这样一个类似于github的热力图主体部分就基本完成了

首先在heatmap组件上方添加月份信息 使用grid布局,利用 moment.months() 来获取月份信息,需要注意localization
其次使用类似的方法加上星期数据
最终成品如下:

从零开始实现一个heatmap虽无必要,但却也可以享受技术DIY带来的乐趣,对于掌握前端基础知识大有裨益。
在搭建过程中,不仅需要考虑实际数据的组织形式,还需要考虑日期的计算匹配,同时也是对Grid布局和tailwind的一次复习,更是对shadcn组件的一次实践。