Skip to content

Fresco UI 框架文档(docFresco) ​

原文: https://finproducts.atlassian.net/wiki/spaces/JIDD3/pages/34793521160/FIN+5.3.1+docFresco 中文整理基于 FIN 5.3.1


manual ​

Fresco UI 框架文档(docFresco) ​

SkySpark Fresco UI 框架文档


chapters ​

Overview弗雷斯科框架概览
AppsApps 用于组织视图
Views17 使用在使用前使用前的摄前前的 现在 17 服用前 使用前 服用
ValDefValDef 模型 如何可视化和编辑值
Nav配置导航
Actions动作用于执行用户交互
Templates模板预定义窗体
Tables视网格为表格
Cards视网格为牌
Charts用图表引擎可视化网格
Maps在地理地图上可视化数据
IconsSVG 图标管理
Resources外部资源文件
Export用 Axon 、 电子邮件或 REST 导出视图
Fantom与 Fantom APIs 合作

行动 ​

概览 ​

动作是作为 Axon 函数执行的用户命令. 他们是 registered 在视图中创建一个动作工具栏,而无需写入自定义的 UI 代码。 行动分为四大类:

  • No Input: 没有用户输入的行动
  • Form: 以窗体提示用户
  • Upload: 从用户上传文件
  • Custom: 自定义客户端 Fantom 方法

此外,可以将动作包在一个用户中 confirmation 步骤,然后返回 results 完成后发送给用户。

核心库包含一套通用功能,可用于标准矩形 CRUD 行动。

动作元 ​

Meta数据被添加到自定义行为的行动中. 用于动作的最常用标记有:

  • action知名度 : Axon func name 用于引用(或 Fantom qname 用于自定义动作)
  • dis: 显示动作 UI 控制的名称
  • disKey检查 dis 从地方键
  • select: 动作需要视图选择来引用
  • multi: 从视图中支持多个选择的动作
  • selectTag: 选择其它标签 id 转到动作函数
  • noFlash: 完成后省略闪存横幅
  • noUpdate: 完成后不重新评价视图的数据表达式

可在两个不同的地方添加这一元数据:

  1. 在功能上作为附加标记
  2. 关于观点中的行动定义

如果在 action def 上定义了元, 它将永远覆盖 func 记录上的任何配置值 。

魄力 select:

// define 'select' directly on func
name: "myFunc"
func
select
src:
  (dict) => do
    ...
  end

// enable selection on the action def
myAction: { action:"anotherFunc" select }

无输入动作 ​

好啦,最简单的动作是直接引用的,没有详以电子方式输入. 好啦,这叫做“不输入”动作:

myAction: { action:"myFunc" }

name: "myFunc"
func
src:
  () => do
    echo("Action performed!")
  end

虽然没有输入动作从不需要用户输入,但可以通过添加 select 动作元a:

myAction: { action:"myFunc" select }

name: "myFunc"
func
src:
  (sel) => do
    ids: actionNormInput("sel", "ids")
    ...
  end

见 form 关于使用详情的章节 actionNormInput.

添加 multi 多个选择的标记 :

myAction: { action:"myFunc" select multi }

窗体动作 ​

窗体动作以 Haystak 4 def 或 template 用于为辅助行动功能收集输入的窗体。 通过定义一个有单一参数的 func 来创建形式动作 dict 或后缀为 Dict:

myAction: { action:"myFunc" }

name: "myFunc"
func
src:
  (siteDict) => do
    site: actionNormInput(siteDict, "dict")
    ...
  end

用于形式动作的模板可按先后顺序以三种方式指定:

  1. 用途 defName 行动元或视图元a (海斯塔克 4 度和表格)
  2. 使用 kind inference 通过后缀参数名称 Dict
  3. 使用 templateName 动作或视图元a

类推的例子:

siteDict     // create form using the 'site' template
myFormDict   // create form using the 'myForm' template

视图/行动元实例a:

view: myView
dis: "My View"
templateName: someTemp
src:
  view:    { inherit:"table"}
  action1: { action:"myFunc" }                             // use view.templateName
  action2: { action:"myFunc" templateName:"anotherTemp" }  // override template
  data:    { expr:"readAll(someTag)" }

name: "myFunc"
func
src:
  (dict) => do
    rec: actionNormInput(dict, "dict")
    ...
  end

添加 showDis 标记动作/视图节点的标记,以便在窗体对话框中使用显示名称。 如果省略,则会使用程序名称.

添加 hideAdd 在动作/视图节点上标记标记,以隐藏窗体对话框底部的“添加标签”按钮。

添加 hideAdvanced 在动作/视图节点上标记标记,以隐藏窗体对话框底部的“高级”按钮。

函数绝不应假定传递给他们的参数类型。 要访问窗体值,请使用 actionNormInput() 函数,可以将输入转换为理想类型:

id:    actionNormInput(siteDict, "id")
ids:   actionNormInput(siteDict, "ids")
dict:  actionNormInput(siteDict, "dict")
dicts: actionNormInput(siteDict, "dicts")

对于基于 Fantom 的动作,请输入参数为 Obj 并使用 Committer.actionNormInput 方法 :

@Axon { ... }
static Obj? fooEdit(Obj fooDict)
{
  dict := Committer.actionNormInput(fooDict, "dict") as Dict
}

关于使用的一些注释 actionNormInput() 页:1 "dict" or "dicts" 选项 :

  • 模板已验证; Dict 返回为
  • 在编辑现有记录时,弗雷斯科将返回稀疏的 Dict 仅包含修改过的标签
  • 总是用 recNew() or recEdit() 从窗体动作中执行更改(从未使用) commit()) (中文(简体) ). 这样可以确保表格输入能够对照模板进行适当的验证。

使用示例 actionNormInput() 和 recEdit():

name: "myFunc"
func
src:
  (dict) => do
    rec: actionNormInput(dict, "dict")
    ...
    recEdit(rec)
  end

您通常会想要编辑当前由视图选中的记录 。 这一点通过适用 select 标记到您的动作函数 :

myAction: { action:"myEditFunc" select }

对于多个选择,请添加 multi 标签外加 select:

myAction: { action:"myEditFunc" select multi }

注意在进行批次编辑时不使用模板. 在这些情况下使用通用批量表格。

动作选择 ​

时间的推移,

myAction: (arg) => echo("myAction: " + arg)

以下是界定4项行动的观点:

view: {inherit:"table"}
data: {expr:"readAll(site)"}
action1: {action:"myAction"}
action2: {action:"myAction" select}
action3: {action:"myAction" select multi}
action4: {action:"myAction" select selectTag:"geoAddr"}

行动1不使用 select 标签,所以当引用时,它会提示有窗体的用户输入字符串值。 arg.

行动2 select 标记 。 除非选中一行, 否则将禁用 。 当它被引用时,它会通过记录 id 标记到动作函数( 总是使用) actionNormInput() 使情况正常化。

行动3使用 select 和 multi 支持多个选择的元标记。 只要选定了一个或多个行,它就会被启用。 当引用时, 它会传递一个函数的 ID 列表( 总是使用 ) actionNormInput() 页:1

行动4使用 select 和 selectTag 元将特定的列值传递给动作。 在这个例子中,它会通过 geoAddr 标记选定行的动作函数。 您可以使用这一技术来生成您数据格中的合成,隐藏的单元格,将任意数据传递回动作(例如来自输入状态的变量).

上传动作 ​

上传动作允许用户从其本地计算机上传文件. 要创建上传动作,请添加 upload 动作元a:

myAction: { action:"myFunc" upload }

当动作被引用时,会用一个表格提示用户选择他们想要上传的文件. 默认情况下,文件会被上传到 io/uploads/ 服务器上的目录 。 如果file已经存在,则会添加一个独特的后缀. 上传时文件永远不会被覆盖 。 要访问上传的文件,请使用 actionNormInput()返回一个 IO handle 实例 :

name: "myFunc"
func
src:
  (obj) => do
    h: actionNormInput(obj, "ioHandle")
    echo(h.ioReadStr)
  end

要允许上传多个文件,请添加 multi 元数据 :

myAction: { action:"myFunc" upload multi }

使用 "ioHandles" 用于 知道了 :

name: "myFunc"
func
src:
  (obj) => do
    handles: actionNormInput(obj, "ioHandles")
    handles.each h => echo(h.ioReadStr)
  end

上传到默认以外的地方 io/uploads/,将使用 uploadDir 元,其中的线索 / 需要:

