Создание первой информационной панели
Информационная панель — это тип реактивного приложения, в котором визуализируются данные и с которым пользователь может взаимодействовать с помощью таких элементов управления, как кнопки или ползунки. На каждое действие пользователя приложение реагирует путем выполнения кода, производящего операции с базовыми данными и быстро отражающего изменения в пользовательском интерфейсе. Все это происходит в реальном времени без необходимости перезагружать страницу.
В этом руководстве вы узнаете, как создать информационную панель, на которой выводится статистика по вектору случайных чисел и которая позволяет пользователю изменять длину вектора. Код основан преимущественно на функциях реактивного пользовательского интерфейса, реализованных в пакете Stipple.jl
, который уже включен в метапакет GenieFramework.jl
.

Структура проекта
При создании приложения 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
#здесь будет реактивный код
end
function ui()
p("") #инициализируется пустым абзацем
end
@page("/", ui)
end
Кодекс делится на четыре части:
-
операторы импорта
GenieFramework
,PlotlyBase
и кода для анализа данных вStatisticAnalysis.jl
; -
реактивный код в блоке
@app
для управления интерактивностью информационной панели; -
определение пользовательского интерфейса в функции
ui
; -
определение маршрута с помощью
@page
для связывания URL-адреса с представлением страницы, предоставляемым функциейui
.
Структура файлов должна выглядеть так:
├── app.jl └── lib └── StatisticAnalysis.jl
Чтобы запустить приложение, выполните в REPL Julia следующие команды.
using GenieFramework; Genie.loadapp(); up()
Сервер запустится на порте 8000
, и приложение будет доступно по адресу https://localhost:8000
. Чтобы остановить сервер, выполните в REPL команду down()
.
Теперь добавим код пользовательского интерфейса и реактивный код для реализации следующих элементов:
-
ползунок для управления длиной вектора случайных чисел;
-
текстовая строка для отображения среднего значения элементов вектора;
-
гистограмма вектора.
Ползунок и среднее значение — пользовательский интерфейс
Пользовательский интерфейс можно создать на чистом языке Julia, используя малокодовый API, предоставляемый пакетом StippleUI.jl
, который включается автоматически при выполнении директивы using GenieFramework
. Он предоставляет ряд вызовов, таких как textfield
или slider
, для формирования HTML-кода компонента пользовательского интерфейса:
julia> slider(1:1:1000, :N)
"<q-slider :min=1 v-model=\"N\" :max=1000 :step=1></q-slider>"
Полный список доступных компонентов см. в коллекции компонентов и API.
Чтобы включить в пользовательский интерфейс компонент ползунка и компонент для отображения среднего значения, добавьте в функцию 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
The average of {{N}} random numbers is {{m}}
</div> </div>
Здесь задается макет страницы с строкой
и ячейкой
с CSS-классами st-col, col-3
для установки ширины столбцов. Внутри ячейки отображаются заголовок, слайдер и абзац. Компонент slider
принимает в качестве параметров диапазон возможных значений и символьное имя реактивной переменной, в которой будет храниться выбранное число. Эта переменная пока не существует. Мы добавим ее в реактивный код позже.
Синтаксис {{variable}}
используется в абзаце p
для отображения содержимого реактивных переменных. Более того, этот синтаксис принимает любое допустимое выражение JavaScript, поэтому можно написать, например, {{m.toFixed(2)}}
для отображения среднего значения с двумя знаками после запятой.
Чтобы изучить код HTML, сгенерированный функцией ui
, можно вызвать его в REPL. Результат будет таким:
<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
в коде пока являются просто заполнителями, пользовательский интерфейс работать не будет. Давайте добавим реактивный код, чтобы сделать его интерактивным.
Ползунок и среднее значение — логика
При перемещении ползунка должно устанавливаться новое значение длины вектора и отображаться обновленное среднее значение. Для этого сначала объявим реактивную переменную N
в блоке @app
следующим образом.
@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
можно легко реализовать любые интерактивные возможности. Дополнительные сведения см. в справке по реактивности.
Теперь у вас должен получиться работающий реактивный пользовательский интерфейс! Давайте добавим гистограмму.
Гистограмма
Чтобы отобразить график в пользовательском интерфейсе, добавьте вызов 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
Вот и все, вы создали свою первую информационную панель! Дополнительные сведения о построении графиков см. на странице справки. Далее вы можете продолжить ознакомление с руководствами, чтобы добавить дополнительные возможности, например несколько страниц или API.