echarts可视化的时间筛选-刘德华恭喜发财视频的数据弹幕

春节期间,各商场又响来刘德华的《恭喜发财》,许多网友戏称这是数字生命解冻了。既然大家那么关心,那我们就爬去一下B站里刘德华《恭喜发财》的弹幕数据,来看一看有什么有趣的现象。

我原来的想法是爬取视频上线以来的数据,不过操作后发现我还是太年轻了。从2022年1月30日视频上线至今,弹幕量高达8个多G,所以我只统计每天有多少条弹幕,以及弹幕的累计数据。

这里我用flask做了前后端分离,把数据存在了Mysql中,实现了图表。

在这个图表中,我们会发现,23年春节以后,视频的弹幕量有一个显著的提升。而23年春节就是《流浪地球2》的上映时间,也可以看出《流浪地球2》确实是当年的热门话题,并给刘德华带来了一波流量。

不过,我对这个图表还是不大满意,时间跨度太长了,如果能为时间加入一个筛选功能就能更好的观察一段时间内的弹幕变化。

我们试着简单写一个筛选功能,在页面中加上时间的选择按钮。

html 复制代码
    <label for="year-select">选择年份:</label>
    <select id="year-select">
        <option value="">未选择</option>
        <option value="2022">2022</option>
        <option value="2023">2023</option>
        <option value="2024">2024</option>
    </select>

    <label for="month-select">选择月份:</label>
    <select id="month-select">
        <option value="">未选择</option>
        <option value="1">1月</option>
        <option value="2">2月</option>
        <option value="3">3月</option>
        <option value="4">4月</option>
        <option value="5">5月</option>
        <option value="6">6月</option>
        <option value="7">7月</option>
        <option value="8">8月</option>
        <option value="9">9月</option>
        <option value="10">10月</option>
        <option value="11">11月</option>
        <option value="12">12月</option>
    </select>

我们要向服务器端发送这个时间的参数。

python 复制代码
    # 获取来自前端的查询参数
    selected_year = request.args.get("year", None)
    selected_month = request.args.get("month", None)

    # 构建查询
    query = db.session.query(danmu1.id, danmu1.time, danmu1.number, danmu1.allnumber)

    # 如果有年份参数,则根据年份进行过滤
    if selected_year:
        query = query.filter(extract("year", danmu1.time) == int(selected_year))

    # 如果有月份参数,则根据月份进行过滤
    if selected_month:
        query = query.filter(extract("month", danmu1.time) == int(selected_month))

在服务器端,我们用request 方法取得选择的时间,用filter方法对数据进行筛选。因为服务器中的time是按照时间格式存储的,可以用extract函数对其中的year和month进行匹配。

JS函数在接收服务器信息的时候也要进行调整,因为我们用的是GET方法,关于日期的信息会跟在请求的url链接后面。

这里最好加上一个条件判断,这样只输入年而没有月时也能正常筛选。

html 复制代码
    var option;

    var selectedYear = document.getElementById('year-select').value;
    var selectedMonth = document.getElementById('month-select').value;

    var url = "/data?year=" + selectedYear;
    if (selectedMonth !== "") {
        url += "&month=" + selectedMonth;
    }

不过这里其实还有个问题,当数据量过大时,服务器向浏览器发送的数据不一定完整,最好再人为的进行处理。

服务器:

python 复制代码
from flask import Flask, render_template, session, jsonify, request
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import extract
from datetime import datetime

app = Flask(__name__)


HOSTNAME = "127.0.0.1"
PORT = 3306
USERNAME = "root"
PASSWORD = ""
DATABASE = "bisystem"

DB_URI = f"mysql+pymysql://{ USERNAME }:{ PASSWORD }@{ HOSTNAME }:{ PORT }/{ DATABASE }?charset=utf8mb4"

app.config["SQLALCHEMY_DATABASE_URI"] = DB_URI

db = SQLAlchemy(app)


# 映射员工表
class danmu1(db.Model):
    __tablename__ = "danmu1"

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    time = db.Column(db.DateTime)
    number = db.Column(db.String(100))
    allnumber = db.Column(db.String(100))

    def to_dict(self):
        return {
            "id": self.id,
            "time": self.time,
            "number": self.number,
            "allnumber": self.allnumber,
        }


@app.route("/")
def to_index():
    return render_template("index.html")


@app.route("/data")
def get_data():
    # 获取来自前端的查询参数
    selected_year = request.args.get("year", None)
    selected_month = request.args.get("month", None)

    # 构建查询
    query = db.session.query(danmu1.id, danmu1.time, danmu1.number, danmu1.allnumber)

    # 如果有年份参数,则根据年份进行过滤
    if selected_year:
        query = query.filter(extract("year", danmu1.time) == int(selected_year))

    # 如果有月份参数,则根据月份进行过滤
    if selected_month:
        query = query.filter(extract("month", danmu1.time) == int(selected_month))

    # 执行查询
    datas = [
        {"id": items[0], "time": items[1], "number": items[2], "allnumber": items[3]}
        for items in query
    ]
    print(datas)
    # 返回结果
    return jsonify(data=datas)


