Focus UI是基于HTML5和MVP设计模式的UI组件库, 包括图形可视化/通用组件/表单管理等模块, 用于快速构建高性能Web应用和数据可视化
组件开发库主要包括两个文件
<!-- 引入js库 -->
<script src="http://focus-ui.com/download/latest/focus-ui.min.js"></script>
<!-- 引入css样式(如果不使用通用组件,可省略) -->
<link rel="stylesheet" href="http://focus-ui.com/download/latest/theme/bootstrap.min.css">
请参考Hello World
适用于任何支持HTML5的浏览器
以下是一个简单示例
运行结果如下
整个系统架构遵循MVP设计模式
一个数据模型可以同时驱动多个不同的视图组件, 事件交互一般只需修改模型中的数据, 组件会监听数据变化更新视图
ZObject是组件库中所有数据元素(Data/Node/Link/...)和视图组件(GView/Grid/Tree/...)的根类, ZObject的方法适用于所有数据和视图组件
以下是ZObject对属性进行增删改查的操作方法
var data = new z.Data({
name:"focus-ui"
});
data.set("version","2.0");
data.set({
"name": "focus-ui",
"version": "2.0"
});
var data = new z.Data({
name: "focus-ui",
version: 2.0
});
data.get("name"); //"focus-ui"
var data = new z.Data({
name: "focus-ui",
version: 2.0
});
data.remove("name"); //"focus-ui"
var data = new z.Data({
name: "focus-ui",
version: 2.0
});
data.has("name"); //true
data.has("city"); //false
var data = new z.Data({
name: "focus-ui",
version: 2.0
});
data.gets(["name","version"]); //{name:"focus-ui","version":2.0}
data.gets(); //{name:"focus-ui","version":2.0}
数据模型由数据元素Data和容器Provider组成
数据元素是经过封装的Object对象, 是z.Data及其子类(z.gv.Node/z.gv.Link/...)的对象, 主要包含以下两个功能
/**
* 创建data对象
* 此处的new可以省略, Data内部做了处理
* 参数为一个object, 是data的初始化参数, 可以省略
*/
var data = new z.Data({
name: "focus ui",
version: 2.0
});
/**
* 设置data属性,
* 可以单个设置, 也可以通过object批量设置
*/
data.set("version", "v2.2");
data.set({
url: "http://www.focus-ui.com",
email: "taozh1982@gmail.com"
});
/**
* 获取data属性&获取data所有属性
*/
console.log(data.get("name"));//"focus ui"
console.log(data.gets());//属性object
/**
* 删除data属性
*/
data.remove("email");
/**
* 事件监听器
*/
var listener = function (event) {
console.log(event);//{property: "version", new_value: "v1.1", old_value: undefined}
};
/**
* 添加事件监听
*/
data.addChangeListener(listener);
/**
* 移除事件监听
*/
data.removeChangeListener(listener);
请注意, Data中用于显示的属性名可能会和业务属性冲突(比如type属性), 可以考虑把业务属性作为一个整体对象存储到Data中(比如client:{type:'spine',...})
属性容器Provider有两个主要功能
/**
* 创建Provider对象
*/
var provider = new z.Provider();
var data1 = new z.Data({name: "data1"});
var data2 = new z.Data({name: "data2"});
var data3 = new z.Data({name: "data3"});
/**
* 添加Data对象
* 可以添加一个或者通过Array一次添加多个
*/
provider.add(data1);
provider.add([data2, data3]);
/**
* 删除Data对象
*/
provider.remove(data1);
/**
* 检查是否包含Data对象
*/
console.log(provider.contains(data1));//false
console.log(provider.contains(data2));//true
/**
* 查找Data对象
* 可以通过属性/属性集合/回调函数进行查找
*/
provider.find("name", "data2");//data2对象
provider.find({name: "data2"});//data2对象
provider.find(function (data) {//data3对象
return data.get("name") === "data3";
});
/**
* 过滤Data对象
* 可以通过属性/属性集合/回调函数进行过滤
*/
provider.filter(function (data) {
return data.get("type") === "group"
});
/**
* 返回所有Data对象数组
*/
var arr = provider.toArray();
/**
* 遍历所有Data数据
*/
provider.each(function (data) {
console.log(data.get("name"));
});
/**
* 清除所有Data数据
*/
provider.clear();
事件主要分三类:
对于所有添加到provider的data, provider都添加了data的属性变化事件监听, 当data属性发生变化时, provider会监听到事件, 然后将事件进行转发
这样就不用针对每一个data都添加属性变化事件监听了, 只需要在provider添加即可, 针对大量数据的情况, 这种实现非常方便
派发出的这些事件, 会被view组件监听到, 然后根据具体的事件更新组件
/**
* provider中data的增删事件
*/
provider.addProviderChangeListener(function (event) {
console.log(event);//{type: "add", data: $Data}
});
/**
* provider中data的属性变化事件
*/
provider.addDataChangeListener(function (event) {
console.log(event);//{property: "name", new_value: "hello", old_value: "data2", data: $Data}
});
/**
* provider中data的index顺序变化事件
*/
provider.addIndexChangeListener(function (event) {
console.log(event);//{data: $Data, new_index: 0, old_index: 1}
});
大部分场景下, 数据都是以JSON或者Object对象的格式, 通过组件的setData方法设置的, 组件会解析这些数据, 生成对应的数据模型来驱动视图组件
视图组件用于数据的渲染, 不同的组件以不同的方式显示数据, 同一个数据模型可以同时驱动多个相同/不同的视图组件
组件库主要包括图形可视化和通用组件两部分
| 组件 | 功能描述 |
|---|---|
| 图形可视化 | |
| GView 文档 | 基于canvas实现的图形可视化组件, 可以通过Node节点、Link链路、Group分组和Subview子图等图形元素, 实现拓扑图、设备面板图、流程图、组织架构图等 |
| 数据列表 | |
| Grid | 以表格的方式呈现数据 |
| Tree | 以树的方式呈现层次数据 |
| TreeGrid | 以树表的方式呈现数据, 在表格的基础上添加了树层次功能 |
| ListView | 以列表的方式呈现数据 |
| 导航 | |
| Tabs | 选项卡 |
| Menu | 菜单 |
| 弹窗 | |
| Tooltip | 信息提示 |
| Popover | 弹窗 |
| Notification | 通知 |
| Loader | 加载面板 |
| Modal | 对话框 |
| 其他 | |
| Collapse | 折叠面板 |
| Pagination | 分页 |
| 表单 | |
| z.form.Form | 表单管理器用于表单管理(value/status) |
| z.form.Validator | 表单校验器用于表单元素校验 |
调用组件的构造函数以创建组件对象(new关键字可省略)
//GView
var gv = z.gv.GView({
appendTo: "#gvDiv", //指定组件所在的HTML元素
data: dataArr, //设置数据
label_field: "label" //设置属性
});
//Grid
var grid =new z.widget.Grid({
appendTo: "#gridDiv", //指定组件所在的HTML元素
columns: [ //设置表格列
{name: "#", field: "index"},
{name: "Language", field: "language"},
{name: "Ratings", field: "ratings"},
{name: "Change", field: "change"}
]
});
grid.setData(dataArray) //使用setData方法设置数据
以下属性适用于大部分视图组件
| 组件 | 功能描述 |
|---|---|
| appendTo | 组件所在的HTML元素 |
| data | 要显示的数据, 也可以通过setData方法进行设置 |
| 显示属性 | |
| label_field | 视图Label标签显示的数据的属性名, 默认为name |
| 交互属性 | |
| selectable | 视图上的数据是否可选中 |
| checkable | 视图上的数据是否可被勾选 |
| hoverable | 视图上的数据是否可悬停 |
| expandable | 视图上的数据是否可展开 |
大部分属性既可以在数据元素上设置也可以在组件列表上设置, 数据元素上的优先级大于视图组件上的, 如果元素设置了属性就用元素上的, 如果没有设置就用视图上的
视图组件默认提供了基本的选择、单机、双击、勾选等交互功能, 可以通过如下函数监听这些交互事件
//单击事件
view.onDataClick(function (evt) {
console.log("onDataClick", {"data": evt.data.get("name")});
});
//双击事件
view.onDataDblClick(function (evt) {
console.log("onDataDblClick", {"data": evt.data.get("name")});
});
//勾选事件
view.onCheckChange(function (evt) {
var checkedArray = view.getChecked();
var checkDataNameArray = [];
checkedArray.forEach(function (data) {
checkDataNameArray.push(data.get("name"));
});
console.log("onCheckChange"+checkDataNameArray.join(","))
});
//选择事件
view.onSelectChange(function (evt) {
var info = {"type": evt.type};
var dataArray = evt.data;
if (dataArray.length > 0) {
var dataNames = [];
dataArray.forEach(function (d) {
dataNames.push(d.get("name"));
});
info.data = dataNames.join(",");
}
console.log("onSelectChange", info);
});
//选择批事件
view.onSelectBatchChange(function () {
var last = view.getLastSelected();
var info = {};
if (last) {
info.lastSelect = last.get("name");
} else {
info.lastSelect = "none";
}
console.log("onSelectBatchChange", info);
});
//展开事件
view.onExpandChange(function (evt) {
console.log("onExpandChange", {"data": EventLogUtil.getNames(evt.data), "type": evt.type});
});
视图组件的数据操作、选择、勾选、悬停等功能和事件监听都通过功能接口统一实现
为了方便组件使用和前端开发, 系统提供了以下工具类
工具类的使用请参考API文档