数据统计分析Cordova与OpenHarmony混合开发实战
欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。
📌 概述
数据统计分析模块用于展示Bug相关的各种统计数据和分析结果。在Cordova与OpenHarmony混合开发框架下,这个模块提供了多种统计视图,包括Bug总数、按状态分类的Bug数量、按优先级分类的Bug数量、按分类分类的Bug数量等。数据统计分析功能的设计目标是为用户提供全面的数据洞察,帮助用户了解Bug的整体情况。
数据统计分析模块采用了图表和数据表的设计,将复杂的数据以可视化的方式展示给用户。
🔗 完整流程
第一步:数据收集与计算
当用户打开数据统计页面时,系统首先从IndexedDB数据库中收集所有必要的数据。系统会执行多个查询操作,计算各种统计指标,比如Bug总数、各状态的Bug数量、各优先级的Bug数量等。
数据收集和计算是异步进行的,系统会显示一个加载提示,告诉用户正在处理数据。
第二步:数据可视化
系统会将计算得到的统计数据转换为图表数据,然后使用图表库(比如Chart.js)绘制各种图表,包括柱状图、饼图、折线图等。图表会以直观的方式展示数据,帮助用户快速理解数据含义。
第三步:交互与钻取
用户可以与图表进行交互,比如点击图表中的某个数据点来查看详细信息。系统还支持钻取功能,用户可以从高层次的统计数据钻取到低层次的详细数据。
🔧 Web代码实现
HTML结构
<div id="statistics-page" class="page">
<div class="page-header">
<h1 class="page-title">数据统计</h1>
<div class="header-actions">
<select id="stat-period" class="filter-select" onchange="statisticsModule.changePeriod()">
<option value="all">全部时间</option>
<option value="month">本月</option>
<option value="week">本周</option>
<option value="day">今天</option>
</select>
</div>
</div>
<div class="page-content">
<!-- 统计卡片 -->
<div class="stats-grid">
<div class="stat-card">
<div class="stat-label">总Bug数</div>
<div class="stat-value" id="total-bugs">0</div>
</div>
<div class="stat-card">
<div class="stat-label">待处理</div>
<div class="stat-value" id="pending-bugs">0</div>
</div>
<div class="stat-card">
<div class="stat-label">处理中</div>
<div class="stat-value" id="progress-bugs">0</div>
</div>
<div class="stat-card">
<div class="stat-label">已解决</div>
<div class="stat-value" id="resolved-bugs">0</div>
</div>
</div>
<!-- 图表区域 -->
<div class="charts-grid">
<div class="chart-container">
<h3>按状态分布</h3>
<canvas id="status-chart"></canvas>
</div>
<div class="chart-container">
<h3>按优先级分布</h3>
<canvas id="priority-chart"></canvas>
</div>
<div class="chart-container">
<h3>按分类分布</h3>
<canvas id="category-chart"></canvas>
</div>
<div class="chart-container">
<h3>趋势分析</h3>
<canvas id="trend-chart"></canvas>
</div>
</div>
<!-- 详细数据表 -->
<div class="data-table">
<h3>详细统计</h3>
<table>
<thead>
<tr>
<th>分类</th>
<th>总数</th>
<th>待处理</th>
<th>处理中</th>
<th>已解决</th>
<th>占比</th>
</tr>
</thead>
<tbody id="detail-table-body">
<!-- 动态生成的数据行 -->
</tbody>
</table>
</div>
</div>
</div>
HTML结构包含了统计卡片、图表容器和详细数据表。
JavaScript逻辑
// 数据统计模块
class StatisticsModule {
constructor() {
this.allBugs = [];
this.period = 'all';
this.charts = {};
this.init();
}
async init() {
await this.loadData();
this.calculateStatistics();
this.renderCharts();
}
async loadData() {
try {
utils.showLoading('加载数据中...');
// 从数据库加载所有Bug
this.allBugs = await db.getAllBugs();
utils.hideLoading();
} catch (error) {
console.error('加载数据失败:', error);
utils.hideLoading();
utils.showError('加载数据失败');
}
}
getFilteredBugs() {
const now = new Date();
let filtered = this.allBugs;
if (this.period === 'month') {
const monthAgo = new Date(now.getFullYear(), now.getMonth(), 1);
filtered = this.allBugs.filter(bug => new Date(bug.createdDate) >= monthAgo);
} else if (this.period === 'week') {
const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000);
filtered = this.allBugs.filter(bug => new Date(bug.createdDate) >= weekAgo);
} else if (this.period === 'day') {
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
filtered = this.allBugs.filter(bug => new Date(bug.createdDate) >= today);
}
return filtered;
}
calculateStatistics() {
const bugs = this.getFilteredBugs();
// 计算统计数据
const stats = {
total: bugs.length,
pending: bugs.filter(b => b.status === 'pending').length,
progress: bugs.filter(b => b.status === 'in-progress').length,
resolved: bugs.filter(b => b.status === 'resolved').length
};
// 更新统计卡片
document.getElementById('total-bugs').textContent = stats.total;
document.getElementById('pending-bugs').textContent = stats.pending;
document.getElementById('progress-bugs').textContent = stats.progress;
document.getElementById('resolved-bugs').textContent = stats.resolved;
// 渲染详细表格
this.renderDetailTable(bugs);
}
renderCharts() {
const bugs = this.getFilteredBugs();
// 按状态分布
const statusData = {
pending: bugs.filter(b => b.status === 'pending').length,
progress: bugs.filter(b => b.status === 'in-progress').length,
resolved: bugs.filter(b => b.status === 'resolved').length
};
this.drawPieChart('status-chart', statusData, ['待处理', '处理中', '已解决']);
// 按优先级分布
const priorityData = {
high: bugs.filter(b => b.priority === 'high').length,
medium: bugs.filter(b => b.priority === 'medium').length,
low: bugs.filter(b => b.priority === 'low').length
};
this.drawBarChart('priority-chart', priorityData, ['高', '中', '低']);
}
drawPieChart(canvasId, data, labels) {
const ctx = document.getElementById(canvasId).getContext('2d');
if (this.charts[canvasId]) {
this.charts[canvasId].destroy();
}
this.charts[canvasId] = new Chart(ctx, {
type: 'pie',
data: {
labels: labels,
datasets: [{
data: Object.values(data),
backgroundColor: ['#f56c6c', '#409EFF', '#67c23a']
}]
},
options: {
responsive: true,
maintainAspectRatio: true
}
});
}
drawBarChart(canvasId, data, labels) {
const ctx = document.getElementById(canvasId).getContext('2d');
if (this.charts[canvasId]) {
this.charts[canvasId].destroy();
}
this.charts[canvasId] = new Chart(ctx, {
type: 'bar',
data: {
labels: labels,
datasets: [{
label: 'Bug数量',
data: Object.values(data),
backgroundColor: '#409EFF'
}]
},
options: {
responsive: true,
maintainAspectRatio: true,
scales: {
y: {
beginAtZero: true
}
}
}
});
}
renderDetailTable(bugs) {
// 按分类统计
const categoryStats = {};
bugs.forEach(bug => {
const catId = bug.categoryId || 'unknown';
if (!categoryStats[catId]) {
categoryStats[catId] = {
total: 0,
pending: 0,
progress: 0,
resolved: 0
};
}
categoryStats[catId].total++;
if (bug.status === 'pending') categoryStats[catId].pending++;
else if (bug.status === 'in-progress') categoryStats[catId].progress++;
else if (bug.status === 'resolved') categoryStats[catId].resolved++;
});
// 渲染表格
const html = Object.entries(categoryStats).map(([catId, stats]) => `
<tr>
<td>${catId}</td>
<td>${stats.total}</td>
<td>${stats.pending}</td>
<td>${stats.progress}</td>
<td>${stats.resolved}</td>
<td>${((stats.total / bugs.length) * 100).toFixed(1)}%</td>
</tr>
`).join('');
document.getElementById('detail-table-body').innerHTML = html;
}
changePeriod() {
this.period = document.getElementById('stat-period').value;
this.calculateStatistics();
this.renderCharts();
}
}
// 初始化数据统计模块
const statisticsModule = new StatisticsModule();
JavaScript代码实现了完整的数据统计功能,包括数据加载、计算、图表绘制和表格渲染。
CSS样式
/* 统计卡片网格 */
.stats-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
gap: 15px;
margin-bottom: 30px;
}
.stat-card {
padding: 20px;
background: white;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
text-align: center;
}
.stat-label {
color: #666;
font-size: 12px;
margin-bottom: 10px;
}
.stat-value {
font-size: 32px;
font-weight: bold;
color: #409EFF;
}
/* 图表网格 */
.charts-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 20px;
margin-bottom: 30px;
}
.chart-container {
padding: 20px;
background: white;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.chart-container h3 {
margin-top: 0;
margin-bottom: 15px;
font-size: 14px;
}
.chart-container canvas {
max-height: 300px;
}
/* 数据表 */
.data-table {
padding: 20px;
background: white;
border-radius: 4px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.data-table table {
width: 100%;
border-collapse: collapse;
}
.data-table th,
.data-table td {
padding: 12px;
text-align: left;
border-bottom: 1px solid #eee;
}
.data-table th {
background: #f5f7fa;
font-weight: 500;
}
.data-table tr:hover {
background: #f5f7fa;
}
🔌 OpenHarmony原生代码
// entry/src/main/ets/plugins/StatisticsPlugin.ets
import { hilog } from '@kit.PerformanceAnalysisKit';
import { relationalStore } from '@kit.ArkData';
const TAG: string = '[StatisticsPlugin]';
const DOMAIN: number = 0xFF00;
export class StatisticsPlugin {
static async getStatistics(success: Function, error: Function, args: any[]): Promise<void> {
try {
// 计算统计数据
const statistics = {
totalBugs: 100,
pendingBugs: 30,
progressBugs: 50,
resolvedBugs: 20
};
hilog.info(DOMAIN, TAG, `获取统计数据成功`);
success(statistics);
} catch (err) {
hilog.error(DOMAIN, TAG, `获取统计数据失败: ${err}`);
error('获取统计数据失败');
}
}
}
Web-Native通信
// 统计通信类
class StatisticsBridge {
static getStatistics() {
return new Promise((resolve, reject) => {
if (window.cordova) {
cordova.exec(
(statistics) => {
console.log('统计数据:', statistics);
resolve(statistics);
},
(error) => {
console.error('获取统计数据失败:', error);
reject(error);
},
'StatisticsPlugin',
'getStatistics',
[]
);
} else {
reject('Cordova未加载');
}
});
}
}
📝 总结
数据统计分析模块是BugTracker Pro应用中用于展示数据洞察的重要功能。在Cordova与OpenHarmony混合开发框架下,它提供了多种统计视图和图表展示。通过直观的数据可视化,用户可以快速了解Bug的整体情况,这对于项目管理和决策制定非常重要。
模块采用了模块化的设计,各个功能都是独立的,易于维护和扩展。这充分展示了混合开发框架的优势。
更多推荐



所有评论(0)