myAction: { action:"myFunc" upload uploadDir:`io/my/dir/` }

自定义动作 ​

自定义动作只是客户端方 Fantom 方法, 用当前视图的可选参数引用 :

myAction: { action:"myPod::MyType.myFunc" }

class MyType {
  Void myFunc(UiView view) { ... }
}

注意这里的动作是 Fantom qname 以援引。 Fantom 函数也可能是 instance or static - 两者都得到了支持。

确认 ​

这个 confirm 标记应用到您的动作函数中,以便在动作被引用前用确认对话框提示用户。 确认标记被定义为带有下列标记的嵌入式Dict:

  • icon:逻辑图标名称(典型的“ warn ”)
  • iconColor: 默认为 Colors.yellow 以警告除此之外, #333
  • dis/disKey: 显示确认对话框的标题
  • details/detailsKey: 其他细节

以下是一个例子:

dangerAction: {
  action: "doSomethingDangerous"
  confirm: {
    icon:       "warn"
    disKey:     "acmeExt::dangerConfirm"
    detailsKey: "acmeExt::dangerDetails"
  }
}

结果 ​

引用动作后,您可以通过返回网格向用户选择显示结果 view 在网格元中标记,并使用视图名称。

所謂的同理會

  • table: 在表格中显示结果
  • chart: 将结果显示为图表
  • text: 显示 grid.first->val 作为文本内容
  • fandoc: 显示 grid.first->val as Fandoc 内容

以下是向用户显示一些纯文本的示例:

details: { action:"fooDetails" }

name: "fooDetails"
disKey: "ui::details"
func
src
  () => do
    { val:"some details" }.toGrid.addMeta({ view:"text" })
  end

A. 活动 ​

内置功能 recNew(), recEdit(),以及 recTrash() 可以在视图中与模板组合使用,以提供 CRUD(创建,读,更新,删除)支持:

