TabaegraergaergenieFramework
在本文中,我们将探讨如何创建一个Web应用程序——一个显示航班信息的机场信息屏。 为了熟悉 GenieFramework 中 Web 应用程序的基本逻辑,建议您先阅读入门文章。 本文将重点介绍如何通过DataTable 操作表格、与CSV文件交互,以及使用异步循环动态更新数据。我们将特别关注为何使用DataTable 来显示表格,而不是简单地使用DataFrame 。.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。DataFrames、Dates、CSV:用于处理表格数据、时间格式化和文件操作。
每个包都发挥着各自的作用,为应用程序提供了一套最基本的工具。
数据生成
函数 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)):
- 每 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.Tables 的DataTable 解决了这一问题:
- 响应性:
DataTable与 Stipple 响应性系统集成。当flight_table中的数据发生变化时,界面会自动更新,无需手动重绘表格。 - Web 格式化:
DataTable将DataFrame转换为与 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]: