AnyMath 文档
Notebook

TabaegraergaergenieFramework

在本文中,我们将探讨如何创建一个Web应用程序——一个显示航班信息的机场信息屏。 为了熟悉 GenieFramework 中 Web 应用程序的基本逻辑,建议您先阅读入门文章。 本文将重点介绍如何通过DataTable 操作表格、与CSV文件交互,以及使用异步循环动态更新数据。我们将特别关注为何使用DataTable 来显示表格,而不是简单地使用DataFrameboard.png

应用程序代码

using GenieFramework
using Stipple
using Stipple.Tables
using DataFrames
using Dates
using CSV

function generate_flight_data()
    DataFrame(
        "Номер рейса"=>["SU123", "AF456", "BA789"],
        "Назначение"=>["Москва", "Париж", "Лондон"],
        "Время отправления" => [Dates.format(now() + Hour(rand(1:5)), "HH:MM") for _ in 1:3],
        "Статус" => ["Вовремя", "Задержан", "Отменен"]
    )
end

@app begin
    @out current_time = "Текущее время: " * Dates.format(now(), "HH:MM:SS")
    @out flight_table = DataTable(DataFrame())  # Пустая таблица изначально

    @onchange isready begin
        initial_df = generate_flight_data()
        CSV.write("flight_data.csv", initial_df)
        flight_table = DataTable(initial_df)

        @async while true
            sleep(5)
            current_time = "Текущее время: " * Dates.format(now(), "HH:MM:SS")
            df = CSV.read("flight_data.csv", DataFrame, types=String)
            df.Status[rand(1:3)] = rand(["Вовремя", "Задержан", "Отменен"])
            CSV.write("flight_data.csv", df)
            flight_table = DataTable(df)
        end
    end
end

function ui()
    [
        h3("{{current_time}}"),
        table(:flight_table; dense=true, flat=true)
    ]
end

@page("/", ui)

程序逻辑:分步分析

引入包

使用了以下包:

  • GenieFramework:用于创建Web应用程序的主要框架。
  • Stipple:提供响应式功能,并实现服务器与界面之间的通信。
  • Stipple.Tables:提供用于在 Web 界面中显示表格的DataTable
  • DataFramesDatesCSV:用于处理表格数据、时间格式化和文件操作。
    每个包都发挥着各自的作用,为应用程序提供了一套最基本的工具。
数据生成

函数 generate_flight_data() 用于生成航班表:

  • 返回一个对象 DataFrame ,包含四列:
    - FlightNumber`` :航班号(“SU123”、“AF456”、“BA789”)。
    -Destination :目的地(“Moscow”、“Paris”、“London”)。
    -DepartureTime :以“HH:MM”格式表示的起飞时间,基于当前时间加上一个随机偏移量(1–5小时)。
    -Status :航班状态(“准点”、“延误”、“取消”)。
  • 该函数模拟了记分板的初始数据,这些数据将在应用程序运行期间持续更新。
数据模型:变量

@app ”模块定义了数据模型:

  • @out current_time:一个响应式变量,包含表示当前时间的字符串(“当前时间:HH:MM:SS”)。该变量在启动时初始化,随后会进行更新。
  • @out flight_table: 一个响应式类型变量DataTable ,初始为空(DataTable(DataFrame()) )。应用程序加载时,该变量将被填充数据。
    这些变量可在界面中显示,且当其值发生变化时,界面会自动更新。
数据模型:初始化和更新

