Engee 文档

创建第一个仪表板

仪表盘是一种反应式应用程序,可显示可视化数据,并允许用户通过按钮或滑块等控件进行交互。每次用户交互时,应用程序都会执行代码来处理底层数据,并及时将这些变化反映在用户界面上。所有这些都是实时进行的,无需重新加载页面。

本指南将向您展示如何创建一个仪表盘,显示随机数矢量的统计数据,并允许用户更改矢量的长度。代码将主要依赖`Stipple.jl` 软件包实现的反应式用户界面功能,该软件包已包含在`GenieFramework.jl` 元软件包中。

preview

项目结构

在构建 Genie 应用程序时,通常的假设是您已经有了一些执行数据分析的代码,并希望将其转化为网络应用程序。在本演示中,我们将从包含以下内容的`StatisticAnalysis` 模块开始:

module StatisticAnalysis

export gen_numbers, calc_mean

function gen_numbers(N::Int)
    return rand(N)
end

function calc_mean(x::Vector{Float64})
    return round(sum(x) / length(x); digits=4)
end
end

为演示程序创建一个项目文件夹,并在其中创建`lib/` 文件夹,将`StatisticAnalysis.jl` 文件放入其中。程序运行时,该文件夹的内容将自动加载到`Main` 模块中。

接下来是`app.jl` 文件,它是应用程序的主要入口,也是我们实现仪表盘的地方。在项目根目录下创建包含这些内容的文件:

module App
using Main.StatisticAnalysis
using GenieFramework, PlotlyBase
@genietools

@app begin
    #reactive code goes here
end

function ui()
    p("") #initialized to an empty paragraph
end

@page("/", ui)
end

代码分为三个部分:

  • 导入`GenieFramework` 、PlotlyBase 和`StatisticAnalysis.jl` 中的数据分析代码。

  • @app 块中的反应代码,用于控制仪表盘的交互性。

  • ui 函数中的用户界面定义。

  • 通过`@page` 进行路由定义,将 URL 与`ui` 提供的页面视图连接起来。

文件结构应该是这样的:

├── app.jl
└── lib
    └── StatisticAnalysis.jl

要启动应用程序,请在 Julia REPL 中运行此文件:

using GenieFramework; Genie.loadapp(); up()

服务器将在`8000` 端口启动,您可以通过`https://localhost:8000` 访问应用程序。要停止服务器,请在 REPL 中执行`down()` 。

现在让我们添加用户界面代码和反应代码,以实现以下功能:

  • 控制随机数向量长度的滑块。

  • 显示向量平均值的文本行。

  • 向量的直方图。

滑块和均值 - 用户界面

您可以使用`StippleUI.jl` 软件包提供的低代码应用程序接口,用纯 Julia 构建用户界面,该软件包会自动包含在`using GenieFramework` 中。它提供了多种调用,如`textfield` 或`slider` ,用于生成用户界面组件的 HTML 代码:

julia> slider(1:1:1000, :N)
"<q-slider :min=1 v-model=\"N\" :max=1000 :step=1></q-slider>"

有关可用组件的完整列表,请参见component galleryAPI

要将滑块组件和均值显示纳入用户界面,请在`ui` 函数中添加以下代码:

function ui()
    row([
    cell(class="st-col col-3", [
        h1("A simple dashboard"),
        slider(1:1:1000, :N),
        p("The average of {{N}} random numbers is {{m}}", class="st-module"),
        ])
    ])
end

<div style="width: 35%;" class="pt-6"><div class=" border border-gray-400 rounded">[discrete.text-center] ====== 简单的仪表盘

{{N}} 随机数的平均值是{{m}</div></div>}

</div>

这定义了页面布局,其中`row` 和`cell` 使用`st-col, col-3` CSS 类设置列宽。在单元格内,将显示标题、滑块和段落。 slider 组件的参数包括取值范围,以及用于存储所选数字的反应式变量的符号名称。这个变量目前还不存在。我们稍后将其添加到反应代码中。

+{{variable}}+`语法在段落`p 中用于显示反应式变量的内容。此外,该语法还可以接受任何有效的 Javascript 表达式,因此您可以编写类似 `{{m.toFixed(2)}}`来显示带两位小数的平均值。

您可以在 REPL 中调用`ui` 函数,检查它生成的 HTML,结果如下

<div class="row">
   <div class="st-col col-3 st-col col">
      <h1>A simple dashboard</h1>
      <q-slider :min=1 v-model="N" :max=1000 :step=1 ></q-slider>
      <p class="st-module">The average of {{N}} random numbers is {{m}}</p>
   </div>
</div>

由于代码中的`N, m` 变量目前只是占位符,因此用户界面无法运行。让我们添加反应代码,使其具有交互性。

滑块和平均值—​逻辑

当滑块移动时,我们要为矢量长度设置一个新值,并显示更新后的平均值。为此,首先在`@app` 代码块中声明一个反应变量`N` 如下:

@app begin
   @in N = 0
end

使用`@in` 标记可使变量具有反应性,并可从用户界面写入。只要浏览器用户界面中的变量值发生变化,该变化就会自动传播到 Julia 代码中。同样,Julia 代码中的任何变化也会传播到用户界面。

接下来,添加一个只读输出变量来保存平均值:

@out m = 0.0

标记为`@out` 的变量只能在 Julia 代码中修改。浏览器中的任何更改都不会传播到后台。请注意,反应式变量必须始终初始化为相应类型的值。

此外,你还可以使用`@private` 宏来定义不向用户界面公开的非反应式变量。使用这些变量可以存储不在用户间共享的数据。

最后,使用`@onchange` 宏声明一个反应式处理程序,当`N` 发生变化时,该处理程序会生成一个新的向量并计算其平均值:

@app begin
    @in N = 0
    @out m = 0.0
    @onchange N begin
        x = gen_numbers(N)
        m = calc_mean(x)
    end
end

使用`@in` 、@out 和`@onchange` 可以轻松实现各种交互功能。要了解更多信息,请查看Reactivity 参考资料。

现在你应该有了一个可以工作的反应式用户界面!让我们添加直方图。

直方图

要在用户界面中显示直方图,请添加`plot` 调用:

row([
    cell(class="st-col col-3", [
        h1("A simple dashboard"),
        slider(1:1000, :N),
        p("The average of {{N}} random numbers is {{m}}", class="st-module"),
        plot(:trace, layout=:layout)
    ])
])

这将添加一个 Plotly绘图,其中`trace` 变量将保存要绘制的数据,而`layout` 则决定样式选项。

现在,声明一个空的直方图轨迹和布局变量为

@app begin
    @out trace = [histogram(x=[])]
    @out layout = PlotlyBase.Layout(title="Histogram plot")
    . . .
end

然后,添加代码,以便在`N` 发生变化时更新反应处理程序中的轨迹

@onchange N begin
    . . .
    trace = [histogram(x=x)]
end

这就是`app.jl` 中的最终反应式代码:

@app begin
    @in N = 0
    @out m = 0.0
    @out trace = []
    @out layout = PlotlyBase.Layout(title="Histogram plot")
    @onchange N begin
        x = gen_numbers(N)
        m = calc_mean(x)
        trace = [histogram(x=x)]
    end
end

就这样,你完成了第一个仪表盘!有关绘图的更多详情,请参阅Plotting 参考页面。然后,您可以继续阅读指南,添加更多功能,如multiple pagesAPI