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>
相关推荐
黄尚圈圈3 小时前
Vue 中引入 ECharts 的详细步骤与示例
前端·vue.js·echarts
2401_857622666 小时前
SpringBoot框架下校园资料库的构建与优化
spring boot·后端·php
2402_857589366 小时前
“衣依”服装销售平台:Spring Boot框架的设计与实现
java·spring boot·后端
哎呦没8 小时前
大学生就业招聘:Spring Boot系统的架构分析
java·spring boot·后端
_.Switch8 小时前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
杨哥带你写代码9 小时前
足球青训俱乐部管理:Spring Boot技术驱动
java·spring boot·后端
AskHarries10 小时前
读《show your work》的一点感悟
后端
A尘埃10 小时前
SpringBoot的数据访问
java·spring boot·后端
yang-230710 小时前
端口冲突的解决方案以及SpringBoot自动检测可用端口demo
java·spring boot·后端
Marst Code10 小时前
(Django)初步使用
后端·python·django