view: myView
dis: "My View"
templateName: foo
src:
  view:  { inherit:"table"}
  new:   { action:"recNew" }
  edit:  { action:"recEdit }
  trash: { action:"recTrash" }
  data:  { expr:"readAll(foo)" }

上下文菜单 ​

您可以在视图中添加上下文菜单动作, 声明一个动作命名 uiContextMenu。如果您有表格视图,它将自动提供基于表格当前选择的上下文菜单:

view:  { inherit:"table"}
menu:  { action:"uiContextMenu" }
data:  { expr:"readAll(equip)" }

或者可以使用导航拾取器输入,作为上下文菜单的选择 selInput 标识输入变量名称的标签 :

view:  { inherit:"table"}
equip: { input var kind:"Ref<equip>" }
menu:  { action:"uiContextMenu" selInput:"equip" }
data:  { expr:"readById({{equip}}).toPoints" }

如果您有自定义的 Fantom 视图, 那么上下文菜单基于结果 UiView.sel.


应用程序 ​

概览 ​

Apps 为逻辑分组 views。它们定义用于视图顶级导航的显示名称和图标。 它们的命名使用全局命名空间similier来查看和模板. 视图被指定为应用程序 appName 标记 。

定义 ​

提供的支持 App由文件"lib/apps.trio"中的sys mod或扩展库定义. 使用以下标记:

  • app: 全警探名 Str( 必须是有效的标签名称)
  • dis or disKey: 显示应用程序的名称
  • icon: SVG 图标的逻辑名称

以下是一个完整的例子:

// lib/apps.trio
app: "acmeReports"
dis: "Acme Reports"
icon: "chartBar"

纸牌 ​

概览 ​

牌 非常景色用来呈现一个Dicts(即一个格子)列表作为牌的甲板. 每个Dict是作为卡片代表的,并且可以使用与该卡片相同的演示技术进行样式化. table view。在显示单张卡片时,卡片视图特别适合仪表板应用。 显示多张牌时,从上到下垂直排列.

网格模型 ​

显示卡片(即Dict)的默认行为是每行显示一个标记/值对. 每个标记/值对被称为"物品". 因此它以只读的形式布局呈现Dict项.

tag1     val1
tag2     val2
.        .
.        .
.        .
tagN     valN

卡片上؟的某些项目是特殊的,可用于改变卡片的显示方式. 这些标记从未以上述形式布局显示. 每个标记都是可选的.

  • title: 卡片的标题
  • subtitle: 卡片的字幕
  • primary: 显示卡时应强调的值。 此值会在显示时填充卡片中的剩余空间 。
  • viewLink:如果存在,该卡将成为视图的超链接.

卡片布局 ​

下图显示单张卡片的设置方式,包括可选配置:

 ________________________________
|title                           |
|________________________________|
|subtitle                        |
|________________________________|
|                                |
|                                |
.                                .
.            primary             .
.                                .
|                                |
|________________________________|
| form items                     |
|________________________________|

就这些 ​

一种卡片的型式可能采用《联合国示范公约》中说明的一样的型式。 table chapter。这包括将项目显示为 viz cells但请注意,下列样式标记不适用于卡片:

  • 表格级别标签:
    • hideHeader
    • hideRowInfo
    • disableSel
  • 排, Colum, 和细胞:
    • halign
  • 仅列:
    • colWidth

您也可以通过使用 c 快捷键。

您可以通过设置 cardNoScroll 在您的网格元中标记标记标记 。

实例 ​

演示项目 Demo | Site Card 视图显示一个示例仪表板。 那个 demoSiteCard() 函数用于创建破碎的瓦片。 它可以在代码编辑器中查看,它包含了几个创建卡片和造型卡片的例子.


图表 ​

概览 ​

SkySpark提供了一套丰富的图形图表,用于可视化数据. 目前图表由源数据网严格定制,使用一套常规和网格/栏元a

图表类型 ​

支持下列图表类型:

  • 栏杆
  • 甜点
  • 热映射
  • 线条
  • 馅饼
  • 运行时间
  • 散开
  • 叠巴

图表类型中,每个类型都是可视化的 Demo | Collage 在演示数据库中查看。

网格模型 ​

图表生成的默认行为是将第一列作为x轴处理,每个附加的列都是单独的序列y轴. 系列按地块类型和单位分组,除非与 chartGroup 标记 。 图表采用网格元和列元的组合定制.

网格元标记 :

  • title: 将标题添加到图表顶部的字符串
  • subtitle: 图表标题下的字符串字幕
  • noData: 如果无数据可用, 将使用字符串消息
  • chartType: 为所有序列定义图表类型
  • chartLegend: 用于图例控制的字符串语句
  • chartLegendNoSort: 在图例、 强制网格列顺序中以 dis 排序禁用
  • chartNoScroll: 禁用滚动的标记标签

列元标记( 个人序列) :

  • chartType: 将列的图表类型定义为 Y 轴
  • chartGroup: 定义明确的图表分组
  • color: 序列颜色
  • strokeWidth: 行幅宽度
  • strokeDasharray: 线条图案的破损图案, 栏/跑时间的交叉舱门
  • opacity: 区域填充数为 0.0 到 1.0 的α 透明
  • chartAreaMode我想知道 :
  • chartMin: 定义序列轴小分值
  • chartMax: 定义序列轴最大值
  • chartHeight: 对系列绘图使用固定劳力
  • exclude: 将一个序列标记为排除( 不用于计算 Y 轴界限)
  • format: 轴格式

分组 ​

将系列组合成图表的默认机制是按图类型和单位划分的. 那个 chartGroup 标记可以应用到一个列来解释性的力量分组。 当组合多个系列的不同地块类型时,地块被覆盖在一起. 具有相同y轴类型的系列会被共享,否则会使用多个y轴堆叠使用另一种模式:左,右,左,右等.

热映射 ​

HeatMap版图需要三个维度,其中z轴代表横跨x轴和y轴的颜色尺度值. 热门必须使用 chartType 网格元(不是列元)。 x和y轴必须是正弦(通常为字符串),z必须是表示颜色缩放的数值.

网格形状有两个选项:

  1. 分别代表x,y,z维的三列
  2. 第一种称呼的两栏 ts 并定义 DateTime 列,其次为数字 z 值列。 这个 ts 列自动爆炸为日期的x轴和24小时的y轴

默认颜色尺度是 [blue, white, red]您可以使用 colors 在网格旷野上作为两个或多个颜色的逗号分隔列表。 颜色目前使用RGB进行插值. 请注意,这方面的设计可能会有变化。


导出 ​

概览 ​

本章涵盖向PDF和其他文件类型导出视图. 导出可以使用多种方式:

  • Axon: 视图导出为脚本 ioExport() 函数
  • 电子邮件:视图可导出为电子邮件附件
  • 临Τ export 操作可能通过 HTTP 请求导出
  • 链接:与弗雷斯科视图的超链接

请求 ​

所有导出/ 链接请求都以命令为模式, 标记如下 :

  • view: 导出或链接到的视图名称
  • state: 可选视图变量状态作为嵌入式 Dict
  • filetype: 导出的文件类型 - 见下文格式列表
  • filename: 下载/附件文件名
  • pageSize: 配置 PDF页面大小 - 见 pageSize (仅限PDF).
  • size新格式 : 将大小配置为逻辑单位中的“ w, h ” (仅 SVG)
  • background页:1 color 或“透明” (只有 SVG)

文件类型 ​

任意定义 filetype 可供导出 :

  • csv: 逗号分离值
  • excel: Excel 2003 XML 电子表格
  • html: 超文本标记语言
  • json: 海斯塔克 JavaScript 对象标记格式
  • jsonldmaximum: JavaScript 链接数据的对象标记
  • pdf: 便携式文档格式
  • svg: 可缩放矢量图形
  • trio: 海斯塔克标签记录输入输出
  • turtle: RDF 乌龟
  • xml: 极限标记语言
  • zinc: Haystack 键入 CSV 格式

实例 ​

我们将以下列观点为例:

view: {inherit:"chart"}
points: {var kind:"Ref<point>" input}
span: {var kind:"Span" input}
data: {expr:"readByIds({{points}}).hisRead({{span}})"}

这是一个简单的视图,有两种输入:点对数列表和跨度. 投入用于读取积分历史,并将数据显示为图表.

斧头 ​

Axon 函数 ioExport() 用于导出视图到任何可写 I/O 手柄。 导出请求作为第一个使用 Dict 的参数传递:

// we will use these variables to populate our state
p: readAll(kwSite).toRecIdList  // point ids as Ref[]
s: yesterday().toSpan           // span

// export to PDF using defaults
ioExport({view:"example", state:{points:p, span:s}}, `io/example.pdf`)

// export to PDF as US landscape with explicit pageSize
ioExport({view:"example", state:{points:p, span:s}, pageSize:"11in,8.5in"}, `io/example-landscape.pdf`)

// export data to excel
ioExport({view:"example", state:{points:p, span:s}, filetype:"excel"}, `io/excel.xls`)

至少 ​

查看请求dicts可用作电子邮件附件 emailSend() 参加了ộ式游戏。 兄弟们。参加了ộ子会议。 兄弟会

// we will use these variables to populate our state
p: readAll(kwSite).toRecIdList  // point ids as Ref[]
s: yesterday().toSpan           // span

// emailSend parameters
rcpts: "someone@somewhere.com"
subject: "export examples"
body: "Export examples are attached"

// PDF attachment
emailSend(rcpts, subject, body, {view:"example", state:{points:p, span:s}, pageSize:"11in,8.5in"})

// explicit attachment filename
emailSend(rcpts, subject, body, {view:"example", state:{points:p, span:s}, filename:"report.pdf"})

// list of attachments, both PDF and Excel
emailSend(rcpts, subject, body, [
    {view:"example", state:{points:p, span:s}, pageSize:"11in,8.5in"},
    {view:"example", state:{points:p, span:s}, filetype:"excel"}
  ])

资源 ​

可使用 HTTP 请求出口 export op。海斯塔克行动将请求作为第一行定义标准的网格 export request tags由于它最自然地通过 HTTP GET 使用导出, 我们允许将状态编码为 Base64 Zinc dict literal 。 以上述例子:

// state as Zinc dict literal
{points: [@21025d8d-7471da9f, @21025d8d-be11a76f,  @21025d8d-a9e1af0b, @21025d8d-78e503fd], span:Span("yesterday")}

// base64 encoding of above
e3BvaW50czogW0AyMTAyNWQ4ZC03NDcxZGE5ZiwgQDIxMDI1ZDhkLWJlMTFhNzZmLCAgQDIxMDI1ZDhkLWE5ZTFhZjBiLCBAMjEwMjVkOGQtNzhlNTAzZmRdLCBzcGFuOlNwYW4oInllc3RlcmRheSIpfQ

// REST URI to export as PDF
http://localhost:8080/api/demo/export?view=example&state={base64}&pageSize=11in,8.5in

链接 ​

同样的导出概念适用于创建与弗雷斯科视图的超链接. 要超链接到Fresco视图,使用下列URI格式:

// format
http://{host}:{port}/ui/{proj}?view={viewName}&state={base64}

// examples
http://localhost:8080/ui/demo?view=example&state={base64}

您可以使用以下 Axon 函数生成超链接 URI :

  • uiLink(): 生成主机相对 URI( 以斜线启动)
  • uiLinkAbs(): 生成绝对 URI( 以 httpSiteUri())

两种并不构成 request 格式为导出操作和 ioExport() 函数 :

// we will use these variables to populate our state
p: readAll(kwSite).toRecIdList  // point ids as Ref[]
s: yesterday().toSpan           // span

// generate URI to Fresco view for current project
uri: uiLink({view:"example", state:{points:p, span:s}})

方图 ​

概览 ​

本章涵盖了UI Fantom API.

自定义视图 ​

你可以下级 UiView 创建自定义视图。

自定义视图的视图定义 Trio 指定了您视图类型的 Fantom 限定类型名称 :

view: exampleView
appName: misc
dis: Example
src:
  view:   {uiType:"exampleExt::ExampleView"}
  data:   {expr:"readAll(site)"}

这个 UiView.onUpdate 当一个新的数据网格准备向DOM渲染时,即引用回调。 你利用 dom 和 domkit APIs (英语). 以下是一个非常简单的执行,它显示了数据网格中每一行的标签列表:

@Js
class ExampleView : UiView
{
  override Void onUpdate()
  {
    removeAll
    data.each |row|
    {
      add(Label { it.text = row.dis; it.style->display = "block" })
    }
  }
}

视图栏 ​

如果您的视图有输入和/或动作,请使用 UiViewBar.layoutWithContent 创建标准视图工具栏:

// Trio def
view: exampleView
appName: misc
dis: Example
src:
  view:    {uiType:"exampleExt::ExampleView"}
  refresh: {dis:"Refresh" noFlash action:"noop"}
  data:    {expr:"readAll(site)"}

// Fantom code
using domkit
using ui

@Js
class ExampleView : UiView
{
  new make()
  {
    // setup data content be flex layout top-to-bottom
    this.content = FlexBox {
      it.dir = "column"
      it.style->gap = "8px"
    }

    // add viewbar to the top with configured inputs
    this.add(UiViewBar(this).layoutWithContent(content))
  }

  override Void onUpdate()
  {
    // get current data as haystack Grid
    grid := data(null)

    // rebuild DOM content with a label per site
    content.removeAll
    grid.each |site|
    {
      content.add(Box {
        it.style->padding = "8px"
        it.style->border = "1px solid #ccc"
        it.style->borderRadius = "5px"
        Label {
          it.text = site.dis
          it.style.addClass("font-bold")
          it.style->fontSize = "18px"
        },
      })
    }
  }

  private Box content
}

自定义输入 ​

在显示窗体时,您可以在标签名称上注册自定义输入。

在标签中, 注册您这样的合格类型名称 :

def: ^exampleFlags
is: ^str
uiInput: "exampleExt::ExampleFlagsInput"
doc: "Comma separated names"

然后莺的子类 Input:

@Js
class ExampleFlagsInput : Input
{
  new make()
  {
    one = addCheckbox("one")
    two = addCheckbox("two")
  }

  private Checkbox addCheckbox(Str dis)
  {
    cb := Checkbox()
    add(cb.wrap(Label { it.text = dis; it.style->paddingRight = "6px" }))
    cb.onAction { this.modified = true }
    return cb
  }

  protected override Void onLoad(Obj val)
  {
    names := val.toStr.split(',')
    one.checked = names.contains("one")
    two.checked = names.contains("two")
  }

  protected override Obj onSave()
  {
    s := StrBuf()
    if (one.checked) s.join("one", ",")
    if (two.checked) s.join("two", ",")
    return s.toStr
  }

  protected override Void onRO()
  {
    one.enabled = !ro
    two.enabled = !ro
  }

  private Checkbox one
  private Checkbox two
}

这个例子创建 还有两个复选框来编码像"一,二"这样的字符串标记.

要创造适当的投入,您必须执行:

  • 通过 Input.onLoad 回调
  • 通过... Input.onSave 回调
  • 设定您的用户界面仅通过 Input.onRO 回调
  • 在修改时,您必须通过设置 Input.modified 字段

注:每个输入部件都必须映射到 modified 旗帜。 如果这样做不正确,那么在窗体关闭时,您的输入将不会被保存 。


图标 ​

概览 ​

SkySpark使用的所有图标都使用SVG格式化,使用逻辑名称进行识别. 逻辑名称映射到一个SVG文件,作为资源文件捆绑,或者可能是另一个逻辑名称的别名.

SVG 格式 ​

图标被包装为包含三个不同组层元素的SVG文件:

  • ** 外线**:图标大纲
  • ** 固态**:固态图标
  • ** 颜色**:图标的全彩版

为了在运行时自定义颜色, SVG 元素应当有 style B. A. A. 二. B. 二. fill 和 stroke.

所有图标都应使用 viewBox="0 0 128 128" 的 。 。

  • ** 外线**:6px
  • 固态:6px
  • ** 颜色**:3px

以下是一个简单的矩形例子,的最新资料包括所有三个层次:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 128">
  <title>rect</title>
  <g id="outline">
    <rect x="10" y="10" width="108" height="108" style="fill: none;stroke: #333;stroke-width: 6px"/>
  </g>
  <g id="solid">
    <rect x="10" y="10" width="108" height="108" style="fill: #555;stroke: #555;stroke-width: 6px"/>
  </g>
  <g id="color">
    <rect x="10" y="10" width="108" height="108" style="fill: #0f0;stroke: #000;stroke-width: 3px"/>
  </g>
</svg>

AI 模板 ​

这里可下载 Adobe Illustrator CC 的样本图标模板: icon_template.ai

不添加、删除或重命名任何层。 在将您的 AI 图标导出到 SVG 时, 请使用以下设置来获取最佳效果 :

  • ** 样式**:内含样式
  • ** 冯特**:SVG
  • ** 图像**:保留
  • ** 对象编号**:图层名称
  • ** 决定**:2
  • ** 尽量减少**:否
  • ** 反应**:是

使用这些设置将生成符合上述格式要求的SVG图标.

登记 ​

注册新的图标逻辑名称需要以下步骤:

  1. 在 build.fan 元添加以下密钥对 skyarc.icons: true
  2. 创建一个 aliases.props 将逻辑名称映射到现有的 SVG 文件
  3. 将新的 SVG 文件装入 svg/ 其中文件名是逻辑密钥名称

示例 pock 目录 :

// directory layout
acmeIcons/
  build.fan
  aliases.props
  svg/
    acmeCustom1.svg
    acmeCustom2.svg

// aliases.props file
acmeWarn=warn
acmeEnergy=bolt

// build.fan script
using build
class Build : BuildPod
{
  new make()
  {
    podName = "acmeIcons"
    summary = "Acme icon library"
    meta    = ["org.name":     "Acme",
               "skyarc.icons": "true"]
    resDirs = [`aliases.props`, `svg/`]
  }
}

在上述例子中,我们将绘制逻辑名称acmeWarn,acme Energy,acmeCustom1和acmeCustom2. 注意,由于命名空间是平的,因此必须在图标名称前加一个工程或org名称,以保证独有性,避免将来的命名碰撞.

URIs 语录 ​

使用图标时 resource file,用于识别图标的规范化的URI遵循模式:

/icon/{name}?s={style}&c={color}  // pattern

在上述图案中,名称是图标的逻辑名称. 风格选项有:颜色,固态,或轮廓. 颜色被格式化为 RGB 或 RRGGBBB ,没有主色调 # 签名。 实例:

/icon/app                      // color style is default if omitted
/icon/app?s=color              // same as above
/icon/app?s=solid&c=F00        // solid red icon
/icon/home?s=outline&c=00FF00  // green outline icon

你可以用这个 iconUri() 以创建图标 URI。

测试 ​

浏览和测试图标的最简单方法是使用 /ui/icon-test 页面。 本页面显示所有已注册的图标逻辑名称以及三个版本的解析. 您可以选择用于固态和大纲版本的图标大小和颜色。 您可以将图标放入“ {var}/ pub/ icons/” 目录, 以测试它们在这个工具中 。


地图 ​

概览 ​

SkySpark为在地理地图上可视化信息提供了地图视图. 目前我们使用苹果的 MapKit 库. 您的咀嚼软件必须具有最新的维护功能,以便使用绘图功能.

数据 ​

地图视图数据是一个网格,列如下:

  • id: 每行必须有一个独特的代号
  • geoCoord: 每行必须有一个coord( 如果缺少则跳过)
  • title: glyph 的字符串( 如果省略, 然后使用 dis)
  • subtitle: glyph 的可选字幕
  • color: Glyph 的 CSS 颜色字符串

如果数据为流线 feed(),然后地图视图将提供活的glyph更新。 见 demoMap() 用于在地图上更新活的 kW 数据和颜色。


导航 ​

概览 ​

Fresco为用户如何在系统中导航数据提供了一个灵活的框架:

  • 编辑参考标记
  • 选取场地或点等视图投入的实体
  • 挑选实体采取行动

维梅塔 ​

用户导航配置中有一个特殊单顿记录,标记为 uiMeta 标记标记。 uiMeta 推荐定义了以下标签 既然您想要使用此标签

  • projIncludeFilter: 匹配用于导航的项目
  • {foo}Nav: 定义如何以给定的标签导航

Proj 包含过滤器 ​

在特定项目内工作时的默认行为是仅在该项目内导航退缩. 但是,您可以通过配置此选项来方便地扩展导航以包含额外的工程 projIncludeFilter 标记带有 Str 过滤器以匹配 projMeta:

projIncludeFilter: portfolio=="SkyFoundry Bank"

您还必须添加 navCluster 标记到您的导航输入视图变量。 例如,从包含过滤器中的任何项目中选择设备区域:

{var input kind:"Ref<equip>" navCluster}

注意:复制项目的项目元基于上次同步的本地版本. 因此,如果在正在复制的项目上更改 projMeta,那么在测试更改为 projIncludeFilter 之前,先进行同步。

拱门选择 ​

顶端工具栏和每个项目的主页显示一个项目选择按钮. 默认情况下, project picker 显示用户可根据其 projAccessFilter。这个拾取器基本上是重定向到“/ui/{projName}”。

您可以通过添加 navHidden 标记到 projMeta 各个项目的记录。 请骰子注意此标记** 不** 限制用户访问工程或在 URI 中打字直接进入工程. 此标签只服务项目选择拾取器中的隐藏项目 。

标记导航 ​

您可以定义任意标记的自定义导航树 。 导航树是通过使用命名常规定义给定标记的分组路径构建的:

{tag}Nav: {groupBy1}/{groupBy2}/...

让我们看看我们如何用以下站点的回转设置导航:

dis: "A", site, geoState: "VA", geoCity: "Richmond"
dis: "B", site, geoState: "VA", geoCity: "Richmond"
dis: "C", site, geoState: "VA", geoCity: "Norfolk"
dis: "D", site, geoState: "MD", geoCity: "Gaithersburg"

默认情况下,当导航站点聚合时,会向用户提供所有站点的平面列表. 我们可以将站点按地理状态分类如下:

// uiMeta
siteNav: "geoState"

// navigation tree
VA
  A
  B
  C
MD
  D

我们可以定义地理状态和地理城市的两级导航:

// uiMeta
siteNav: "geoState/geoCity"

// navigation tree
VA
  Richmond
    A
    B
  Norkolk
    C
MD
  Gaitherburg
    D

您可以使用任意标签定义多少关。 标记的每一个独特的价值都会成为树上的导航节点.

按参考文献分组 ​

创建带有 ref 标记的导航级别时有一些特殊规则 :

  • 标记必须以“参考”结尾
  • 标记必须是分组路径中的第一个关卡
  • 标记的导航树是继承的

ref 分组最常见的例子是装备和指向这个导航的默认值:

equipNav: siteRef
pointNav: equipRef

在上述定义中,我们首先导航到站点,然后将其作为我们顶级的分组机制来装备. 这又间接继承了场地的导航定义。 依次从任何导航设备中 指向链条 举个例子:

// recs
dis: "A", site, campus: "East"
dis: "B", site, campus: "West"
dis: "A-1", equip, floor: "Floor 1", siteRef:@A
dis: "A-2", equip, floor: "Floor 1", siteRef:@A
dis: "A-3", equip, floor: "Floor 2", siteRef:@A
dis: "B-1", equip, floor: "Floor 1", siteRef:@B

// uiMeta
siteNav: "campus"
equipNav: "siteRef/floor"

// navigation tree
East
  A
    Floor 1
      A-1
      A-2
    Floor 2
      A-3
West
  B
    Floor 1
      B-1

注:按参考文献分类要求所有后代都包含对应所有祖先的参考文献标记。 例如,如果您将站点组合为 regionRef 标记,然后 regionRef 还必须适用于所有装备和点数。 这样可以对Folio进行高效的查询.

未平衡树 ​

在使用分组标记来进行导航定义时,可能会有部分记录丢失标记. 当这种情况发生时,没有标记的记录会作为对等点出现到组树节点. 我们称之为“缜密”是因为导航树的某个级别是由组节点和记录节点组成的。 举个例子:

// site recs
dis: "A", site, campus: "East"
dis: "B", site, campus: "West"
dis: "C", site

// uiMeta
siteNav: "campus"

// navigation tree
C
East
  A
West
  B

注意网站"C"将成为校园组"东"和"西"的对等节点. 这一技术适用于分组的任何级别。

缠绕 ​

导航支持在某个导航树的指定级别内 *nesting *. 例如航海时常见的 equip {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}通过... equipRef 标记 。 巢穴隐含地用于以下目标:

  • equip衔接 equipRef
  • space衔接 spaceRef
  • meter衔接 submeterOf

请注意,你必须不包括 equipRef 在你身边 equipNav. Nesting是一个单独的特性,是自动的。

订购 ​

命令一个级别导航树的默认行为是由相对的显示名称(相对于母节点). 如果在记录中定义了下列标记,则可以定制此顺序:

  • order
  • floorNum

如果上面的任何标记被定义为: Number 值然后定义 * 顺序数 *。 带有命令的复数总是根据其命令编号排序,如果相等,则根据其相对的显示名称排序。 没有命令号的记录在明确命令的记录之后,根据其显示名称定位。

导航选择任意 ​

这个 navSelAny 标记标记用于一个 Ref[] 查看输入,以便选择导航树的任意级别。 从语义上讲,这意味着用户暗中选择了节点"under"的一切. 例如,如果选择一个装备参考人名单,那么选择一个场地将意味着选择该场地包含的所有装备。 从本质上讲,这要求 navSelAny 只使用多个选择( 类型必须是 a) "Ref<target>[]" 列表类型)。

