Engee 文档

绘图

Genie 使用 PlotlyJS 在浏览器中生成交互式绘图。尤其是,它利用 PlotlyJS.jl 软件包及其语法在 Julia 代码中声明绘图。

PLotlyJS 图形有两个组成部分:

  • Data 一个轨迹对象数组,每个轨迹对象代表一组不同的数据点及其在绘图中的图形表示。跟踪对象指定了绘图类型(散点图、条形图、饼图、热图等),并包含颜色、线条样式或标记样式等属性。通过在数据数组中组合多个跟踪对象,可以创建具有不同数据序列和绘图类型的复杂分层可视化效果。

using PlotlyBase

trace1 = scatter(
    x=[1, 2, 3, 4],
    y=[10, 15, 13, 17],
    mode="markers",
    name="Trace 1"
)

trace2 = scatter(
    x=[1, 2, 3, 4],
    y=[5, 9, 11, 12],
    mode="lines+markers",
    name="Trace 2",
    line=attr(color="red")
)
  • Layout 图表:定义图表的整体外观和格式,包括图表标题、坐标轴标签、图例、边距设置、背景颜色、网格线等设置。

layout = Layout(
    title="A Scatter Plot with Multiple Traces",
    xaxis=attr(
        title="X Axis Label",
        showgrid=false
    ),
    yaxis=attr(
        title="Y Axis Label",
        showgrid=true,
        range=[0, 20]
    )
)

要在 Genie 应用程序中包含绘图,首先要将其数据和布局声明为反应变量

@out plotdata = [trace1, trace2]
@out plotlayout = layout

并使用低代码应用程序接口将绘图添加到用户界面中

ui() = plot(:plotdata, layout=:plotlayout)

或使用 HTML 代码中的`plotly` 标签将绘图添加到用户界面

<plotly :data="plotdata" :layout="plotlayout"> </plotly>

从 Plots.jl 中定义绘图

还可以使用 Plotly 后台和`Plots.plotly_traces`/Plots.plotly_layout 函数,从 Plots.jl 定义的绘图中获取`plotdata` ,方法如下:

module App
using GenieFramework
import PlotlyBase, PlotlyKaleido, Plots
Plots.plotly()

p = Plots.plot([1, 2, 3], show=false)
@app begin
    @out traces = Plots.plotly_traces(p)
    @out layout = Plots.plotly_layout(p)
end

function ui()
    plot(:traces, layout=:layout)
end

@page("/", ui)
end
::alert{type="info"} The plotly_traces function is loaded by Plots.plotly() in the integration with PlotlyBase and PlotlyKaleido. Therefore, PlotlyBase and PlotlyKaleido should be available installed and in the environment when Plots.plotly() is called for plotly_traces to be defined.

在 HTML 中定义绘图

您也可以完全在 HTML 代码中定义绘图,只需将数据绑定到 Julia 变量即可、

module App
using GenieFramework
@genietools

@app begin
    @out firstX = [1, 2, 3, 4, 5]
    @out firstY = [5, 0, 3, -1, 2]
    @out secondX = [1, 2, 3, 4, 5]
    @out secondY = [1, 4, 6, 4, 4]
end


@page("/", "app.jl.html")
Server.up()
end
<div>
    <plotly
      :data="[
        {
          x: firstX,
          y: firstY,
          mode: 'markers',
          type: 'scatter',
          marker: { color: 'rgb(201, 90, 218)', size: 12 }
        },
        {
          x: secondX,
          y: secondY,
          mode: 'lines+markers',
          type: 'scatter',
          line: { color: 'rgba(61, 185, 100, 0.8)', width: 1.5 },
          marker: { color: 'rgb(61, 185, 100)', size: 8 }
        }
      ]"
      :layout="{
        title: 'Complex StippleJS Plot Example',
        xaxis: { title: 'X Axis', range: [0, 5] },
        yaxis: { title: 'Y Axis', range: [-1, 6] },
        legend: { x: 0.5, y: -0.3, orientation: 'h' }
      }"
    />
  </div>

请注意,本示例使用的是 Javascript PlotlyJS,因此不需要 Julia`PlotlyBase` 软件包。

检测绘图上的鼠标事件

PlotlyJS 允许检测绘图上的各种鼠标事件,如点击、悬停、选择和中继输出。您可以捕获这些事件并执行特定代码。

要启用事件检测功能,您需要使用用`@app ModelName` 定义的 named`ReactiveModel` 。请注意,截至目前,命名模型是*shared across all sessions and users* ,因此任何用户交互都会在所有浏览器窗口中触发响应。

此外,事件处理代码会通过`@mixin` 宏和`watchplots` 函数附加到`ReactiveModel` 上。

下面的示例展示了如何处理可用的鼠标事件。

module App
using GenieFramework, PlotlyBase, StipplePlotly
@genietools

trace1 = scatter(; x=1:4, y=[0, 2, 3, 5], fill="tozeroy")
trace2 = scatter(; x=1:4, y=[3, 5, 1, 7], fill="tonexty")

@app EventsModel begin
    @out traces = [trace1, trace2]
    @out plotlayout = PlotlyBase.Layout(title="Filled line chart")
    @mixin traces::PlotlyEvents
    @onchange traces_click begin
        @show traces_click
    end
    @onchange traces_hover begin
        @show traces_hover
    end
    @onchange traces_selected begin
        @show traces_selected
    end
    @onchange traces_relayout begin
        @show traces_relayout
    end
end

# start watchning plots when page is loaded
@mounted EventsModel watchplots()

ui() = [plot(:traces, layout=:plotlayout, syncevents = true)]

route("/") do
    global model
    model = EventsModel |> init |> handlers
    page(model, ui()) |> html
end

Server.isrunning() || Server.up()
end