Engee 文档
Notebook

机场记分牌与动态表在GenieFramework

在本文中,我们将看看创建一个web应用程序-一个带有航班表的机场记分牌。 要了解GenieFramework中web应用程序的基本逻辑,我们建议您阅读介绍статьей。在这里,我们将通过以下方式专注于处理表格 DataTable,与CSV文件交互并使用异步循环动态更新数据。 我们将特别注意为什么它用于显示表格。 DataTable 而不仅仅是 DataFrame.

board.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:提供 DataTable 以在web界面中显示表格。
  • DataFrames, Dates, CSV:需要使用表格数据,时间格式化和文件操作。
    每个包都扮演着自己的角色,为应用程序提供了最少的工具集。
数据生成

功能 generate_flight_data() 创建飞行表:
-返回一个对象 DataFrame 有四列:

  • FlightNumber:航班号("SU123","AF456","BA789")。
  • Destination:目的地("莫斯科","巴黎","伦敦")。
  • DepartureTime 出发时间以"HH:MM"格式,基于当前时间加上随机偏移(1-5小时)。
  • Status:航班状态("准时"、"延误"、"取消")。
    -此功能模拟记分牌的初始数据,然后在应用程序的操作过程中更改记分牌。
数据模型:变量

@app 定义数据模型:

  • @out current_time:包含当前时间字符串的响应变量("Current time:HH:MM:SS")。 它最初在启动时设置,稍后更新。
  • @out flight_table:反应型变量 DataTable,最初为空(DataTable(DataFrame())). 当应用程序被加载时,它将被填充数据。
    这些变量可在界面中显示,并在更改时自动更新。
数据模型:初始化和更新

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

  • isready 和他的角色:
    • isready —这是内置的反应变量Stipple,它最初具有值 false. 她变成了 true 当客户端(浏览器)完全加载页面并通过WebSocket与服务器建立连接时。
    • @onchange isready 表示块内的代码执行一次,当 isreadyfalsetrue 也就是说,在客户端第一次成功下载应用程序时。 这并不意味着更新仅限于这一刻。 — @onchange 它运行一次代码,但我们可以在其中启动持久进程。
      -我们使用 @onchange isready 以确保数据初始化和更新周期的开始仅在接口准备好操作之后发生。 如果没有这一点,代码可能会在与客户端建立通信之前执行得太早,这将导致同步错误。
      -初始化:
      -初始表正在创建 initial_df 通过 generate_flight_data().
      -数据写入文件 flight_data.csv.
    • flight_table 更新与 DataTable(initial_df).
      -异步循环:
      -通过开始 @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 它不打算显示在web界面中。 它表示程序内存中的数据,但它没有将其传输到浏览器或将其呈现为HTML表的内置逻辑。

DataTableStipple.Tables 解决了这个问题:
-反应性: DataTable 与点画反应系统集成。 在更改数据时 flight_table 界面会自动更新,而不需要手动重绘表。
-网页格式: DataTable 皈依者 DataFrame 到与类星体(Stipple用于接口的框架)兼容的结构,以所需的格式添加标题和数据。
-简单:使用 table(:flight_table) 允许您显示数据,而无需编写复杂的HTML或JavaScript代码。 如果我们用的只是 DataFrame,我将不得不手动将其转换为字典数组(Vector{Dict})并将其传递给接口,这使代码复杂化。

因此, DataFrame —这是"原始"数据, DataTable -他们和web界面之间的"桥梁",提供方便和自动化。


如何启动应用程序?

使用当前脚本转到文件夹并执行下面的单元格。

因此,应打开包含web应用程序的窗口。

如果它没有在单独的选项卡中打开,请单击输出单元格中的链接。

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. 为了充分理解逻辑,我们建议快速查看整个代码—这将帮助您了解所有部分是如何相互连接的。