if __name__ == "__main__":
    app.run(debug=True)

浏览器

html 复制代码
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.4.3/echarts.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.7.1/jquery.js"></script>
</head>

<body>
    <label for="year-select">选择年份:</label>
    <select id="year-select">
        <option value="">未选择</option>
        <option value="2022">2022</option>
        <option value="2023">2023</option>
        <option value="2024">2024</option>
    </select>

    <label for="month-select">选择月份:</label>
    <select id="month-select">
        <option value="">未选择</option>
        <option value="1">1月</option>
        <option value="2">2月</option>
        <option value="3">3月</option>
        <option value="4">4月</option>
        <option value="5">5月</option>
        <option value="6">6月</option>
        <option value="7">7月</option>
        <option value="8">8月</option>
        <option value="9">9月</option>
        <option value="10">10月</option>
        <option value="11">11月</option>
        <option value="12">12月</option>
    </select>
    <div style="width:100%;height: 600px;"></div>

    <script>
        function createchart() {
            var option;

            var selectedYear = document.getElementById('year-select').value;
            var selectedMonth = document.getElementById('month-select').value;

            var url = "/data?year=" + selectedYear;
            if (selectedMonth !== "") {
                url += "&month=" + selectedMonth;
            }

            $.ajax({
                type: "GET",
                url: url,
                success: function (response) {
                    const agg = {}
                    console.log(response.data)
                    response.data.forEach(function (item) {
                        var id = item.id;
                        var time = item.time;
                        var number = item.number;
                        var allnumber = item.allnumber;

                        var fulltime = new Date(time)
                        var year = fulltime.getUTCFullYear();
                        var month = fulltime.getUTCMonth() + 1;
                        var day = fulltime.getUTCDay()
                        var ym = year + "-" + (month < 10 ? "0" + month : month)
                        var ymd = year + "-" + (month < 10 ? "0" + month : month) + "-" + (day < 10 ? "0" + day : day)

                        if (!agg.hasOwnProperty(ymd)) {
                            agg[ymd] = {
                                name: ymd,
                                value: number,
                                allnumber: allnumber
                            }
                        }

                    })


                    const days = Object.keys(agg)

                    const seriesData = Object.values(agg).map(item => {
                        return {
                            name: item.name,
                            value: item.value,
                            allnumber: item.allnumber

                        }
                    });
                   
                    var chart = echarts.init(document.querySelector("div"))
                    console.log(days)
                    option = {
                        title: {
                            text: '每日弹幕统计',
                            left: 'center'
                        },
                        legend: {
                            data: ['弹幕']
                        },
                        xAxis: {
                            type: 'category',
                            data: days
                        },
                        yAxis: {
                            type: 'value'

                        },

                        series: [{
                            type: "line",
                            data: seriesData,
                            itemStyle: {
                                color: "rgba(237, 125,49,0.7)"
                            },
                        }]
                    };
                    option && chart.setOption(option);

                }

            })
        }
    </script>

    <script>
        document.addEventListener('DOMContentLoaded', function () {
            createchart()
        });

        // 监听年份和月份选择框的变化,当变化时重新生成图表
        document.getElementById('year-select').addEventListener('change', createchart);
        document.getElementById('month-select').addEventListener('change', createchart);
    </script>
</body>

</html>
相关推荐
小马爱打代码8 分钟前
Spring Boot项目开发常见问题及解决方案(下)
java·spring boot·后端
Q_19284999061 小时前
基于Spring Boot的工商局商家管理系统
java·spring boot·后端
web136885658711 小时前
rust教程 第一章 —— 初识rust
开发语言·后端·rust
songroom1 小时前
Rust : tokio中select!
开发语言·后端·rust
uhakadotcom2 小时前
2025年,最新的AI发展趋势是什么?
后端·面试·架构
星就前端叭3 小时前
【开源】一款基于SpringBoot的智慧小区物业管理系统
java·前端·spring boot·后端·开源
weixin_SAG3 小时前
21天掌握javaweb-->第19天:Spring Boot后端优化与部署
java·spring boot·后端
SomeB1oody4 小时前
【Rust自学】7.4. use关键字 Pt.2 :重导入与换国内镜像源教程
开发语言·后端·rust
新知图书4 小时前
Rust编程与项目实战-箱
开发语言·后端·rust
SomeB1oody4 小时前
【Rust自学】7.3. use关键字 Pt.1:use的使用与as关键字
开发语言·后端·rust