欢迎大家加入开源鸿蒙跨平台开发者社区,一起共建开源鸿蒙跨平台生态。

请添加图片描述

📌 模块概述

观影统计模块是MovieTracker应用中用于统计和分析用户观影数据的功能。系统会统计用户观看的影片数量、评分分布、分类分布等信息,并以图表的形式展示。用户可以通过统计数据了解自己的观影习惯。

该模块的主要功能包括:统计观影数量、统计评分分布、统计分类分布、生成统计报表等。通过Cordova框架与OpenHarmony原生能力的结合,实现了完整的数据统计和可视化。

观影统计需要处理大量的数据聚合和计算,同时需要提供多种统计维度。

🔗 完整流程

第一步:数据收集与聚合

系统从数据库中收集所有影片数据,按照不同的维度进行聚合。包括按分类聚合、按评分聚合、按年份聚合等。

数据聚合过程需要进行复杂的计算,如计算平均值、中位数、标准差等统计指标。

第二步:统计指标计算

根据聚合的数据计算各种统计指标,如总观影数、平均评分、最高评分、最低评分等。

同时需要计算趋势指标,如月度观影数的变化趋势等。

第三步:可视化展示

将统计数据以图表的形式展示,包括柱状图、饼图、折线图等。用户可以通过图表直观地了解观影数据。

同时需要提供详细的统计表格,显示具体的数值。

🔧 Web代码实现

观影统计HTML结构

<div id="statistics-page" class="page">
    <div class="page-header">
        <h2>观影统计</h2>
    </div>
    
    <div class="statistics-container">
        <div class="stat-cards">
            <div class="stat-card">
                <span class="label">观影总数</span>
                <span class="value" id="total-watched">0</span>
            </div>
            <div class="stat-card">
                <span class="label">平均评分</span>
                <span class="value" id="avg-rating">0.0</span>
            </div>
            <div class="stat-card">
                <span class="label">最高评分</span>
                <span class="value" id="max-rating">0</span>
            </div>
        </div>
        
        <div class="chart-container">
            <h3>分类分布</h3>
            <canvas id="category-chart"></canvas>
        </div>
        
        <div class="chart-container">
            <h3>评分分布</h3>
            <canvas id="rating-chart"></canvas>
        </div>
    </div>
</div>

统计实现

async function loadStatistics() {
    try {
        const watchedMovies = await db.getMoviesByStatus('watched');
        
        if (watchedMovies.length === 0) {
            showError('暂无观影数据');
            return;
        }
        
        // 计算基本统计
        const totalWatched = watchedMovies.length;
        const ratings = watchedMovies.map(m => m.rating).filter(r => r);
        const avgRating = ratings.length > 0 
            ? (ratings.reduce((a, b) => a + b, 0) / ratings.length).toFixed(1)
            : 0;
        const maxRating = ratings.length > 0 ? Math.max(...ratings) : 0;
        
        document.getElementById('total-watched').textContent = totalWatched;
        document.getElementById('avg-rating').textContent = avgRating;
        document.getElementById('max-rating').textContent = maxRating;
        
        // 绘制图表
        drawCategoryChart(watchedMovies);
        drawRatingChart(ratings);
    } catch (error) {
        console.error('加载统计失败:', error);
        showError('加载统计失败');
    }
}

function drawCategoryChart(movies) {
    const categoryCount = {};
    movies.forEach(m => {
        const cat = m.category || '未分类';
        categoryCount[cat] = (categoryCount[cat] || 0) + 1;
    });
    
    const ctx = document.getElementById('category-chart').getContext('2d');
    new Chart(ctx, {
        type: 'pie',
        data: {
            labels: Object.keys(categoryCount),
            datasets: [{
                data: Object.values(categoryCount),
                backgroundColor: [
                    '#FF6B6B', '#4ECDC4', '#45B7D1', '#FFA07A', '#96CEB4'
                ]
            }]
        }
    });
}

function drawRatingChart(ratings) {
    const ratingCount = {};
    for (let i = 1; i <= 10; i++) {
        ratingCount[i] = ratings.filter(r => r === i).length;
    }
    
    const ctx = document.getElementById('rating-chart').getContext('2d');
    new Chart(ctx, {
        type: 'bar',
        data: {
            labels: Object.keys(ratingCount),
            datasets: [{
                label: '影片数',
                data: Object.values(ratingCount),
                backgroundColor: '#409EFF'
            }]
        }
    });
}

🔌 OpenHarmony原生代码

统计插件

// StatisticsPlugin.ets
import { webview } from '@kit.ArkWeb';
import { common } from '@kit.AbilityKit';

export class StatisticsPlugin {
    private context: common.UIAbilityContext;
    
    constructor(context: common.UIAbilityContext) {
        this.context = context;
    }
    
    public registerStatistics(controller: webview.WebviewController): void {
        controller.registerJavaScriptProxy({
            object: new StatisticsBridge(),
            name: 'statisticsNative',
            methodList: ['calculateStats', 'generateReport']
        });
    }
}

export class StatisticsBridge {
    public calculateStats(moviesJson: string): string {
        try {
            const movies = JSON.parse(moviesJson);
            const ratings = movies.map((m: any) => m.rating).filter((r: any) => r);
            
            const stats = {
                total: movies.length,
                avgRating: ratings.length > 0 
                    ? parseFloat((ratings.reduce((a: number, b: number) => a + b, 0) / ratings.length).toFixed(1))
                    : 0,
                maxRating: ratings.length > 0 ? Math.max(...ratings) : 0,
                minRating: ratings.length > 0 ? Math.min(...ratings) : 0
            };
            
            return JSON.stringify(stats);
        } catch (error) {
            return JSON.stringify({ error: error.message });
        }
    }
    
    public generateReport(moviesJson: string): string {
        try {
            const movies = JSON.parse(moviesJson);
            
            const report = {
                generatedAt: new Date().toISOString(),
                totalMovies: movies.length,
                summary: `观看了 ${movies.length} 部影片`
            };
            
            return JSON.stringify(report);
        } catch (error) {
            return JSON.stringify({ error: error.message });
        }
    }
}

📝 总结

观影统计模块展示了Cordova与OpenHarmony混合开发中的数据统计和可视化功能。通过Web层提供统计界面和图表展示,同时利用OpenHarmony原生能力进行复杂的统计计算。

在实现这个模块时,需要注意数据计算的准确性、图表展示的清晰性、以及性能的优化。通过合理的架构设计,可以构建出高效、易用的观影统计功能。

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