处理程序@onchange isready 控制应用程序逻辑:

  • isready 及其作用
    -isready — 这是 Stipple 的内置响应式变量,初始值为false 。当客户端(浏览器)完全加载页面并通过 WebSocket 与服务器建立连接后,该值将变为true
    -@onchange isready 表示当isready 的值从false 变为true 时,即客户端首次成功下载应用程序时,该代码块内的代码将被执行一次。这并不意味着更新仅限于这一时刻。—@onchange 它会执行一次代码,但我们可以在其中启动持久化进程。
    • 我们使用@onchange isready 来确保只有在接口准备就绪后,才会进行数据初始化和更新周期的启动。如果没有这一机制,代码可能会在与客户端建立通信之前过早执行,从而导致同步错误。
  • 初始化
    • 通过generate_flight_data() 创建初始表initial_df
    • 将数据写入文件flight_data.csv
    • 通过DataTable(initial_df) 更新flight_table
  • 异步循环
  • 通过@async while true 启动,该函数会创建一个后台任务。
    • 每 5 秒(sleep(5) ):
  • 更新current_time
    • 从参数文件types=String 中读取数据,以保存字符串格式。
    • 随机更改一个航班的状态。
    • 将更新后的数据写入文件,并赋值给 的flight_table`` 。
    界面

函数 ui() 用于设置界面外观:

  • h3("{{current_time}}"):显示当前时间,该时间会自动更新。
  • table(:flight_table; dense=true, flat=true):创建一个与 flight_table`` 关联的表格。
    -dense=true 使表格布局紧凑。
    -flat=true 移除阴影以实现简洁设计。
    -DataTable 根据列名DataFrame 自动生成表头。
页面注册
  • @page("/", ui):表示可通过根路由“/”访问该接口。至此,应用程序的配置已完成。

为什么是DataTable 而不是简单的DataFrame

DataFrame —— 这是一个功能强大的 Julia 工具,用于在代码中处理表格数据。它非常适合进行数据操作:过滤、排序和计算。 然而,仅凭DataFrame 本身,它并不适合在网页界面中显示。它虽然能在程序内存中呈现数据,但并不具备将数据传输至浏览器或渲染为HTML表格的内置逻辑。

来自Stipple.TablesDataTable 解决了这一问题:

  • 响应性DataTable 与 Stipple 响应性系统集成。当flight_table 中的数据发生变化时,界面会自动更新,无需手动重绘表格。
  • Web 格式化DataTableDataFrame 转换为与 Quasar(Stipple 用于界面渲染的框架)兼容的结构,并按所需格式添加表头和数据。
  • 简便性:使用table(:flight_table) 可以无需编写复杂的 HTML 或 JavaScript 代码即可显示数据。如果仅使用DataFrame ,则必须手动将其转换为字典数组(Vector{Dict} ),并将其传递给界面,这会增加代码的复杂度。

因此,DataFrame 代表“原始”数据,而DataTable 则充当数据与 Web 界面之间的“桥梁”,提供了便利性和自动化功能。

---### 如何启动应用程序?

转到包含当前脚本的文件夹,并运行下方的单元格。

这将打开一个显示 Web 应用程序的窗口。

如果未在单独的标签页中打开,请点击输出单元格中的链接。

-match(r"'(https?://[^']+)'" 允许您根据 的genie.start 函数的输出结果,使用正则表达式查找链接
-Markdown.parse 该功能用于在输出单元格中显示“可点击”链接。

In [ ]:
using Markdown
cd(@__DIR__)

app_url = string(engee.genie.start(string(@__DIR__,"/app.jl")))

Markdown.parse(match(r"'(https?://[^']+)'",app_url)[1])
Out[0]:

using Markdown
cd(@DIR)

app_url = string(engee.genie.start(string(@DIR,"/app.jl")))

Markdown.parse(match(r"'(https?://[^']+)'",app_url)[1])

结论

本应用演示了如何使用动态表格创建机场信息显示屏。我们探讨了生成数据、将其保存到文件、通过异步循环更新数据,以及使用DataTable 进行显示。每个代码块都执行各自的任务,从而实现了一个简约且功能完备的解决方案。DataTable 事实证明,这是简化表格数据集成到 Web 界面的关键要素,而这是标准 DataFrame`` 无法实现的。为了充分理解其逻辑,建议您快速浏览整个代码——这将帮助您了解各部分之间的相互关联。