时间段统计-Cordova&openharmony日内节奏洞察
本文介绍了如何实现喝水应用中的"时间段统计"功能模块,主要包括Web端和原生端的实现方案。在Web端,通过Cordova框架实现按时间段(如00:00-06:00、06:00-12:00等)统计喝水行为,包括HTML页面结构、CSS样式设计、时间映射函数以及数据聚合逻辑。JavaScript代码将统计结果渲染为表格视图,并通过Cordova接口同步到原生侧。在OpenHarmo
一、功能概述
很多人白天忙于工作,真正记得喝水的时间往往集中在上午某个时段或晚间休息时。如果应用能够按“时间段”统计喝水行为,就可以帮助用户看清自己的日内节奏,从而有针对性地调整习惯。本篇文章围绕“时间段统计”模块展开,介绍如何在 Cordova Web 层 按小时或时间段聚合数据,并通过 OpenHarmony ArkTS 插件 将这些结果同步到原生侧,用于构建更直观的日内节奏视图。
我们将继续采用“一段代码一段说明”的形式,结合 HTML/JavaScript 和 ArkTS 示例,完成从 IndexedDB 记录到时间段分布视图的完整链路。
二、Web 端时间段统计页面结构
<div id="time-slot-page" class="page page-time-slot">
<h1>时间段喝水统计</h1>
<table class="data-table" id="table-time-slot">
<thead>
<tr>
<th>时间段</th>
<th>次数</th>
<th>总饮水量 (ml)</th>
</tr>
</thead>
<tbody id="table-time-slot-body"></tbody>
</table>
</div>
这段 HTML 定义了时间段统计页面的基础结构。time-slot-page 是页面根容器,内部的表格包含三列:时间段(如 06:00-09:00)、喝水次数和总饮水量。真实的统计数据将由 JavaScript 在运行时写入 tbody,因此这里只需要一个空的 tbody 占位元素 table-time-slot-body。统一的 data-table 样式可以和其他统计页面共用,从而降低样式维护成本。
.page-time-slot {
padding: 16px 24px;
}
#table-time-slot td:nth-child(2),
#table-time-slot td:nth-child(3) {
text-align: right;
}
CSS 为页面增加内边距,并将“次数”和“总饮水量”两列右对齐,以便在纵向比较不同时间段时更直观。这里沿用了之前统计表格的视觉规范,保证用户在不同统计页面之间切换时,体验保持一致。
三、将时间映射到时间段
function getTimeSlotKey(dateString) {
const d = new Date(dateString);
const hour = d.getHours();
if (hour < 6) return '00:00-06:00';
if (hour < 12) return '06:00-12:00';
if (hour < 18) return '12:00-18:00';
return '18:00-24:00';
}
getTimeSlotKey 是时间段统计最关键的辅助函数之一。它将喝水记录的时间(ISO 字符串)转换为四个粗粒度时间段之一:凌晨、上午、下午和晚上。实际项目中,你可以根据需求细分为更多时间段,这里为了示例简单只划分为四段。通过这样的映射,我们可以在聚合时以时间段字符串为键,统计每个时间段内的喝水次数和总饮水量。
四、按时间段聚合统计数据
async function loadTimeSlotStats() {
const records = await db.getAllDrinkRecords();
const map = new Map();
records.forEach((r) => {
const slot = getTimeSlotKey(r.date);
const current = map.get(slot) || { count: 0, total: 0 };
current.count += 1;
current.total += r.amount;
map.set(slot, current);
});
renderTimeSlotTable(map);
syncTimeSlotStatsToNative(map);
}
loadTimeSlotStats 用于从 IndexedDB 中读取所有喝水记录,并按时间段进行聚合。它遍历每条记录,使用前面定义的 getTimeSlotKey 得到时间段键值,然后在 Map 中累加对应的次数和总饮水量。聚合完成后,一方面调用 renderTimeSlotTable 渲染表格,另一方面通过 syncTimeSlotStatsToNative 将相同的数据发送给原生侧,实现数据一次计算、多端复用。
function renderTimeSlotTable(map) {
const tbody = document.getElementById('table-time-slot-body');
if (!tbody) return;
tbody.innerHTML = '';
const orderedSlots = ['00:00-06:00', '06:00-12:00', '12:00-18:00', '18:00-24:00'];
orderedSlots.forEach((slot) => {
const stat = map.get(slot) || { count: 0, total: 0 };
const tr = document.createElement('tr');
const tdSlot = document.createElement('td');
const tdCount = document.createElement('td');
const tdTotal = document.createElement('td');
tdSlot.textContent = slot;
tdCount.textContent = String(stat.count);
tdTotal.textContent = String(stat.total);
tr.appendChild(tdSlot);
tr.appendChild(tdCount);
tr.appendChild(tdTotal);
tbody.appendChild(tr);
});
}
renderTimeSlotTable 负责将聚合结果渲染到表格中。为了保证时间段的顺序固定,函数定义了一个 orderedSlots 数组,并按预设顺序依次取出对应统计值。这可以避免 Map 的遍历顺序带来的不确定性。对于不存在记录的时间段,使用 { count: 0, total: 0 } 作为默认值,让用户清晰地看到“没有在这个时间段喝过水”。通过这种方式,日内节奏的整体轮廓在一张表中就能完整呈现。
五、将时间段统计同步到原生
function syncTimeSlotStatsToNative(map) {
if (!window.cordova) {
console.warn('[TimeSlot] cordova not ready, skip native sync');
return;
}
const items = [];
map.forEach((stat, slot) => {
items.push({
slot,
count: stat.count,
total: stat.total,
});
});
cordova.exec(
() => {
console.info('[TimeSlot] sync stats success');
},
(err) => {
console.error('[TimeSlot] sync stats failed', err);
},
'WaterTrackerTimeSlot',
'setStats',
[items]
);
}
syncTimeSlotStatsToNative 将 Map 结构转换为数组,并通过 Cordova 的 exec 接口发送给 ArkTS 插件。每个数组元素包含 slot(时间段字符串)、count 和 total 三个字段。原生侧收到后可以直接在 ArkUI 中构建时间段分布视图,例如使用条形图、雷达图或者简单列表。与之前其他统计模块类似,函数在调用前检查 window.cordova 是否存在,以避免在 Cordova 尚未注入时发生错误。
document.addEventListener('DOMContentLoaded', () => {
loadTimeSlotStats();
});
在 DOMContentLoaded 事件中调用 loadTimeSlotStats,确保 DOM 结构准备就绪后再进行统计和渲染。用户每次打开时间段统计页面时,都能看到基于当前所有记录计算出的最新结果。
六、OpenHarmony ArkTS 插件与时间段统计存储
// entry/src/main/ets/plugins/WaterTrackerTimeSlotPlugin.ets
import common from '@ohos.app.ability.common';
export interface TimeSlotStatItem {
slot: string;
count: number;
total: number;
}
export class TimeSlotStatsStore {
private static _items: TimeSlotStatItem[] = [];
static setItems(items: TimeSlotStatItem[]) {
this._items = items;
}
static get items() {
return this._items;
}
}
export default class WaterTrackerTimeSlotPlugin {
context: common.UIAbilityContext;
constructor(ctx: common.UIAbilityContext) {
this.context = ctx;
}
setStats(args: Array<Object>, callbackId: number) {
const items = args[0] as TimeSlotStatItem[];
TimeSlotStatsStore.setItems(items);
console.info(`[TimeSlotPlugin] receive ${items.length} slots`);
}
}
这段 ArkTS 代码定义了时间段统计插件 WaterTrackerTimeSlotPlugin 及其数据存储 TimeSlotStatsStore。TimeSlotStatItem 接口描述了每个时间段统计项包含的字段:时间段字符串、次数和总饮水量。TimeSlotStatsStore 使用静态数组 _items 缓存最新的时间段统计结果,供 ArkUI 组件读取。插件在 setStats 方法中解析来自 Web 层的数组,将其存入存储类,并输出日志说明接收到多少个时间段的数据。
七、ArkUI 中展示日内节奏视图
// entry/src/main/ets/pages/TimeSlotStatsPage.ets
import { TimeSlotStatsStore } from '../plugins/WaterTrackerTimeSlotPlugin';
@Component
struct TimeSlotStatsView {
build() {
Column() {
Text('日内喝水节奏')
.fontSize(18)
.margin({ bottom: 8 });
TimeSlotStatsStore.items.forEach((item) => {
Row() {
Text(item.slot)
.fontSize(14);
Text(`次数:${item.count}`)
.fontSize(14)
.margin({ left: 8 });
Text(`总量:${item.total} ml`)
.fontSize(14)
.margin({ left: 8 });
}
.margin({ bottom: 4 });
});
}
.padding(16)
}
}
TimeSlotStatsView 是一个示例性的 ArkUI 组件,用于在原生界面中展示日内喝水节奏。组件遍历 TimeSlotStatsStore.items,为每个时间段渲染一行包含时间段名称、喝水次数和总饮水量的文本行。虽然这里只是基础列表,但已经可以帮助用户快速识别出自己在哪些时间段喝水最多,哪些时间段几乎没有喝水。在实际项目中,可以根据这些数据生成折线图或雷达图,以更加形象的方式呈现日内节奏。
八、小结
本篇文章以“时间段统计”为主题,展示了如何在 Cordova&openharmony 混合应用中,从时间维度挖掘出用户日内喝水节奏。Web 层通过 getTimeSlotKey 将记录时间映射到预设时间段,loadTimeSlotStats 对所有记录按时间段聚合,renderTimeSlotTable 将结果渲染到表格,syncTimeSlotStatsToNative 则将同一份数据同步给 ArkTS 插件。原生侧通过 TimeSlotStatsStore 和 WaterTrackerTimeSlotPlugin 缓存数据,ArkUI 组件 TimeSlotStatsView 则将这些信息以原生界面形式呈现给用户。
通过“一段代码一段说明”的写作方式,我们把整个数据流拆解得足够细致,便于在阅读和调试时快速定位每一步的职责。你可以在此基础上进一步细化时间段(例如每 2 小时一段)、增加过滤条件(例如只看最近 7 天的数据),或者与提醒系统联动,在用户最容易忘记喝水的时间段增加提醒频率,从而真正做到对日内节奏的有针对性优化。
欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net
更多推荐

所有评论(0)