在封面下,这个功能需要复杂的选择编码和查询引擎. 例如,一些导航节点本身就是一个基于过滤器的分组(即特定地理城中的所有站点). 我们把这个数据编码成一个特殊的 ref 类型,叫做 *nav refs * , 它的前缀是这个方案 "nav:". Nav refs的格式不透明! Do ** 不**对导航参考格式作任何假设,随时可能改变。 仅通过公开记录的功能与导航员合作:

  • navRef(): 从目标名称和记录中构建一个导航参考器
  • navResolve(): 解决返回记录的导航 refs 列表

以下是一些例子:

// view input that selects any level of the equip tree using clustering
input kind:"Ref<equip>[]" navSelAny navCluster

// programmatically construct a nav ref selection
selection := navRef("equip", someEquip)

// resolve a navRef selection
recs: navResolve(selection, {navCluster})

注:如果您正在使用 navCluster 在输入时,您还必须通过该旗帜作为选项。 navResolve 函数。

特定观点如何利用祖辈选择将有所不同。 但特别要注意与 nesting 用来筑巢 equip 通过 equipRef默认 navResolve() 不会处理巢穴。 它可以用一个选项打开,但从需要的QQuery请求数量来看,它非常昂贵.

导航选择任意注释 ​

这个 navSelAnyRec 标记标记为similier 到 navSelAny 具有下列差异:

  • 只有可选择地图到Folio记录的导航树节点
  • 评估到正常记录的ID
  • 多选是可选的

