热力图组件
一个直观展示数据密度和分布的热力图组件,支持多种颜色主题和交互功能
组件简介
热力图组件是一种数据可视化工具,通过颜色的深浅来直观地展示数据的密度和分布情况。本组件适用于展示用户活动、数据热点、时间序列数据等场景,如GitHub贡献图、网站访问热图、天气温度分布等。组件支持多种颜色主题、响应式设计和交互功能,帮助用户更直观地理解数据模式和趋势。
组件特性
- 支持多种颜色主题(蓝色、红色、绿色、紫色等)
- 响应式设计,适配不同屏幕尺寸
- 交互式体验,支持悬停查看详细数据
- 可自定义网格大小和单元格尺寸
- 支持图例显示,方便用户理解数据含义
- 简洁的API接口,易于集成和扩展
- 基于CSS Grid布局,性能优良
基本使用
以下是一个基本的热力图组件示例,展示了默认蓝色主题的热力图效果:
最低
最高
高级示例
以下是几个不同场景下的热力图应用示例:
多种主题热力图
红色主题
绿色主题
紫色主题
自定义数据分布
集中式数据分布
HTML结构
<div class="heatmap-container heatmap-blue">
<div class="heatmap-controls">
<div class="control-group">
<label for="themeSelect">选择主题:</label>
<select id="themeSelect">
<option value="blue">蓝色主题</option>
<option value="red">红色主题</option>
<option value="green">绿色主题</option>
<option value="purple">紫色主题</option>
</select>
</div>
</div>
<div class="heatmap-wrapper">
<div class="heatmap-grid"></div>
<div class="heatmap-tooltip"></div>
</div>
<div class="heatmap-legend">
<div class="legend-item">
<span class="legend-color heatmap-cell-0"></span>
<span>最低</span>
</div>
<!-- 更多图例项... -->
</div>
</div>
JavaScript实现
// 热力图组件类
class Heatmap {
constructor(containerId, options = {}) {
this.container = document.getElementById(containerId);
this.gridElement = this.container.querySelector('.heatmap-grid');
this.tooltip = this.container.querySelector('.heatmap-tooltip');
this.options = { ...this.defaultOptions, ...options };
this.init();
}
defaultOptions = {
theme: 'blue',
gridSize: 52,
cellSize: 12,
generateRandomData: true
};
init() {
this.render();
this.bindEvents();
}
render() {
// 清空现有网格
this.gridElement.innerHTML = '';
// 设置网格样式
this.gridElement.style.gridTemplateColumns = `repeat(${this.options.gridSize}, ${this.options.cellSize}px)`;
// 生成数据
const data = this.generateData();
// 渲染单元格
data.forEach((value, index) => {
const cell = document.createElement('div');
cell.classList.add('heatmap-cell');
cell.classList.add(`heatmap-cell-${value}`);
// 为每个单元格存储数据值
cell.dataset.value = value;
this.gridElement.appendChild(cell);
});
}
generateData() {
const data = [];
const totalCells = this.options.gridSize * this.options.gridSize;
for (let i = 0; i < totalCells; i++) {
if (this.options.generateRandomData) {
// 生成随机数据
data.push(Math.floor(Math.random() * 8));
} else if (this.options.customData) {
// 使用自定义数据
data.push(this.options.customData[i] || 0);
} else {
data.push(0);
}
}
return data;
}
bindEvents() {
// 如果有工具提示,绑定鼠标事件
if (this.tooltip) {
const cells = this.gridElement.querySelectorAll('.heatmap-cell');
cells.forEach(cell => {
cell.addEventListener('mouseenter', (e) => {
const value = cell.dataset.value;
this.tooltip.textContent = `值: ${value}`;
this.tooltip.style.left = `${e.pageX + 10}px`;
this.tooltip.style.top = `${e.pageY - 30}px`;
this.tooltip.style.opacity = '1';
});
cell.addEventListener('mouseleave', () => {
this.tooltip.style.opacity = '0';
});
});
}
}
// 更改主题
setTheme(theme) {
// 移除所有主题类
this.container.classList.remove('heatmap-blue', 'heatmap-red', 'heatmap-green', 'heatmap-purple');
// 添加新主题类
this.container.classList.add(`heatmap-${theme}`);
this.options.theme = theme;
}
// 更改网格大小
setGridSize(size) {
this.options.gridSize = size;
this.render();
}
}
// 初始化热力图
document.addEventListener('DOMContentLoaded', function() {
const basicHeatmap = new Heatmap('basicHeatmap');
// 主题切换
document.getElementById('themeSelect').addEventListener('change', function(e) {
basicHeatmap.setTheme(e.target.value);
});
// 网格大小切换
document.getElementById('gridSizeSelect').addEventListener('change', function(e) {
basicHeatmap.setGridSize(parseInt(e.target.value));
});
// 初始化其他示例热力图
new Heatmap('redThemeGrid', { theme: 'red' });
new Heatmap('greenThemeGrid', { theme: 'green' });
new Heatmap('purpleThemeGrid', { theme: 'purple' });
// 自定义数据分布
const customData = generateConcentratedData(52);
new Heatmap('customDataGrid', { customData: customData, generateRandomData: false });
// 生成集中式数据分布
function generateConcentratedData(size) {
const data = [];
const center = Math.floor(size / 2);
for (let y = 0; y < size; y++) {
for (let x = 0; x < size; x++) {
const distance = Math.sqrt(Math.pow(x - center, 2) + Math.pow(y - center, 2));
// 中心区域数值较高,向外逐渐降低
const value = Math.max(0, Math.min(7, 7 - Math.floor(distance / 2)));
data.push(value);
}
}
return data;
}
});
使用指南
以下是如何在您的项目中集成和使用热力图组件的步骤:
- 引入CSS文件:将
heatmap.css文件添加到您的项目中,并在HTML文件中引入。 - 创建HTML结构:使用示例中的HTML结构创建热力图容器。
- 初始化组件:使用JavaScript创建Heatmap类的实例,并根据需要配置选项。
- 自定义配置:您可以通过options对象自定义热力图的主题、网格大小、单元格尺寸等属性。
- 数据绑定:您可以提供自定义数据数组,或者使用组件自动生成的随机数据。
- 事件处理:组件内置了基本的交互事件,您也可以根据需要添加自定义事件处理器。
主题定制
热力图组件支持通过CSS自定义颜色主题。要创建新的主题,您只需要在CSS中定义相应的颜色类:
自定义主题CSS
/* 自定义橙色主题 */
.heatmap-orange .heatmap-cell-0 { background-color: #fff8eb; }
.heatmap-orange .heatmap-cell-1 { background-color: #ffe8c3; }
.heatmap-orange .heatmap-cell-2 { background-color: #ffd699; }
.heatmap-orange .heatmap-cell-3 { background-color: #ffc166; }
.heatmap-orange .heatmap-cell-4 { background-color: #ffad33; }
.heatmap-orange .heatmap-cell-5 { background-color: #ff9a00; }
.heatmap-orange .heatmap-cell-6 { background-color: #e68a00; }
.heatmap-orange .heatmap-cell-7 { background-color: #cc7a00; }