这个旗子更简单 navSelAny 在标记组中不能选择(例如,按地理城市分组)。 因为只有记录是可选择的,采摘者评价到普通记录的ID,这些ID可以直接使用 readById()等 类. 您不需要将结果路径到 navResolve().

导航 Aux 过滤器 ​

您可以添加一个命名的标签 navAuxFilter 到您的导航输入 filter 字符串值 。 此过滤器应用于导航树上的叶节点. 它与正常的目标名称结合使用. 例如觅取设备树,但只选择带有 ahu 和 rooftop 标记,您可以像这样设置输入 :

kind:"Ref<equip>" navAuxFilter:"ahu and rooftop"

导航采取器将使用配置的树结构来进行"设备"(通常由网站Ref组装). 任何装备的叶子节点 都要用"Ahu和屋顶"过滤器

注意,这与设定目标"ahu"不同,在这种情况下,默认行为是导航一个平面的"ahu"记录列表. 或者你可以将“ahu”目标配置如下:

// configured on uiMeta
ahuNav: "siteRef"

您可以在设置 QQUI QQ测试 Nav 中测试 NavAuxFilters 。

注:导航树(无论有无NavAuxFilter)做 *not *过滤母节点. 例如,如果您按站点/设备/点对点进行导航,那么所有站点即使不包含点,也会显示为树根.

只安装项目 ​

在边缘环境中使用SkySpark时很常见,一个单一的站点可能拥有分布在多个项目/主机上的设备记录. 在此情况下,建议将站点消化器放入顶级组合项目,并配置设备作为导航根:

  1. 设置 uiMeta.equipNav 转到空字符串,这样设备就不会按站点分组
  2. 设置尽可能广泛地装备 siteRef 你能成为跨项目的参考文献
  3. 使用绝对 dis 设备上标记; 无法使用 disMacro

旨在通过系统检测设备是根实体类型时,构建工具将使用 navCluster 四. 通则 siteRef 拣者.

站点构建根 ​

默认情况下, SiteBuilder 的使用 site 作为创建的根实体. 若为 equipNav 设置为空字符串,然后 equip 用作根实体。 您也可以手动配置 uiMeta 上的 root dict , 使用一个名为 的标签 siteBuilderRoot 与Dict价值。

如果您想要在站点级别上创建一级实体类型, 请确保您的 Haystack 4 defs 设置 。 以下是一个"营地"级别的例子:

// Define a def for campus
def: ^campus,
is: ^entity
children: [
  {site}
  ]

// Define campusRef
def: ^campusRef
is: ^ref
of: ^campus
containedBy: ^campus
tagOn: ^site

// Change SiteBuidler root
uiMeta
siteBuilderRoot: {dis:"New Campus", campus}

搜索中 ​

导航框架提供可选的自由形式搜索,其搜索模式语法如下:

  • *<glob>* 大小写 ? 和 QQ 通配符( 默认)
  • re:<regex> 正则表达式
  • f:<filter> 大草堆过滤器

glob和regex图案与唱片的显示字符串相匹配. 默认的 glob 模式将匹配显示字符串内的任何子字符串, 并带有一个隐含 * 在模式的开始和结尾。 还可以使用 ? 以匹配单个字符和 * 以匹配图案中的多个字符。 正则表达式模式可能通过将搜索字符串前缀为“re:”来使用,并使用 Regex.

您可以指定一个 filter 通过将搜索字符串前缀为"f:"来表达. 这将使用与函数相同的规则匹配记录,例如 readAll().

您可以使用 parseSearch() 函数。


概览 ​

概览 ​

Fresco是在SkySpark建立基于网络的用户界面的框架. Fresco包括一套内置的强大的工具,用于管理SkySpark项目,以及一套丰富的可视化SkySpark数据的工具. 另外它还包括一组扩展的API集,供您建立自己的用户界面.

建筑 ​

Fresco是一个HTML5单页应用程序,用Fantom转录到JavaScript. 以下是该架构的主要模块:

  • sys: Fantom 系统库
  • dom: 浏览器 DOM 和 CSS 操作
  • domkit: 基于 DOM 的部件工具包
  • haystack: 海斯塔克数据建模
  • skyarc: 标签、 func 、模板等的反射 API
  • ui:弗雷斯科框架

概念 ​

弗雷斯科框架围绕这些核心概念:

  • Apps: 视图的逻辑分组
  • Views: 设计用于可视化数据网格的UI基本组件
  • Actions: 在视图中命令与系统互动
  • Navigation:系统存储数据的组织和导航
  • Templates: 数据输入格式的定义

资源 ​

概览 ​

本章涉及与外部资源文件合作时的一些问题. 资源文件最常见的案例是图像文件.

URIs 语录 ​

在使用浏览器和服务器环境之间的资源文件时,支持以下的URI方案:

  • http://host/path: 绝对 你很了解HTTP URI
  • https://host/path: 绝对 HTTPS URI
  • /pod/{podName}/path: 资源捆绑在一起 Fantom pods
  • /proj/{projName}/io/file: URI 到项目文件 io/ 目录
  • /icon/name?s=outline&c=F00编号: SVG icon
  • /path: 阅读/写入文件的最一般URI形式 virtual filesystem 使用 URI 到 a file op。上面所有非HTTP URI都是这种一般格式的专业。

注意HTTP/HTTPS URI在导出时需要通过 *server *上的网络加载文件. 在可能的情况下,应避免使用,特别是当服务器受到限制或没有公共IP连接时。

Pub 用户界面 ​

您可以配置系统,以便在每个Fresco HTML页面中自动插入额外的JavaScript和CSS文件. 要启用此功能, 可将“ . js” 和“ . css” 扩展名的文件添加到“ {var}进行过/ pub/ ui/” 目录中 。 您还必须添加 includePub 标记标记到您的 uiMeta 记录。

注: ...这个特征是实验性的,可以改变.

嘞! ​

特殊 js 视图类型允许您在原始 JavaScript 代码中创建自定义视图而不使用 Fantom. 这样你就可以使用自己选择的JS技术. 通常你需要通过 pubUi 特性。 请注意您的JS代码必须使用 Fantom-to-JavaScript 编译器与 Fantom API 交互 conventions.

您的视图必须继承“ js ” , 并声明一个名为“ JsHandler” 的节点, 其对象为 UiView callback 。 这里有一个简单的例子:

dis:JS Test View
appName:misc
view:jsTestView
src:
  view:      { inherit:"js" }
  varA:      { var kind:"Number", defVal:0 }
  varB:      { var kind:"Number", defVal:0 }
  jsHandler: { var defVal:"myView" }
  data:      { expr:"readAll(site).setMeta({ sum: {{varA}}+{{varB}} })" }

以下是 JavaScript 显示访问和更新视图变量的 jsHandler 的示例代码 :

var myView = {};

// onUpdate is called to re-render the DOM with data grid
myView.onUpdate = function(arg) {

  // callback is passed information in arg object
  console.log("--- onUpdate ---");
  console.log(arg);

  // extract callback information
  var data = arg.data;   // haystack::Grid
  var view = arg.view;   // ui::UiView
  var elem = arg.elem;   // Element

  // clear all our existing elements using dom::Elem.removeAll
  view.removeAll();

  // get varA, varB from view state and get sum tag from data meta
  // note: var is keyword so methods named var are compiled to $var
  var varA = view.$var("varA");      // haystack::Number
  var varB = view.$var("varB");      // haystack::Number
  var sum  = data.meta().get("sum"); // haystack::Number
  myView.addLabel(elem, varA + " + " + varB + " = " + sum);

  // display text fields for varA and varB
  var inputA = myView.addInput(elem, "varA", varA.toStr());
  var inputB = myView.addInput(elem, "varB", varB.toStr());

  // create update button
  myView.addButton(elem, "update", event => {
    // call UiView.update with new state
    var newState = fan.sys.Map.make();
    newState.set("varA", fan.haystack.Number.fromStr(inputA.value));
    newState.set("varB", fan.haystack.Number.fromStr(inputB.value));
    view.update(newState);
  });

  // add p element for each row in grid
  for (var i=0; i<data.size(); ++i) {
    var row = data.get(i);
    var dis = row.dis();
    myView.addLabel(elem, dis);
  }
}

myView.addInput = function(parent, id, val) {
  var input = document.createElement("input");
  var para = document.createElement("p");
  var text = document.createTextNode(id + ": ");
  input.setAttribute("id", id)
  input.setAttribute("type", "text")
  input.setAttribute("value", val)
  para.appendChild(text);
  para.appendChild(input);
  parent.appendChild(para);
  return input;
}

myView.addButton = function(parent, id, cb) {
  var button = document.createElement("button");
  var text = document.createTextNode(id);
  button.appendChild(text);
  button.onclick = cb;
  parent.appendChild(button);
}

myView.addLabel = function(parent, label) {
  var para = document.createElement("p");
  var text = document.createTextNode(label);
  para.appendChild(text);
  parent.appendChild(para);
}

注: ...这个特征是实验性的,可以改变.


表格 ​

概览 ​

该表视图用于以表格格式显示二维网格数据. 其表的呈现有许多样式选择,可以用各种技术加以应用.

样式应用程序 ​

样式可以适用于每列,每行,或每个单元格基数. 表格采用四个选项样式:

  1. 将标签应用到列元中来样式列
  2. 创建一个名为 presentation 样式行; 数值 天啊, 应该是带有样式标记的 Dicts
  3. 在命名的网格元中定义演示文稿网格 presentation
  4. 将演示文稿网格定义为命名的视图变量 presentation

演示文稿网格将所有样式拉出一个允许列、行或单元格样式的网格。 演示文稿网格的每行都适用了造型规则. 演示文稿网格的每行都定义了行和/或coll选择器以及该选择的样式标记.

行选择器使用 row 标记以下值之一:

  • 数字行索引(从 你太晚时选择的负数)
  • “QQ”或“无效”选择所有行 这是什么? -:even"或" 老天爷"
  • 用于选择表头的“:页眉”

列选择器使用 col 标记以下值之一:

  • 数字列索引(从末尾选择负数)
  • "QQ" 或 无效以选择所有列
  • 字符列名称 咕
  • 条纹柱的“ 偶数” 或“ 偶数”

单元格选择器同时指定 a row 和 col 选择器。

样式的应用顺序如下(后期可能覆盖较早期的样式标记):

  1. 元列a
  2. 带 presentation 标签
  3. Gre镶嵌网格(从第一行到最后一行)
  4. 视图变量中的显示网格(从第一行到最后一行)

以下是构建演示文稿网格的一些例子:

row      col   color
-------  ----  -----
0        null  "blue"     // select first row
-1       null  "red"      // select last row
null     "ts"  "purple"   // select column named 'ts'
0        0     "green"    // select first row, first column
@xyz     null  "yellow"   // select row with id==@xyz
":even"  null  "pink"     // select even rows 0, 2, 4, ...

样式标记 ​

以下标签应用到格元上,以给整个表格样式:

  • title: 表上显示的主标题字符串
  • subtitle: 显示上表的次要标题字符串
  • hideHeader: 显示/隐藏表头列名称
  • hideRowInfo: 隐藏第一列显示的信息弹出图标
  • disableSel: 禁用表格行
  • disableSort: 禁用列排序

下列标记适用于行、列或单元格:

  • format: 用于格式化文本值的字符串模式;参见 format()
  • color: 文本或可视化颜色为 Color 字符串
  • backgroundki : 单元格背景颜色为 Color 字符串
  • fontWeight:字体粗体为"正常"或"粗体"
  • halign: 水平对齐为"左","中",或"右"
  • padding欣见 这里脸 我有 我去等问题 老 反对》、《之一是 来吧中提出的 有人问题 其他问题 Insets 字符串

以下标记仅适用于列:

  • hidden长官在国际 目录健en纲领健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健健
  • colWidth: 显示宽度的像素数
  • viz: 单元格可视化小图名称;见 Viz Cells
  • chartMin: viz的 一个单元格可视化的强制分值
  • chartMax唠آẻ
  • colors: 逗号分离 colors 热图

数字 ​

我也是 假设字符向他们提供的 , 如果柱名有相应的 Haystack def , 则使用图标和颜色来命名 。 以下规则用于确定 enum def 的显示字符串:

  1. 用途 dis 标记如果定义
  2. 用途 disKey 阎浮提 localization key 你在诫中规定:
  3. 用途 disMacro 你在诫中规定: 做出的承诺 ui::{name}
  4. 回到方案名称

由于许多通用术语 ui 本地化密钥,你会发现您通常可以省略 dis 标记 。

这个 icon 和 iconColor 标记用于配置单元格中显示的图标。 图标颜色也用于文本本身.

以下还为定义: connStatus 使用图标 :

def: ^connStatus
is: ^str
tagOn: ^conn
transient
doc: "Current status of a connector as one of the predefined strings"
enum: Trio:
  ok:       {icon:"check"    iconColor:"#1ca355" doc:"All is okay"}
  fault:    {icon:"err"      iconColor:"#db311f" doc:"Configuration problem"}
  down:     {icon:"warn"     iconColor:"#e67e22" doc:"Communication or network problem"}
  disabled: {icon:"disabled" iconColor:"#a4aeae" doc:"Manual disable"}
  unknown:  {icon:"question" iconColor:"#a4aeae" doc:"Status not computed yet"}

Viz 单元格 ​

以下字符串值用于图形化单元格:

Viz单元格按每列制成,并从列的数据中计算一个可视化分/最大.

单元格 ​

这种可视化在每个单元格中显示一个迷你条形图. 显示基于单元格数据:

  • 从左到右显示正数栏
  • 正面和负面数字,显示栏从中央向左或向右延伸
  • 下迥语 min 和 max 将蜡烛条从分钟返回到最大

泡泡单元格 ​

这种可视化与各国的细胞显示一个气泡图. 气泡面积代表电柱总分/最大值的大小。 显示基于单元格与各国的单元格数据:

  • 正数显示固体气泡
  • 阳性和阴性数字会遮蔽左侧的气泡为阴性,右侧为阳性
  • 下迥语 min 和 max 使用内缘可视化分钟的环,外缘可视化最大

热映射单元格 ​

数字数据通过单元格的背景颜色可视化. 使用以下列元来控制可视化:

  • colors: 逗号分隔的频谱颜色列表
  • color: 文本颜色
  • chartMin: 用于频谱起始的数字
  • chartMax: 用于结束频谱的数字

运行时单元格 ​

这可以想象出一个时期的时间表。 数据必须是使用 Base64 编码的字符串 discretePeriods() 函数。 网格元必须包含 hisStart 和 hisEnd 确定周期范围的日期时间 。

高盖单元格 ​

数字数据可视化,使用以下列元的180度弧

  • colors: 用于拨号的逗号分隔颜色列表
  • chartMin: 弧左侧使用的数字经济合作
  • chartMax: 弧形右侧使用的数字

模板 ​

概览 ​

模板是预定义的形式,一般用于编辑特定实体的记录类型. 模板在以下分机中定义: lib/templates.trio.

模板将使用 template 标记 。

注:模板正在逐步取消,以有利于Haystack 4 defs。 如果在 Folio 中与实体共事,则使用 defs 而不是模板 。 然而,如果你正在构建一个不需要完整的本体学的固定形式(例如通过 defx 延迟绑定),那么现在就粘贴模板。

定义 ​

模板由文件"lib/templates.trio"中的sys mod或扩展库定义. 使用以下标记:

  • template: 名称 Str( 必须是有效的标签名称)
  • dis or disKey: 显示模板名称
  • tags: 三重格式的模板标记定义

标签格式化为 Trio 省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省省 tag: {meta}。这里有一个完整的例子:

// lib/templates.trio
template:acmePerson
disKey: "acmeExt::person"
tags:
  dis: {kind:"Str" validate:"validateNotBlank"}
  age: {kind:"Number"}
  job: {kind:"Str" enum:"Boss,Worker"}

验证 ​

模板使用标准验证其项目 ValDef validation。除此之外,您ء一个顶级的 Dict 级别验证功能,以便在字段之间执行规则。 定义模板级别校验 validate 载明为 Axon 函数的标签,该函数将提议的命令 :

// example.trio
template: someExample
dis: "My Template"
validate:
  (rec) => do
    if (rec["min"] >= rec["max"])
      throw "Min not less than max"
  end
tags:
  min: {kind:"Number"}
  max: {kind:"Number"}

瓦尔代夫 ​

概览 ​

这个 ValDef 类用于模拟和定制一个给定值是如何可视化和编辑的:

  • GridTable: 自定义 Ferrari栏中的数值可视化
  • Input: 自定义如何编辑一个值
  • Form: 借鉴 Input 用于编辑一组值

元数据 ​

恺撒 基本上所有ValDef 实例都只是绕过一个Dict元数据。 以下提供了 ValDef 元数据标签的完整列表 :

  • name: 值的字符串名称(例如标签或参数名称)
  • defVal: 默认值
  • enum: 已列出值的逗号分隔字符串
  • enumExpr: Axon 表达式以动态生成列出的值
  • format: 用于通过 ValDef.text
  • hidden: 在 UI 中隐藏值
  • icon: 图标表示的逻辑字符串名称
  • uiInput: q名称 Input 类型
  • kind: 数值的字符串签名 kind 未定义所做的工作
  • navCluster∮:Ref 输入的标记标记以导航集群宽度,或者如果缺少,则只导航本地工程
  • navAuxFilter: Str 过滤器应用到导航输入来过滤叶片目标记录 - 见 Nav
  • navSelAny: 选择任何导航节点的标记 - 见 Nav
  • navSelAnyRec: 选择任何记录导航节点的标记 - 见 Nav
  • optional: 不需要标记标记(仅需要模板表单)
  • multi: 显示多个选择的标记
  • multiLine: 为 Str 使用多行文字输入的标记
  • placeholder文字字段位置持有人的字符串
  • ro: 只读的强制值
  • spanModes: 限制 Span 输入模式
  • unitless: 输入数字时不允许单位拾取器

仁爱推论 ​

ValDef的种类由从最高优先级到最低优先级的以下规则决定: 1.

  1. 明确 kind 元数据标签
  2. 按名称推断
  3. 如果有,按方顿型推断

尽可能明确 kind 应当使用标记来的指控定义 所具有的 ValDef 及早终止。 但尤其对于帕拉姆·德夫斯来说 这可能会很尴尬 所以我们也支持利用的指控惯例推断所具有的能力。 姓名的推论如下:

Name        Kind
----        ----
span        Span
dict        Dict
dicts       Dict[]
ref         Ref
refs        Ref[]
fooDict     Dict<foo>
fooDicts    Dict<foo>[]
fooRef      Ref<foo>
fooRefs     Ref<foo>[]

验证 ​

ValDefs可能使用Axon表达式提供验证功能. 验证将在浏览器和服务器环境中同时工作. 这个 validate 标记定义一个需要验证值的 Axon 函数。 在成功方面无所作为,在错误方面有例外。 如果您的校验功能是用 Fantom 写的, 请提高 ValidateErr 带有本地化误差 mesage 。

有一套预定义的 Axon 函数用于共同验证 :

  • validateFilter()
  • validateNotBlank()
  • validateTagName()
  • validateUsername()

或者可以创建自定义验证函数:

validate: (val) => if (val <= 0) throw "Value must be greater than zero"

视图 ​

概览 ​

视图是在弗雷斯科建立可堆肥用户界面的基本组成部分. 视图包含以下行为:

  • 数据输入从服务器获取数据
  • 通过Domkit制作HTML5中的数据
  • 出口到PDF报告 -噬物输入,使用户能够修改如何获取和查看数据
  • 允许用户将更改输入服务器的行动
  • 收集意见以创建新的定制复合视图

定义 ​

App一向由文件"lib/views.trio"中的sys mod或扩展库定义:

  • view: 全警探名 Str( 必须是有效的标签名称)
  • dis or disKey: 显示视图名称
  • appName: 将视图组合成 app
  • admin: 仅将视图限制为管理用户
  • su: 仅将视图限制为超级用户( 简单的管理员标签)
  • src: 查看定义源代码为 Trio 字符串文字
  • order: 命令应用程序内视图的数字值

以下是一个简单但完整的示例,在表格中显示所有站点的聚合:

view: "acmeTestView"
dis: "Test View"
appName: "misc"
src:
  view: {inherit:"table"}
  data: {expr:"readAll(site)"}

来源 ​

这个 src 标签将视图定义为抽象的语法树。 本树结构由下列节点类型组成: tree types types

  • view:树的顶层,加上任何嵌套子视图
  • data: 数据节点定义 Axon 表达式以获取数据
  • var: 变量用于参数化数据表达式,输入用户的数据,并存储配置数据
  • action: 动作用于提供命令, 通常用于向服务器返回更改

景区结构为树状排列如下:

  • 视图节点可能包含其他节点(子视图、数据、 vars 和行动)
  • 其他节点类型都是叶节点
  • 每个节点都有独有的名称;命名规则遵循附加限制的标签名称:不能从 view or export,也不包含底栏
  • 每个节点都有一个元节点

在此树上编码 Trio 将每个节点定义为 name:{meta}。视图节点被宣布为具有特殊特性的嵌入式三极魔咒。 view 我还以为是他们的名字呢

以下是一个完整的例子,显示所有带有两个嵌入子视图的节点类型:

view: {inherit: "layout"}
configVar: {var kind:"Str"}
subView1: Trio:
  view: {inherit:"table"}
  input1: {var input kind:"Str" defVal:"a"}
  input2: {var input kind:"Str" defVal:"b"}
  data: {expr:"[{{input1}}, {{input2}}]"}
subView2: Trio:
  view: {inherit:"table"}
  cmd: {action:"eula"}
  data: {expr:"readAll(kwSite).hisRead(yesterday)"}

路径 ​

视图定义被组织成一个命名树,允许在树内使用路径来引用特定的节点. 树节点路径的定义与文件系统路径大致相同,其中"."表示这个节点和"."表示我的父节点. 路径中的名称区段由“/”字符分隔。 所有节点路径都是相对的,以确保它们在视图嵌入时有效.

查看节点 ​

视图节点用于定义顶级视图和嵌入子视图. 视图通过保留名称"视图"定义其元. 支持以下视图元标记 :

  • inherit: 要继承的视图名称
  • uiType编号 : UiView 类型
  • renderAs: 如何使可视化节点(仅供内部使用)

一般情况下,一个视图要么继承了另一个视图,要么将自己的uiType定义为自定义视图. 自定义视图的使用 uiType 在方顿代码中使用domkit来让自己变身. 但大多数视图都会通过 view inheritance.

瓦尔斯 ​

变量用于管理视图状态。 可变节点使用下列标记:

  • var: 必须定义为标记标记
  • input页:1
  • binding: 将变量绑定到另一个变量的字符串路径
  • ) ValDef 包括 kind, defVal等 类.

一般使用变量作为输入,让用户对数据表达方式进行参数化. 然后当一个风景被笼罩起来时,这些投入往往 bound 到不同的顶级输入。

输入 vars 是通过 Input torch, 报告, 报告, 报告, 报告, 报告, 报告, 报告, , 报告, 报告, 报告, 报告, 报告, , 报告, , 报告, 报告, 报告, 报告, , , 报告, , 报告, 报告, , 报告, 报告, , , 报告, , , , , , , , , , , , , , , , , 报告, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , torch,该报告,该报告,该报告报告,该报告,该报告,该报告,该报告,该报告,该报告,报告报告,报告,报告,报告,该报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,,报告,报告,报告,报告,报告,报告,报告,报告,,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,报告,, defVal。如果没有指定默认值,则在输入下绘制一条红线,作为指标,用户必须选择一个数值才能加载数据。

注:变量不应作为网格输入。

参数绑定 ​

一个变量可能使用 binding 标记将其绑定到另一个变量。 绑定标签必须是字符串 path 相对变量的父视图节点。 边角 vars 跟踪该变量的值 。

表格视图可以使用 bindSelect 绑定到当前选中行的标签上。 例如,驱动一个使用当前选中内容更新的变量 id 列数 :

selectedId: { var bindSelect:"id" }

数据 ​

数据节点用于宣布一个Axon表达式,从服务器获取数据. 默认情况下,主数据节点被命名为"数据". 数据节点随 expr 元标记 。 价值 expr 是一个 Axon 表达式字符串文字。 您可以使用语法参数化 Axon 表达式 。 {{varName}}。变量会自动注入到表达式中,作为 Axon 字节。 例如:

// values of variables
alpha: "some string"
beta: 123
span: today

// expression string
[{{alpha}}, {{beta}}, {{span}}]

// expands to this when evaluated
["some string", 123, Span("today")]

输入变量和参数化数据表达式的组合是您如何创建交互视图. 当一个输入变量被修改时,它用新的值重新评价Axon表达式,这反过来又更新可视化数据(表,图表等).

安全警告:观测数据表达式不能有任何副作用! 这意味着视图数据节点只能读取数据. 使用数据表达式进行任何写作或承诺的视图可能造成安全脆弱性。

行动 ​

动作用于在视图中声明用于交互后端服务器的命令 。 通常使用动作执行表格视图中的 CRUD( 创建、 更新、 删除) 样式命令 。 行动节点随 action 标记 。 , UiView。见 Actions 详细介绍其运作情况。

继承 ​

除非您从零开始定义一个自定义视图,否则大多数视图都会使用一个名为view 继承 的特征来继承对现有视图的定义. 继承是将整个视图节点树从现有视图复制到您视图的一种间接形式. 它类似于一种观点,包括重新使用现有视图定义,并且能够覆盖继承视图中的特定节点。

继承由 inherit 在视图元a中,标签的值必须是有效的视图名称。 例如, 要继承图表视图 :

view: {inherit:"chart"}

关于继承问题,规定了以下核心观点:

  • table: 使用 GridTable
  • card: 将网格中的每行显示为 card
  • text: 显示 val 从纯文本中的第一行
  • fandoc: 显示 val 从扇形文件格式的第一行
  • form: 使用 Form
  • chart循序渐进。 chart

为了更了解遗产如何运作,

view: "base"
src:
  view: {inherit:"table"}
  alpha: {input var kind:"Str"}
  beta: {input var kind:"Str"}
  data: {expr: "[{{alpha}}, {{beta}}]" }

我们可以继承 base 并包括所有子节点,包括两个输入 vars 和像这样的数据节点:

view: "derived"
src:
   view: {inherit:"base"}

现在,当我们使用 derived 它的工作就像 base - 两个输入和一个数据表达式。 我们可以从这种继承的节点上覆盖特定的标记:

view: "derived"
src:
   view: {inherit:"base"}
   alpha: {input:R defVal:"new default"}  // R is zinc encoding for remove

在上述例子中 derived 覆盖命名为"alpha"的节点上的特定标记. “alpha”的最后有效定义是:

base version: {input var kind:"Str"}
derived overrides: {input:R defVal:"new default"}
derived effective meta: {var kind:"Str" defVal:"new default"}

从继承的节点合并覆盖标记的行为由 merge() 函数。

状态 ​

视图的当前状态是 Dict ,它能捕捉树中任何具有非默认值的变量节点的当前值。 如果有巢景,他们的状态被巢景的诏令所俘获. 用命名的标签捕捉到相关视图 view.

自定义 ​

一些观点可能韵律化,添加元数据.

表单 ​

Form视图的默认试验性显示名为"BasicForm",将简单地列出每个返回的网格行的字段和标签. 字段标签转换为 a ValDef 将使用 ValDef.dis 标签文本 :

view: "demoTenantForm"
src:
  view:   {inherit:"form"}
  submit: {action:"recFormCommit"}
  data:   {expr: "read(demoTenant, false).recForm(\"demoTenant\")"}

为了更加灵活,可以添加 templateName 以启用“TemplateForm”。 见 ValDef 和 Templates 更多信息:

view: "myForm"
templateName: "myTemplate"
src:
  view:   {inherit:"form"}
  submit: {action:"recFormCommit"}
  data:   {expr: "read(site, false).recForm(\"myTemplate\")"}

当启用模板表单时正在开展多个元数据值,您可以踊跃调整您的视图。 这些值可以作为标签存在于您的视图中 rec 或 view 元a.

  • showDis:通过默认的TemplateForm,将使用def名称进行字段标签. 这个 showDis 元强制对字段使用 dis 。
  • hideAdd: 此窗口将“ 添加标签” 按钮隐藏在窗体底部 。

示例

view: "myForm"
templateName: "myTemplate"
src:
  view:   {inherit:"form" showDis hideAdd}
  submit: {action:"recFormCommit"}
  data:   {expr: "read(site, false).recForm(\"myTemplate\")"}

订购 ​

默认情况下, 在其应用程序内根据显示字符串命令查看 。 您可以通过应用 order 在视图定义上使用 0 到 999 之间的数字值标记。 如果省略了命令,则假定默认为500。 具有相同顺序值的视图通过显示排序 。 SkyFoundry视图将在列表开头使用1xx用于预定义视图,并在列表结尾使用8xx命令查看视图. 使用 views() 函数以查看指派给视图的顺序。

默认视图 ​

当用户切换到一个工程时,默认情况下他们可以看到显示用户所有可用的应用程序的"Home"视图. 然而,用户可以被配置,以便在切换到项目时直接导航到特定视图. 有几种方法可以配置这种行为. 见 defView 标记文档的详细信息。