- 微信ID:qq84685009
xinglie / report-designer Goto Github PK
View Code? Open in Web Editor NEW⚡打印设计、可视化、标签打印、编辑器、设计器、数据分析、报表设计、组件化、表单设计、h5页面、调查问卷、pdf生成、流程图、试卷、SVG、图形元素、物联网、标签纸
Home Page: https://xinglie.github.io/report-designer/
⚡打印设计、可视化、标签打印、编辑器、设计器、数据分析、报表设计、组件化、表单设计、h5页面、调查问卷、pdf生成、流程图、试卷、SVG、图形元素、物联网、标签纸
Home Page: https://xinglie.github.io/report-designer/
分而治之的思路在各行各业都可以看到,设计器里也不例外。
在设计器里所有的一切都是分而独立的,比如头部元素栏、工具栏、标尺等。大到面板,小到可被设计的元素均是互相隔离且独立的,彼此之间不知道对方存在。理论上设计器中只要被拆分的界面均可以渲染到其它页面的任意位置上,这为调整软件界面布局提供了很大的便利。
分的思路也为我们插件化的工程打下了良好的基础,当某些功能不需要或添加新功能时,只需要简单的删除或增加相应的代码即可。在设计器中,所有的一切均为插件化,包括基础的工具栏、标尺、右键菜单等,这些仅是设计器中数据状态的一个展示层,不与设计器核心代码偶合
设计器中的核心模块也是采用分的思路进行开发,历史记录、剪切板、元素操作、吸附对齐、选区、快捷键等均为互相独立的模块,这些模块所有的操作都是控制内存中的数据描述,即使没有界面一样可以完成数据的修改变换。当然,界面的存在仅是对这份数据描述进行可视化展示,实时反映内存中数据的状态和对应的可操作项,便于向用户反馈和方便数据修改。
大的组织还是需要独立的单元互相合作来完成更复杂的事情
项目中所有父到子的传递均由参数直接控制,即子提供控制参数,在父级进行传参控制。所有子到父的传递均是标准的DOM
事件派发,这样更利于与第三方进行合作,只需要把设计器中的元素当成标准的HTML
标签即可,所有事件均可以通过标准的addEventListener
及removeEventListener
进行添加和移除
所有需要联动的元素均由中介者进行控制,元素各自仍是互相独立的,通讯控制则交与中介进行管理,这样在不引入中介时,彼此不会联动,引入中介时,由中介控制它们进行联动。中介模块也是插件化的存在。
基于magix的项目背后有自己的打包工具:https://github.com/thx/magix-composer
该工具不仅做代码编译,同时也检测项目中样式:未使用的、重名的、不推荐的写法等问题。检测项目中模板:使用未声明的选择器、未声明的变量、参数传递等问题。
在编译转换的同时,保证代码质量,确保每个人都写出合规的代码。
在做模板转换时,工具会尽可能的检测出模板中哪些是动态的,哪些是静态的,哪些是一次生成可反复使用的,一个变量变化引起哪些模板变化等各种信息,用于运行时最小化的改变界面。
简单来讲:通过离线的编译,使用工具提前优化好相关的代码,减少运行时不必要的处理,因为性能是从点滴做起的。
编译后的代码终归是要在浏览器里结合最新数据来渲染出界面供用户使用的。
在我以往的文章中,谈过运行时的界面更新,magix中的界面异步更新
以及在这个仓库的边界说明也聊到该项目中使用的底层技术原理及方案
底层框架及方案力求使用最少的资源来支撑更庞大的上层建筑。给定一台计算机,它的性能就是1,底层方案占用的资源和性能越少越好,这样在上层的其它应用更有发挥空间
为了全局管理,magix在document.body上统一使用代理的方式处理dom事件。同一种类型的事件,比如click,任意view可注册n多click事件,但在magix框架层面,只会注册一次。不同类型的事件,比如click和keydown,在magix框架层面使用同一个事件回调处理函数,减少对象的创建。在这个统一的事件回调里,再根据编译工具提供的相关信息,直接定位相关联的view及调用开发者提供的事件处理程序,无须任何查找算法。
事件代理靠近document的根节点,性能不一定就下降,这取决于统一的事件回调里,如何处理事件冒泡、嵌套等方案。
得益于编译时的方案,在编译过程中,对模板中的事件属于哪个view可以提前确定,相同类型的事件在一个view中有没有嵌套,也是可以提前确定,并把信息传递给运行时。
在运行时,使用编译时提供的信息,事件发生后,无须层层向上遍历dom节点,即可知道当前事件需要哪个view处理,处理完后,向上嵌套的还有没有相同的事件,来决定中断还是继续调用。
其它关于性能的点这里不再一一描述。
做一个高性能的程序是需要从方方面面,点点滴滴积累起来的,任何一个环节都需要仔细,不漏掉任何一个可以优化的点
对于未处于组合状态的元素,如果对选中的元素使用工具栏中的对齐工具进行操作,则会根据要对齐的操作,如顶部对齐,找出当前编辑区处于最顶部的元素,然后所有其它元素与该元素进行顶部对齐,其它对齐操作同样的道理。
如果在某个元素上点击鼠标右键,使用右键菜单中的对齐操作,则该次的对齐动作以鼠标下的元素为基准。如顶部对齐,则所有其它元素以鼠标下的元素为对齐元素,进行顶部对齐,其它对齐操作同样的道理。
如果所有选择的元素属于同一个组,则表示对组内的元素进行修改,该对齐操作无论是使用工具栏还是鼠标右键,均同未处于组合状态。
如果所选择的元素属于不同的组
使用工具栏中的对齐工具时,先找出当前对齐操作的参考元素。如顶部对齐,则找出当前选中的所有元素处于编辑区最上部的那一个,然后该元素所处的分组中的所有元素均不动。再从选中的元素中找出相应的顶部最大的元素,当对齐时,其它元素所处的组内元素也一起移动相应的距离。
使用鼠标右键时,参考元素直接变成鼠标下面的元素,后续对齐操作如工具栏中的动作
如果选中的元素中有编辑锁定状态,则不能使用对齐,因为编辑锁定的元素不能移动
如果选中的元素与其它元素组合,组合中有元素处于编辑锁定状态,则不能使用对齐,因为编辑锁定的元素所属的组合不能移动
本项目整体分2大部分,设计部分与展示部分。
设计部分是核心,编辑器或叫设计器本身要实现历史记录、对齐操作、复制粘贴等功能,同时管理数据和派发事件。
为了便于可扩展和插件化,设计部分的核心就需要健全和简单,这样方便后续核心功能的开发和插件的开发。
目前像顶部的可编辑元素及4个面板全部以插件化的形式存在,这里介绍下可编辑元素的设计与展示分离。
任意一个可编辑元素,如图片,它需要向设计器提供可编辑能力和根据编辑后的数据展示能力。我们可以把这2部分集成在同一个组件里,但这样做,如果离开设计器,做纯展示的话,那组件内部保存的可编辑能力在展示情况下是无用的。
一个组件的编辑能力与展示能力是分离的,在设计器中是编辑与展示均加载
而到了展示或打印时,则是这样的:
直接加载组件相应的展示层,这样就做到了设计与展示分离,无论在哪种场景下均不加载冗余数据的目标。
使用magix
的v5
版本,该库由本人所写,开源地址:https://github.com/thx/magix/tree/v5
文档链接:https://thx.github.io/magix/
使用magix-composer
的3.x
版本,该库由本人所写,开源地址:https://github.com/thx/magix-composer
该可视化项目所使用的基础组件及样式借签这里,仓库:https://github.com/thx/magix-gallery 文档:https://thx.github.io/magix-gallery/
magix-gallery
由本人发起,目前别人在维护
样式和使用的部分组件均全部在当前项目中重写和重构
2024.4.15 由于一些不太好的原因,以上类库或工具已存档私有,如果您需要上述源码,可以联系我获取。无论开源还是闭源,都请尊重别人的劳动成果。
该软件中的所有功能,整体设计和架构以及相关代码均由本人独立完成。使用的第三方组件和库在下方有说明
容器元素支持其它元素放在它内部,方便组织更复杂的界面关系
容器元素支持自身嵌套,可以无限级嵌套下去。容器元素目前开发了Table,H-Flexbox,V-Flexbox,如需要,可定制各种不同效果的容器元素。
拖动顶部其它元素到编辑区,当鼠标处于容器格子内时,相应的格子会有可放置指示,如下图
松开鼠标后,拖动的元素即放到当前格子内
首先点击容器的格子,使格子处于激活状态,如下图
此时点击顶部元素时,相应的元素添加到当前激活的格子内
当格子内有其它元素填满,无法使用鼠标点击激活格子时,可以先鼠标点击选中格子内的元素,然后再按快捷键F即可激活当前格子
容器元素比较特殊,因为需要承载其它元素,所以没办法像其它元素那样可以点击选中后直接拖动改变位置。
此时可以使用左上角的icon来拖动容器元素,此icon代表了整个容器元素。
容器的每一个格子是一个小的编辑区,所以它的大部分操作同大的编辑区,比如右键菜单等,拉框选择等。
因为格子支持拉框选择元素,所以拉框选择与移动冲突,故容器元素不能在格子内按下鼠标进行移动操作,因为该动作被分配给了拉框选择。
在设计器页面,可按shift+/显示快捷键大全对话框,不同的模式快捷键会有少量差别
按键 | 描述 | 条件 |
---|---|---|
Delete或Backspace | 删除选中的元素 | 需要编辑区选中1个以上的元素时按下有效 |
Ctrl+Z | 撤销操作 | 需要有历史记录 |
Ctrl+Shift+Z或Ctrl+Y | 重做操作 | 需要有撤销操作 |
Tab | 依z轴从小到大选择编辑区中的元素,当编辑区中的元素过多且有重叠,不方便使用鼠标选择时有用。如果按下Tab同时按下了Shift则按z轴从大到小的顺序依次选择元素 | 编辑区处于激活状态 |
Alt | 拖动对齐开启的情况下,按Alt在拖动过程中可临时关闭拖动对齐功能,减少对齐辅助线的干扰 | |
Left | 左箭头按下时,编辑区选中的元素向左移动1像素。如果按下Left同时按下了 Shift,则向左移动10像素。 | 需要编辑区选中1个以上的元素时按下有效 |
Up | 上箭头按下时,编辑区选中的元素向上移动1像素。如果按下Up同时按下了 Shift,则向上移动10像素。 | 需要编辑区选中1个以上的元素时按下有效 |
Right | 右箭头按下时,编辑区选中的元素向右移动1像素。如果按下Right同时按下了 Shift,则向右移动10像素。 | 需要编辑区选中1个以上的元素时按下有效 |
Down | 下箭头按下时,编辑区选中的元素向下移动1像素。如果按下Down同时按下了 Shift,则向下移动10像素。 | 需要编辑区选中1个以上的元素时按下有效 |
Ctrl+A | 全选编辑区中的元素或当容器元素格子激活时,全选格子内的元素 | |
Ctrl+C | 复制编辑区中选中的元素 | 需要编辑区有1个以上的元素处于选中状态 |
Ctrl+V | 粘贴剪切板中复制的元素 | 需要先复制元素 |
Ctrl+X | 剪切编辑区中选中的元素 | 需要编辑区有1个以上的元素处于选中状态 |
H | 显示或隐藏辅助线 | 需要存在1条以上的辅助线 |
Alt+H | 清除辅助线 | 需要存在1条以上的辅助线 |
Ctrl+G | 组合选中的元素 | 需要编辑区有2个以上的元素处于选中状态,且不属于同一个分组 |
Shift+G | 取消组合编辑区中选中的元素 | 需要编辑区有1个以上的元素处于组合状态 |
Ctrl+L | 锁定选中元素的编辑状态 | 至少有一元素处于选中状态 |
Shift+L | 解锁选中元素的编辑状态 | 至少有一个元素处于选中状态 |
U | 把选中的元素向上调整一个层级 | 需要编辑区有且只有1个元素处于选中状态 |
T | 把选中的元素调整到最顶层级 | 需要编辑区有且只有1个元素处于选中状态 |
D | 把选中的元素向下调整一个层级 | 需要编辑区有且只有1个元素处于选中状态 |
B | 把选中的元素调整到最底层级 | 需要编辑区有且只有1个元素处于选中状态 |
F | 当容器格子中的元素选中状态下,按下F可聚焦当前格子进行编辑 | 需要容器格子内的元素有选中状态 |
C | 清除设计区内容 | |
Shift+/ | 显示快捷键大全对话框 | |
数字1 | 打开或关闭元素面板 | |
Shift+数字1 | 打开或关闭元素面板的内容 | |
数字2 | 打开或关闭预览面板 | |
Shift+数字2 | 打开或关闭预览面板的内容 | |
数字3 | 打开或关闭数据面板 | |
Shift+数字3 | 打开或关闭数据面板的内容 | |
数字4 | 打开或关闭属性面板 | |
Shif+数字4 | 打开或关闭属性面板的内容 | |
数字5 | 打开或关闭历史记录面板 | |
Shif+数字5 | 打开或关闭历史记录面板的内容 | |
Shift+Z | 打开或关闭所有可拖动的面板,如属性、预览、元素、数据等面板 | |
Ctrl+加号 | 放大编辑区 | |
Ctrl+减号 | 缩小编辑区 | |
Ctrl+数字0 | 恢复编辑区缩放 | |
Space | 在设计区直接显示带文字输入元素的输入框 | 有且只有一个带文本输入的元素选中 |
输入框用于收集用户的输入内容,通常配合其它元素来收集用户录入的文本信息
首先从“表单”元素中,添加“输入框”到设计区,如下图
它的整体功能和“文本”非常相似,这里重点解释下“属性”面板中几个属性的意思。
输入框背后就是一个input
标签,如<input placeholder="hoder text" value="initial value"/>
指input
标签属性中的placeholder
属性,可用它设置提示输入什么样的内容
指input
标签属性中的value
属性,可用它设置默认填充的内容
用于对当前input
进行特殊标识,通常与其它程序配合时,方便识别定位。最终以markAs
这个key
存在于JSON
数据中。
设计器会对使用的input
标签提供与当前皮肤相同的默认样式,如果您需要对input
做视觉上的控制,则可以提供一个样式,如
<style>
.hide-border{border:none!important}
</style>
您需要先把上述样式添加到页面上,然后在该属性里,填写上hide-border
则输入框的边框将不可见。
用于序列化表单数据时,增加的一个名称属性,方便对数据快速识别。类似<input name/>
中的name
作用
用于把input
换成textarea
以便用户可以换行输入内容
在完成设计,嵌入到页面供用户使用时,所有的表单元素都会向外派发elementinput
事件,在该事件内,可以实时获取用户输入的内容。
比如在document.body
上添加事件监听
document.body.addEventListener('elementinput',e=>console.log(e));
该elementinput
事件增加的参数对象如下
elementType: 'form-input',//针对这个输入元素,elementType则是固定死的form-input值
elementValue: userInputValue,//用户当前输入的内容
elementName: inputName,//这是前面第5点提到的识别名称,如果未填写的话,将是一个空字符串
elementInput: input//用户正在输入使用的input框 dom节点对象
在设计器中,服务端数据仅是辅助功能,因此在设计器中使用http
接口,未来也将会一直如此,这部分的接口配置可查阅:#27
IoT 对数据要求实时性,因此优先采用 WebSocket 连接,这就需要设计器中的数据源字段与 WebSocket 推送的数据进行一定的配合
在 viewer.html 预览器入口中,可配置 iotUrl 直接为 WebSocket 地址 iotUrl: "ws://your.address"
即可对接真实的服务端数据,目前 WebSocket 的数据格式要求返回如下格式的 JSON
{
type: 'data'|'heartbeat',
success: boolean
message: 'exception message',
data: object
}
其中的 data 的 key 要求与设计器中数据源中的绑定的字段名称要一致。
同时在首次连接到 WebSocket 服务器时,需要全量推送页面中需要的数据,在后续数据有变化时,可只推送变化的部分,否则页面中未收到数据的可设计元素将展示设计器中给定的初始状态
IoT 预览器中如果对数据实时性要求不高,可支持配置 http 协议的接口,格式如下
iotUrl: "//pull.data.url^//push.data.url"
如果仅展示不需要通过 IoT 预览器向服务器发送数据,则配置成 iotUrl: "//pull.data.url"
即可
该元素基于"数据-数据表格"构建而来,数据表格帮助信息可参考:数据-数据表格
首先添加“数据采集”元素到设计区
因为要在一个表格中完成复杂的操作,所以在左侧会提示相应的行完成什么样的需求
它可与下面的标题行配合制作复杂的表头,也可以作为容器,承载其它元素。头支持添加行、拆分、合并单元格等操作。
如果不需要,可以在属性面板中对头进行隐藏
用于描述数据列的标题,标题行只允许一行,且不允许合并拆分单元格,如果需要复杂的表头,需要和头进行配合使用。
用于显示静态数据或输入框,用于采集数据,数据行支持添加、删除行,但在只有一行时,禁止删除。同时它也不支持拆分合并单元格
用于对数据行的求和等功能,它也不支持添加行、拆分单元格等操作
如不需要,可以在属性面板中隐藏
与头的功能相同,支持添加行、拆分、合并单元格等操作,允许自定义复杂的格子。
如不需要,可在属性面板中隐藏
数据采集头、合计、尾隐藏后,就是一个基础的表格
除合计行外,其它单元格均支持设置单元格内容为输入框
首先选中某个单元格,在右侧属性面板中,格子内容选择输入框即可
不同的格子内容,下方可供配置的选项不同,输入框的相关配置信息可参考:表单-输入框
至此我们就完成了在设计器中对“数据采集”的介绍,关于使用请参考下方的使用说明
辅助线用于在某个坐标固定留下一根参考线,用于元素的吸附对齐等其它操作
当鼠标在x轴或y轴标尺上移动时,跟随鼠标会有一个水平或垂直的辅助线,如下图
此时鼠标左键单击,会在当前位置留下一条固定的辅助线,如下图
固定的辅助线会多出一条拖动手柄,即上图中一小段较宽的部分,该固定辅助线可以通过鼠标拖动这个手柄改变位置。
也可以单击这个手柄激活,手柄激活后显示如下图:
显示一个空心的矩形,手柄激活后,可以使用键盘的左右箭头(垂直辅助线)或上下箭头(水平辅助线)按键进行调整。
每按下一次移动1px,如果按下箭头方向键的同时,按下了Shift键,则每次移动10px
可使用快捷键H临时隐藏或显示已经存在的辅助线
可使用快捷键Alt+H清空所有辅助线
更多快捷键可参考:通用设计器快捷键大全
以下讨论需要一定的前端基础
report-designer
项目有自己的组件组织方案及打包方案,详情可参考:相关技术及链接。如果你对report-designer
自带的组件方案不是很熟悉,则可以使用第三方的样式和组件
report-designer
会对整个项目的ts
、style
及html
做整体编译,针对样式可以识别出哪些样式声明了却未使用,哪些使用了但未声明等,这种方式有利于把report-designer
放入任何其它库或框架组织的页面当中。
但这种方式会对使用第三方的样式时稍有影响,下面将会详细讨论
以下以引入
element ui
样式为例,其它同理
假设我们要使用element ui
的样式,则根据官方文档链接:https://element.eleme.cn/#/en-US/component/installation
找到从CDN
上加载样式的地址:
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
我们把上述样式地址复制下来,粘贴到我们的入口文件里:index-debug.html
及inex.html
等所有需要使用样式的入口文件里。
以下仅展示导入样式的部分代码
<title>Loading</title>
<!-- import CSS -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<style>html,body,.app{height:100%;overflow:hidden;margin:0;padding:0}html{min-width:1300px}@keyframes r{0%{transform:rotate(0)}to{transform:rotate(359deg)}}.logo{width:60px;position:fixed;left:calc(50% - 35px);top:calc(50% - 35px);animation:r 2s linear infinite}</style>
然后你就可以在任意view
里面使用第三方的样式了。
当我们利用这种方式使用第三方样式时,我们会发现编译工具magix-composer
会警告我们在html
中使用了未声明的样式,如
这是因为如前面所讲,我们的打包工具magix-composer
会对整个项目做编译,因为引入的第三方资源打包工具并不清楚,因此会发出这样的警告,如果要消除该警告,可以在gulpfile.js
里,通过配置checker
检测对象的tmplClassCheck
钩子告诉magix-composer
不对这样的样式做检测即可。
gulpfile.js里combineTool的checker配置
checker: {//代码检测
/**
* 模板中class的代码检测
* @param {string} selector 模板中使用到的样式选择器
*/
tmplClassCheck(selector) {
return selector &&
!selector.startsWith('el-') &&
!selector.startsWith('ant-');
}
},
这里对el-
或ant-
这样开头的样式不做检查,我们在引入第三方样式的时候,最好找这种以统一某个前缀的样式库,方便做样式处理。
当然这里如果不配置,仅会出警告而已,代码还是正常的。
如果配置后还有相应的检测提示,请联系我
可参考项目当中的provider
目录下的第三方组件引入方案,可动态加载,也可直接内置代码。
对于第三方组件,需要带销毁功能,否则极容易造成内存泄漏、事件一直监听等问题
以下以引入
element
为例,其它同理
根据官方文档链接:https://element.eleme.cn/#/en-US/component/installation
需要把以下2
个js
文件放在我们的入口处
<!-- import Vue before Element -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<!-- import JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
在report-designer
的view
中,render
方法改造如下
async render(){
await this.digest();
let vm=new Vue({
el: '#app',
data: function() {
return { visible: false }
}
});
this.on('destroy',()=>vm.$destroy());
}
以上仅示意代码,需要根据自己的需求进行调整。
report-designer
自带的magix
是和vue
类似的组件组织框架,拥有完善的事件监听、参数传递、组件组织等功能,如果可以请尽量使用magix
来完成界面渲染和事件处理。magix
除了完成必须的界面组织管理外,它还拥有更多的性能处理等技术方案,来保证report-designer
在复杂的界面下依然有优秀的性能,因此尽量不要在magix
中再使用其它类似的框架。
该表格元素支持与数据源中某些字段绑定,在需要对报表打印时使用
第2步,点击工具栏右侧的”数据源“面板或使用快捷键数字3(数据源面板目前默认关闭状态)
第3步,在”列表格“元素选中的情况下,可以在数据源面板上方选择要使用的数据源,该数据源需要与后端接口配合,示例中是写死的一份JSON数据。
根据提示,在数据源下拉框中选中一份数据源,则下方显示该数据源可供使用的字段
此时可以拖动1中的字段到右侧属性面板中2的区域中,即完成了列的绑定。
已添加过的列目前置灰,不允许重复添加(可不做这个限制)。
当需要删除时,把2中的字段拖出2区域松开鼠标即可删除。其中2区域中的绑定字段支持拖动排序,同时拖动添加时,也可以直接把需要的列放置到想要的位置上
编辑区”列表格“绑定数据源后显示如上
当列表格绑定的字段来源不是一个数据源时,会自动清空之前数据源的字段,所以当你想换一个数据源时,不必自己清空绑定的字段,只需要把新数据源的字段直接拖过来即可
当”列表格“绑定的数据源数据较多时,在设计区只会尽可能的显示能够显示的数据。
点击右上方的打印页面时,在打印页面会根据数据源数据的多少,自动排版分页,显示完整的待打印数据。
弧是椭圆的一部分
以椭圆为基础的形状元素目前有“弧”和"圆饼"两个
在设计区添加"弧"后,显示如下
可以通过拖动中间虚线圆上的两个角度控制点改变弧的起始和结束角度。
可以通过拖动右侧和底部的两个控制点改变弧的长轴与短轴
当起始角度和结束角度重合时,界面将不显示任何弧,如果需要显示一个完整的椭圆,请直接使用SVG中的椭圆元素
部分复杂的元素,如“圆柱”、"立方体"、”五角星“、”箭头“等,则支持调整元素上的修改点来改变元素的默认形状
拖动元素上的方形修改点,则可以修改元素的默认形状,不同元素的修改点的位置,可修改范围,及可修改方向均根据元素的不同而不同。有些元素的修改点不止一个,如”拐角“元素
则有3个修改点
有些元素由点组成,如”多边形“和”五角星“
这些元素可以删除控制点和添加控制点,用来组织想要的形状
控制点之前目前仅支持直线连结
当鼠标在编辑区的元素上点击”控制点“或”修改点“时,相应的空心圆或空心矩形会变成实心,同时右侧的属性面板中,对应点前的标题会带有淡主题色的背景,如下图
同样,在右侧属性面板中,当鼠标悬浮在相应”控制点“或”修改点“的标题时,编辑区中相应的”控制点“或”修改点“会变成实心的,告诉用户是哪个点
数据表格用于数组数据源的排版及打印,并支持数据汇总功能
从数据元素中,添加”数据表格“到编辑区,如下图
因为要在一个表格中完成复杂的操作,所以在左侧会提示相应的行完成什么样的需求
要对表格进行添加、删除行或列,需要先选中一个单元格,然后属性面板中才会出现相应的行或列的添加功能。这是因为不同单元格的行或列添加会有不同的限制
用于描述数据列的标题,标题行支持添加行、拆分、合并单元格等操作,允许自定义复杂的表头,但目前它不支持数据绑定,显示内容需要使用者在右侧属性面板中书写。
用于与数据源绑定的行,其中仅允许第一行与数据源执行数据绑定操作。绑定操作稍后介绍。数据行不支持添加行、拆分单元格等操作。
灰色的重复数据行告诉使用者绑定数据后,数组数据源的数据在这里展示出来,它不支持操作,仅示意。
用于对数据源的本页求和,累计求和及本单求和等功能,它也不支持添加行、拆分单元格等操作
如不需要,可以在属性面板中隐藏
与标题行的功能相同,支持添加行、拆分、合并单元格等操作,允许自定义复杂的格子。因为数据表格中间的数据行并不固定,为了放一些固定在表格底部的元素,可以放在底这一行的格子里
如不需要,可在属性面板中隐藏
用于对底部的留白,以便打印时放页脚等信息。留白可以在右侧属性面板中的“留白”属性中改变高度,或点击使留白处于选中状态,拖动改变高度的手柄进行调整高度。
即可在右侧对相关的单元格进行拆分、添加等操作,并在下方的内容区域可输入相关的标题文字。
在选中数据表格的情况,点击工具栏右侧的”数据源“面板或使用快捷键数字1
选择合适的数据源,如示例中的报表字段测试
拖动1中的数据字段到2中的单元格内,即可完成数据的绑定。
绑定后默认显示文本,如果需要显示成图片、条形码等其它内容,需要选中绑定的单元格,在右侧属性面板中可修改格子内容显示方式。
选中合计行的单元格,在右侧属性面板中可选择格子的计算方式,如本页累计
目前支持本页求和、累计求和及对整体数据求和,其中本页求和及累计求和在打印分页时有用。
点右角的打印,会来到打印页面。在打印页面,会根据数据源中数据的多少,及用户对表格各种行高的设置,自动生成相应页数的打印。
留白指数据表格底部与纸张底部之间的留白空间,防止表格底部太过于贴近纸张的底部
如果开启,有分页的情况下,只在第一页显示数据表格的"头",关闭则每页都显示“头”
如果开启,有分页的情况下,只在最后一页显示数据表格的"尾",关闭则每页都显示“尾”
打印时不显示头
打印时不显示标题
分页情况下,如果开启,则每页均会显示标题行,关闭时,只有第一页显示标题行
打印时不显示合计行
打印时不显示尾行
开启时,会对进行了数据绑定,但数据接口未提供的列进行删除,否则无论是否有数据均显示
物联网编辑器的源码开源吗,想学习一下
如果使用工具栏中的宽高同步工具,因为无法获知以哪个元素为准进行同步,所以会算出最大或最小尺寸然后同步,如工具上的提示
如果需要精确控制,则需要使用右键菜单
因为是精确控制,所以右键菜单只支持2
个元素选中时的同步操作,如下所示
以鼠标下的元素为要同步到的目标元素,其它元素为来源元素。
把其它元素的宽度同步给鼠标下的元素
把其它元素的高度同步给鼠标下的元素
把其它元素的宽同步给鼠标下元素的高
把其它元素的高同步给鼠标下元素的宽
不是所有元素都支持同步宽高操作,比如表格,因为宽和高都是动态的,则它无法与其它有固定宽高的元素同步,SVG中的部分元素(如贝塞尔,多边形等)也同样的道理,它们都不具备固定的宽高,所以不能使用同步宽高的功能
如果使用工具栏,则元素有编辑锁定时,不能同步,使用鼠标时,如果鼠标下的元素是编辑锁定则不能同步
如果
report-desinger
自带的元素不能满足需求,则需要开发新的符合业务的元素
首先在tmpl/elements
目录下为新元素建立自己的文件夹
在文件夹里需要放上desinger.ts
和index.ts
两个文件,其中desinger.ts
是为设计器服务的,index.ts
用于展示
如果元素过于复杂,也可以新增一个
dshow.ts
文件,专门用于设计器中交互和展示
根据元素的功能确认类型,如展示型的,像设计器自带的文本、图片、二维码等元素。交互型的如地图、富文本等,还是带数据绑定的,如单元格,还是带容器类型的,如数据表格、H-Flex等。
report-designer
提供了5
大类型的元素基类供继承,在这一步根据元素的类型来决定使用哪一个基类来继承即可
在desinger.ts
文件里,需要填充上如名称、类型、图标、是否支持拖动修改尺寸、旋转等供设计器使用的属性。
同时需要提供元素自身有哪些属性,以及这些属性在面板中如何被修改
比如元素有一个数量
属性,需要使用数字
组件来修改它,且最小为2
最大为50
,则只需要对这个属性使用数字
组件来配置,把相应的大小范围等做一个配置即可完成。
设计器提供了如数字
、下拉框
、颜色
、图片
等多达40
余种属性修改组件来供配置
这一步只需要仿照其它组件进行配置即可,无任何开发工作,至此一个元素就开发完成
只有复杂的元素才需要这一步,根据需求的不同,会稍有代码开发的工作
如果元素本身非常复杂,且属性也无法使用设计器提供的常见组件来修改,则需要开发修改元素属性的组件。
首先在tmpl/gallery
目录下增加用于修改元素属性的组件
其次在tmpl/panels/props/element.ts
文件里,进行新增组件的注册,完成后新增的组件即可正常工作
如果元素设计器自身在设计器中接收其它操作,如拖放数据、数据推送等,则可仿照其它带有该功能的元素,如数据表格
进行开发。
其实这一步和开发普通组件没有任何区别,设计器无非就是把部分属性进行可视化展示和设置。
新开发好的元素在tmpl/elements/index.ts
文件中进行导出即可展示在设计器里进行使用了。
部分可设计元素支持通过接口与数据源绑定,方便展示或打印,这里介绍下相关的数据格式和绑定思路
项目中所有用到的接口均按以下统一格式返回
{
"data":any, //根据接口的具体作用,返回相应的如数组、对象等结构的数据
"success": boolean,//接口状态,成功为true,失败为false,当失败时,最好在"message"中提供相应的失败信息
"message": "" //当接口异常时可提供的信息
}
如果您购买了源码,则设计器中所有接口统一由
designer/service.ts
中发出,而状态success
及数据data
均可以在这里适配成其它现有接口的格式,无须按这里描述的格式进行处理。
另外一种适配方案是,通过提供的配置项
response
进行适配,返回上述格式即可,设计器并不要求您一定修改现有接口为上述结构,如果您还是不明白,可以联系作者。您只需要知道上述提到的格式只是设计器默认的数据格式而已,并且可以很方便的适配成其它结构。
该接口为设计器数据源面板中,显示的树形列表,如下图所示
该接口返回后端都有哪些数据接口可供使用,可查看当前项目中使用的一份写死的格式:https://github.com/xinglie/report-designer/blob/master/apis/fields.json
说明一下data中的格式
{
"data":[{//数组格式,可设置多个数据源
"name": "地区测试",//数据源名称,必须设置
"tag": "apis/area.json",//数据源接口地址、参数或其它标识,非必须
"id": 1,//数据源id,必须且唯一
"fields":[{//数据源中包含的可使用的字段
"name": "河北",//字段名称,必须
"key": "area_13"//字段key,必须
}]
}]
"success": true,
"message": ""
}
如上述示例中的”地区测试“数据源,需要配合相应的”地区测试“这个数据接口来看:https://github.com/xinglie/report-designer/blob/master/apis/area.json
其中最关键的是”fields“这个对象,该对象需要列出 https://github.com/xinglie/report-designer/blob/master/apis/area.json 接口中可供使用的字段集合,这是绑定数据源的关键。
对于tag字段,因为开发和发布最终的请求地址会不一样,因此tag可以只存放一个标识字符串,而在最终请求时,report-designer会交由统一的数据模块进行处理,可在这个数据模块里根据一定的规则,把tag存储的标识字符串转换成真实的url。
所有元素均支持数据源的绑定,任意一个元素只要出现在属性面板中的属性也支持数据绑定。目前做了常用元素如文本、图片、条形码、二维码以及“数据”元素分组下的列表格、数据表格等的数据绑定,如果您需要定制元素或调整某些元素的某些属性成数据绑定的形式,请联系作者
元素在绑定时,内部会记录相应的接口地址或标识以及绑定的字段,在展示或打印时,由展示或打印页面根据元素绑定的接口,把数据设置到绑定信息上,而元素仅根据绑定的字段key把相应的数据取出来展示
目前只有“数据”元素分组下的列表格、数据表格等能根据数据源的数据多少在打印时自动分页
根据可设计元素的不同,需要绑定的数据源是数组还是对象也不同。比如“数据”元素分组下的列表格、数据表格等要求数组。文本、图片等要求返回单个对象,即使返回数组也只会使用第一个。
以上是个人根据以往的经验总结的格式,非必须按照执行的最终格式。包括元素绑定数据源时,到底使用对象还是数组,并非最终定论,可根据具体需求调整。
处于同一个容器内的元素支持调整z轴操作。
选中要调整z轴的元素,如果支持向上或向下调整时,工具栏中相应的按钮会高亮显示,如图
右键单击要调整z轴的元素,如果支持向上或向下调整时,右键菜单相应的功能项会高亮显示,如图
选中元素后,可以使用快捷键T、B、U、D四个按键进行调整z轴。
查看所有快捷键
如上图,编辑区右侧的元素面板,不但显示整个编辑区所有的元素层次结构,同时也支持点击选中元素以及拖动调整z轴顺序。
面板上z轴大的在上方。
只有在同一个容器格子内的元素才支持调整z轴顺序哦,比如不能把H-Flex容器中的元素拖到外面来
在网页中要实现静默打印或免去重复设置打印选项等事情,目前需要安装打印插件支持,report-designer
有自己的report-designer-server
来完成静默打印。
单纯的靠客户端无法完成静默打印,需要在当前电脑或服务器安装report-designer-server
,或者其他第三方的打印插件来支持。
这里推荐一下第三方的插件,仅供参考
只要第三方能够接收
html
打印即可使用,report-designer
可以在最后打印时,输出相应的html
交与第三方进行打印或使用。
官方站点:http://www.lodop.net
report-designer
中已集成lodop
打印功能。
官方站点:https://www.webprinter.cn/
可仿照report-designer
集成lodop
的打印功能修改为webprinter
也可仿照report-desinger-server
开发自己的打印服务,只要最终能提供http
或websocket
连接控制打印即可。
欢迎打印第三方与report-designer
进行合作。
单元格元素用于数组数据源的单个排版,批量打印
第1步,从数据元素中,添加”单元格“元素到编辑区
可根据需要添加行、添加列、合并单元格等完成需要的界面排版
第2步,点击工具栏右侧的”数据源“面板或使用快捷键数字3(数据源面板目前默认关闭状态)
选择合适的数据源,如示例中的地区数据源
第3步,拖动数据源中1区的字段,到编辑区“单元格”元素的格子里,拖到相应格子可以放置时,会有可放置提示
松开鼠标即完成了单元格与数据源的绑定操作
当需要解除绑定时,点击单元格右上角的删除图标即可,当需要替换绑定数据源或数据字段时,直接拖动新的数据字段到相应单元格即可,元素会根据是否同一个数据源,自动删除旧的绑定
数据绑定后,单击相应的单元格,在右侧属性面板中,可以选择单元格内数据的展示形式,比如展示成文本或图片或其它任意需要的格式。
单元格内容类型不同,相应的可设置属性也会不一样。
格子默认最小高度即是编辑区设置的高度,当内容较多时,可以设置由内容把高度撑开,但需要注意的是,当一行上有合并单元格时,即使某一个单元格撑开导致合并的单元格也随之撑开,但它的高度依然是编辑时的高度。
点右角的打印,会来到打印页面。在打印页面,会根据数据源中数据的多少,自动生成相应页数的打印,比如地区数据源有100条,则会生成100页。
该设计器可以嵌入到其他页面中的某个区域内,和现有系统更好的融合
为了保证显示的完整,嵌入的区块请保证至少宽960px
首先在页面中,添加如下的html
<div>
some other text
</div>
<div style="display:flex;">
<div style="width:200px">
left
</div>
<div id="app" class="app" style="width:1000px;height:600px;border:solid 1px #ccc;position: relative;overflow: hidden;">
<div class="outer"><div class="inner"></div></div>
</div>
<div>
right
</div>
</div>
<div>
<input placeholder="外部输入框测试" />
bottom text
</div>
请注意上面html
中id
为app
的节点,到时候设计器会渲染在该节点里。为了更好的体验,你可以在app
这个节点里添加一些loading
动画,设计器加载完渲染时,会清除app
节点下的内容。
完整示例源码请查看:https://github.com/xinglie/report-designer/blob/master/mini.html
在线demo示例请查看:https://xinglie.github.io/report-designer/mini.html
在设计器中默认的行为中,设计器会提供自身的一些交互方案,比如顶部元素的展示、面板的拖动处理等。
在这些交互的原则中,其中之一就是严格控制设计器显示的内容在指定的区域内,比如面板不能拖动到指定的DOM
元素外边来。这是因为宿主页面的界面和交互是未知的,我们不能干扰和影响宿主页面的展示行为。
如果要对迷你模式进行近一步的界面控制,可以使用拆分再重新组织界面的方式。
完整示例源码请查看:https://github.com/xinglie/report-designer/blob/master/split.html
在线demo示例请查看:https://xinglie.github.io/report-designer/split.html
以下讲解下代码和思路
首先组织自己想要展示的HTML
结构,如下示例
<div id="toolbar">
</div>
<div id="header">
</div>
<div style="display:flex;">
<div style="width:150px" id="left">
left
</div>
<div id="app" class="app" style="min-width:1100px;max-width:1100px;height:600px;border:solid 1px #ccc;position: relative;overflow: hidden;">
<div style="display: flex;align-items: center;justify-content: center; height: 100%;">
这里可以放一个加载动画...
</div>
</div>
<div id="right">
right
</div>
</div>
我们把设计器中工具栏
渲染到外部指定的toolbar
这个节点上,header
同理。
在设计器初始化的代码里,我们可以看到如下的代码
designer.setup({
rootId:'app',
mini:true,
panels:{
element:{
to:'left'
},
data:{
to:'right'
}
},
header:{
to:'header',
hidden:false
},
toolbar:{
hidden:false,
to:'toolbar'
}
});
我们需要指定split
为true
,否则会有一些样式上的差异。
同时我们配置了panels
、header
、toolbar
等选项,选项中to
指定设计器中的相应界面展示到哪个外部节点里,hidden
指示是否隐藏该界面,比如我想隐藏header
又不想把它渲染到外部其它节点中,则可以这样配置
designer.setup({
rootId:'app',
header:{
hidden:true
},
});
这样设计器自身将不再显示顶部元素栏
后续可以把设计器中的界面拿到外部来展示,进行一定的控制。如果界面改动量比较大,无法通过样式控制完成时,则需要自己二次开发组织相应的界面来供使用。
以顶部元素点击、拖动添加为例,默认是这样展示的。
我们如果把它拿到外部其它节点里渲染时,可能不符合交互要求,此时我们可以开发相同功能的面板,即把顶部元素放到一个面板里重新组织展示。
设计器提供了一个元素面板
,在面板里展示顶部元素并完成相应的功能,设计器已经自带了该示例,目前界面如下
元素面板
里面的行为与顶部在功能上一模一样。
后续则可以利用前面提到的,把设计器中的界面拿到外部使用,渲染元素面板
到外部节点里。
看过代码你会清楚,像这样功能保持不变,对界面重新组织的需求,只需要继承原来已经实现的View
,在html
里重新组织下界面就好。
这样我们就可以对设计器进行一定的外部控制,同时可以保护好内部的功能和界面。
/**
* 面板配置项
*/
interface OuterPanelsConfig {
/**
* 结构树面板
*/
tree?: OuterViewConfig
/**
* 属性面板
*/
props?: OuterViewConfig
/**
* 概览图面板
*/
outline?: OuterViewConfig
/**
* 历史记录面板
*/
record?: OuterViewConfig
/**
* 数据源面板
*/
data?: OuterViewConfig
/**
* 元素面板
*/
element?: OuterViewConfig
/**
* 调试面板
*/
debug?: OuterViewConfig,
/**
* 动画面板
*/
animate?: OuterViewConfig
/**
* 草稿
*/
draft?: OuterViewConfig
/**
* 资源
*/
resource?:OuterViewConfig
}
https://github.com/thx/magix-composer 打包工具会对设计器中使用到的样式做全局编译,且编译时可对生成的选择器做规则定制,比如可以对所有选择器统一添加一个report-desinger
的前缀,这样只要你项目中没有以report-desinger
开头的样式则不会冲突。
目前使用less管理相关的界面皮肤,主题已支持css3 变量,所以界面风格可以定制修改,与你当前系统页面相匹配
设计器本身也是采用区块化开发的方式,把一个个界面区块独立开发,然后在入口页面对它们统一布局管理。这样当后期需要对它们重新布局或更新功能时非常方便。
其他像面板,顶部元素面板均可以去掉或定制到其它dom节点内,以和现有的页面更好的整合。
封装
designer.tsx
文件
import React from 'react';
let idCounter = 0;
let scriptSource = '//localhost/report-designer/dist/designer.js';
let promisePools = {};
let LoadScript = url => {
let key = 'script_' + url;
let p = promisePools[key];
if (!p) {
p = promisePools[key] = new Promise(resolve => {
let script = document.createElement('script');
script.onload = script.onerror = () => {
script.parentNode.removeChild(script);
setTimeout(resolve, 20);
};
script.src = url;
document.body.append(script);
});
}
return p;
};
export default class extends React.Component {
constructor() {
super();
this.state = {
nodeId: 'designer_' + idCounter++
};
}
async updateView() {
await LoadScript(scriptSource);
if (window.designer) {
window.designer.setup({
rootId: this.state.nodeId,
mini:true
});
}
}
componentDidMount() {
this.updateView();
}
componentWillUnmount() {
if (window.designer) {
window.designer.destroy();
}
}
render() {
return (<div id={this.state.nodeId} {...this.props}>{this.props.children}</div>)
}
}
使用
designer.tsx
文件
import Designer from './designer.tsx';
//...
return (
<>
<Designer style={{position:'relative',width:900,height:400}}/>
</>)
在
vue
项目中新建Designer.vue
文件
Designer.vue中的内容如下
<template>
<div :id="designerId"></div>
</template>
<script lang="ts">
import { defineComponent, onMounted, onBeforeUnmount } from 'vue'
let idCounter = 0;
let scriptSource = '//localhost/report-designer/dist/designer.js';
let promisePools = {};
let LoadScript = url => {
let key = 'script_' + url;
let p = promisePools[key];
if (!p) {
p = promisePools[key] = new Promise(resolve => {
let script = document.createElement('script');
script.onload = script.onerror = () => {
script.parentNode.removeChild(script);
setTimeout(resolve, 20);
};
script.src = url;
document.body.append(script);
});
}
return p;
};
export default defineComponent({
setup() {
let designerId = 'report-desinger-' + (idCounter++);
onBeforeUnmount(() => {
if (window.designer) {
window.designer.destroy();
}
});
onMounted(async () => {
await LoadScript(scriptSource);
if (window.designer) {
window.designer.setup({
rootId: designerId,
mini: true
});
}
});
return {
designerId
}
},
})
</script>
使用
<script setup>
import Designer from './path/to/Designer.vue'
</script>
<template>
<Designer style="width:1000px;height:80vh"/>
</template>
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>测试</title>
<script src="https://unpkg.com/vue@next"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
<script>
let ReportDesigner = () => {
let idCounter = 0;
let scriptSource = '//localhost/report-designer/dist/designer.js';
let promisePools = {};
let LoadScript = url => {
let key = 'script_' + url;
let p = promisePools[key];
if (!p) {
p = promisePools[key] = new Promise(resolve => {
let script = document.createElement('script');
script.onload = script.onerror = () => {
script.parentNode.removeChild(script);
setTimeout(resolve, 20);
};
script.src = url;
document.body.append(script);
});
}
return p;
};
return {
data() {
return {
designerId: 'rd-' + idCounter++
}
},
async mounted() {
await LoadScript(scriptSource);
if (window.designer) {
window.designer.setup({
rootId: this.designerId,
mini: true
});
}
},
beforeUnmount() {
if (window.designer) {
window.designer.destroy();
}
},
render() {
return Vue.h('div', { id: this.designerId,style:'width:980px;height:400px' });
}
}
};
Vue.createApp(ReportDesigner()).mount('#app');
</script>
也可以像mini.html
那样,在入口页面引入designer.js
,如,然后在合适的时候,通过调用designer.setup
安装和designer.destroy
销毁
<!DOCTYPE html>
<html>
<head>
<title>report designer</title>
<!--这里引入打包后的文件-->
<script src="//localhost/report-designer/dist/designer.js"></script>
</head>
<body>
<!--可以用样式进行修饰设计器的外轮廓-->
<div id="rd" style="width:1000px;height:80vh"></div>
</body>
</html>
<script>
//此时widnow上存在designer对象,可以调用designer.setup进行安装
designer.setup({
rootId:'rd',//设计器展示在哪个节点里
mini:true//迷你模式,精简界面
});
//在合适的时候进行销毁,这里模拟10s后销毁
setTimeout(()=>{
designer.destroy();
},10000);
</script>
可点击或拖动相关流程图元素到编辑区
当元素处于选中或鼠标移上状态时,元素会出现方块形的连接点,目前仅支持通过连接点进行连线
当鼠标在任意一个方块连接点上按下时,当前元素的其它方块连接点会自动隐藏,不支持自己连接自己。?该处待讨论,是否可以自己可以连接线指向自己
当鼠标移动到其它元素上的广场连接点时,虚线会变成实线,表示可以连接。
当选中流程图中部分元素时,比如[A->B],表示编辑区有3
个元素:A元素,B元素及AB之间的一条连接线。如果只选中A或A加上连接线,此时因为B未选中,所以在移动时,A移动且连接线实时更新。
当AB同时选中时,如果连接线未选中,则对于曲线连接的,控制点并不移动。如果是AB及连接线同时选中,则是普通的移动
连接线不能参与对齐和均分,其它元素可以
控制线和流程元素不能组合,但对于[A->B],如果AB组合,则它们的连接线自动和AB组合到一起。
剪切只是快速移动元素位置的一种方式,并不改变它的关系,组合中的元素不能剪切。
连接线不支持剪切
对于[A->B],如果只是部分选中复制,则连接线并不复制,如果是全部选中,则连接线的关系也一同复制。复制后的新连接线会自动连接到新的元素上。
单独选中连接线不支持复制
连接线可以单独删除,如果流程元素被删除,则与它关联的连接线一同删除
因为元素有z
轴遮挡关系,所以如果不方便操作时,可以通过T
或B
快捷键,把元素快速置顶或置底,这样会方便操作
只有在同一个容器内的流程图元素之间才能连线
查看容器元素介绍
文本元素目前支持简单的富文本,如图所示,如果内容中包含HTML
标签,则可以打开富文本选项,进行富文本的显示
文本只支持简单的富文本,对于较长的富文本在打印时并不会进行分页打印,如果需要分页,请参考后续的几个富文本元素
对于需要输入较复杂的静态富文本时,可使用ckeditor
进行输入,该富文本元素在打印时支持分页打印。
通常富文本会是由服务端指定或生成,此时可以使用支持数据绑定的富文本元素,该元素支持分页打印
如果用户有一定的编程基础,也可以使用HTML片断,输入自己想要的HTML,且可以和数据绑定配合,以动态生成相应的HTML片断。其中模板引擎选用underscore的template方法。
记录将来计划支持的功能及可设计元素
import
动态加载模块shift
键锁定长宽比时不支持吸附)本项目提供可视化设计所需要的基础功能,比如标尺、拖动、旋转、多选、复制等。在此基础之上,设计器中可设计、编辑的元素则由插件化的形式提供,比如需要表格、图片则只添加这2个插件即可,开发人员也可以很方便的定制自己的插件
绝对定位布局要求页面宽和高是固定尺寸的,比如需要投放大屏场景,则根据大屏的尺寸设置好相应的编辑区的大小。再比如需要打印,可针对纸张大小,如A4纸设置好相应的编辑区尺寸
基于绝对定位扩展的通用设计器demo:https://xinglie.github.io/report-designer/iot.html
流式布局只需要给定宽度或不设置宽度,高度无须设置,整体自适应页面,这种更适用于活动、报表、管理等一系列的线上展示页面
流式布局demo示意:https://xinglie.github.io/page-designer/
该项目之前定位为物联网编辑器,后转为通用设计器。但下面的示例图片仍沿用之前的物联网的名称
可设计的元素在目录 tmpl/elements
下面,可根据需要添加或删除相应的元素,并更新到index.ts
中即可。
在插件里面desinger.ts
是针对设计器使用的,该文件中指示设计器能设计哪些属性,对元素能否改变宽高、旋转等功能。针对像流式布局需要对设计后的页面做展示时,最终打包的代码并不需要包含designer.ts
文件,做到了设计和展示分离
工具栏提供撤销、重做功能,同时也支持快捷键Ctrl+Z,Ctrl+Y和Ctrl+Shift+Z
6
种对齐方式,需要对齐操作时,需要在设计区中选中2
个以上的设计元素对齐按钮才会高亮可用显示
2
种同步尺寸的方式,需要同步尺寸时,需要在设计区中选中2
个以上的设计元素对齐按钮才会高亮可用显示。默认按选中元素的最大宽或高度同步,如果按下Shift键,则按最小宽度或高度同步尺寸
2
种分散对齐方式,同样需要选中2
个以上的元素
4
种调整z
轴的方式,z
轴调整只能选中1
个元素,如果某个元素已经处于最顶层或最底层,则相应的顶层调整按钮并不会启用
1
个删除按钮,需要选中1
个以上的元素时高亮可用显示
当鼠标在标尺上移动时,会显示相应的位置辅助线,在标尺上鼠标点击后,会在相应的位置留下一条固定的辅助线。固定的辅助线也可以拖动改变位置以及删除等操作。
如果需要精细的控制辅助线,请参考辅助线操作说明文档:#18
可直接拖动页面顶部设计元素添加到设计区相应的位置上。也可点击设计元素,则添加到设计区的左上角,然后再拖动到设计区中希望的位置上。
改变设计元素的位置时,支持选中1
个或多个,可直接使用鼠标拖动,可以按下键盘Up、Right、Down、Left四个方向键改变位置。每次按下移动1px
,如果在按下方向键的同时,按下Shift键,则每次移动10px
可查看当前添加到设计区中的元素,同时也支持鼠标移上后,在设计区中高亮显示相应的可设计元素,支持鼠标拖动调整设计元素在设计区中的z
轴。
在元素面板某个元素上单击时,则直接选中该设计元素。在单击的同时按下Shift或Ctrl键时,可同时选中多个设计元素
概览面板主要显示整体的布局情况,方便您对整体布局有一个全局观。概览面板中的主题色边框矩形表示当前视窗,同时它也支持拖动改变当前视窗显示的位置
根据设计区中选中的元素不同,属性面板中展示的可设计元素的属性也不同。
可设计属性在elements/xx/desinger.ts
文件中定义(xx表示相应的插件目录名称)
当设计区中选中2
个以上元素时,属性面板显示设计区的属性
当拖动元素时,会在编辑区的四周显示淡淡的主题色边框条,当拖动元素的鼠标到边框条上时,编辑区则会向该方向滚动
默认编辑区显示背景色及背景的配置,当网格选项打开时,则背景色与背景图隐藏,显示网格选项
网格默认10px
X10px
,可自行调整大小,最小4px
最大40px
,宽与高的值可不同
当网格选项打开且拖动吸附时,拖动的元素则自动磁吸到网格上。
当拖动多个元素时,则以鼠标下的元素为吸附元素,其它元素跟随移动,但不吸附,主要是因为多个元素的间距并不一定是网格的整数倍。
磁吸效果只在拖动时有效,如果通过键盘或右侧的属性面板直接修改坐标信息,则仍以最小单位1px
进行。
添加到设计区中的元素,在拖动时,会和非拖动元素自动对齐,示意图如下
水平支持对齐某元素左、中、右三个位置,垂直支持对齐某元素上、中、下三个位置
其中设计区及容器元素的格子也支持拖动对齐,同元素提供的对齐位置
支持吸附到自定义辅助线上
更多信息可参考:拖动对齐操作
https://xinglie.github.io/report-designer/absolute.html
https://xinglie.github.io/report-designer/page.html
https://xinglie.github.io/report-designer/iot.html
请联系微信:qq84685009
大佬,请教一下设计器里的有个概览图的可拖动的画布映射是基于什么方案实现的
好优秀
设计器元素支持应用@keyframes
指定的css
动画,您可以把常用动画封装成单独的css
文件,供设计器使用。
设计器目前以插件的方式使用Animate.css
提供的动画,您可以通过https://animate.style/访问Animate.css
官网了解更多信息
动画面板默认不展示,您需要通过设计器右上角的面板列表中找到动画面板通过点击图标打开,或使用快捷键:数字6
按下后打开,具体动画面板的图标及位置如下图所示
打开后动画面板将会展示在设计区的下方,如下图所示
操控区域用于设置动画时间轴的长度、间隙、重置及播放等功能
通过上图1下面的数字框,您可以修改时间轴的长度。目前默认时间最小时长为10s,最大时长为60s。可通过配置修改
通过上图2下面的数字框,您可以修改时间轴上最小时间的间隔。目前默认最小10px,最大20px。可通过配置修改
通过上图3下面的按钮,您可以停用或启用动画功能。该按钮方便您查看元素在应用动画前是什么状态,应用动画后是什么状态。
通过上图4下面的按钮,您可以一键重置时间轴到起始区域。
通过上图5下面的按钮,您可以让设计器播放或暂停动画,来查看整个时间段内或某个时间点的动画效果
通过时间轴您可以拖动时刻线查看某个时间点动画的效果
时刻线在拖动过程中,左、右两侧会出现自动滚屏提示区域,当您把拖动的设备如鼠标放置在该区域内时,时间轴会自动向右或左进行滚屏,无须您松开鼠标移动时间轴后再拖动。
通过元素区域您可以查看当前设计区哪些元素应用了哪些动画,同时您可以添加、修改、删除某个元素的某些动画
目前设计区内的元素在支持动画的情况下,将会自动出现在元素区域内(这个可通过配置修改为仅选中元素且支持动画的元素才出现在元素区域内
)。
上图1区域内的元素,会自动联动设计区元素的状态作出相应的展示,如元素只读、禁用、启用等状态。同时为了方便您的查看,当您把设备如鼠标放置在1区域内的元素上时,设计区内的对应的元素会自动出现遮盖提示,如果您还是无法确定是哪个元素,也可以通过点击使设计区内的元素选中。
通过点击上图3区域,将会打开添加动画的弹框,您可以在弹框内选择需要的动画,添加后动画将会出现在2区域内。添加动画的弹框将在后面介绍。
上图2区域内添加的动画,您可以通过点击重新打开动画选择框,进行动画的修改或替换。当您的设备如鼠标悬停在该区域内时,会出现删除按钮,如果您对该动画不满意可以删除。
上图2区域内的眼睛图标用于控制该条动画是否应用在设计区内供预览。比如您可能一次性为同一个元素添加了多个动画效果,该元素在设计区内呈现的效果是这些动画叠加后的。如果您想查看某个动画暂时去掉是什么效果,您可以点击眼睛图标,使它变成闭眼状态,则元素将不应用该条动画。通过该功能使您可以快速查看该条动画效果添加或删除后是什么效果,而不必通过反复的添加或删除相应的动画进行查看。通过点击闭眼图标可以再次应用该条动画效果。
上图2区域内的锁图标可锁定或解锁当前动画轨道的编辑,如果您对某条动画编辑满意后,可点击锁图标进行锁定,防止误修改。
通过动画轴您可以调整动画效果在时间轴上的位置及时长
上图1以品牌色出现的是操控区域,您可以通过拖动3下方的手柄调整动画时长,可拖动4上方的区域调整动画在时间轴上的位置。
上图2区域以灰色表示的则是该动画的重复次数,方便您明白动画在时间轴上的效果,如果动画只播放1次,将不会展示灰色部分。
通过动画框选择事先准备好的动画效果
通过上图1区域内您可以挑选需要的动画效果,当您选中后,相应的效果将会在上图2区域内进行预览,方便您把动画添加到动画面板前查看相应的动画效果。
通过点击1区域内的动画名称,您可以进行单选动画,如果您需要选择多个动画,则需要按下Shift键后再点击,此时您将会选中多个动画。
上图1区域内左上角带有f
角标的动画,表示该动画部分时间阶段内置了动画函数
,您在上图3区域内的动画曲线
配置只会应用到部分动画阶段。
上图1区域内左上角带有品牌色f
角标的动画,表示该动画全部时间都内置了动画函数
,您在上图3区域内的动画曲线
配置将不起任何作用。当您选中带有品牌色f
角标的动画时,上图3区域内的动画曲线
将自动进入禁用状态,避免您不必要的操作。
上图3区域内您可以对动画进行详细的配置,如果您对这些配置不太了解,默认就好,不需要做修改。
为了您更好的控制动画,建议您前往MDN
阅读动画章节(https://developer.mozilla.org/zh-CN/docs/Web/CSS/animation)
上图4区域下方的按钮,您可以确定
当前动画的配置或取消
关闭弹框
Animate.css
第一步:在入口文件如index.html
中删除或替换Animate.css
第二步:在report-designer/tmpl/panels/animate/picker.ts
更新替换后的动画名称即完成替换
第一步:把自己的动画写入单独的样式文件内,注意名称不要与现有的冲突
第二步:在入口文件如index.html
中像引用Animate.css
一样,引入您的动画样式文件
第三步:在report-designer/tmpl/panels/animate/picker.ts
添加您样式动画文件内的动画名称即完成添加
这是因为部分动画效果使用了translate
,而Animate.css
又写的值比较大,所以会撑开设计区域
首先确定的是元素旋转或透明没有失效,而是被动画里面的旋转和透明覆盖了。
以旋转为例,比如把元素旋转了30度
,而应用动画后,动画在开始的时刻又把角度旋转到了0度
,此时元素呈现的就是动画旋转的0度
效果。这也是前面操控区域
里面介绍的3区域
下方按钮的作用,方便您停用动画查看未应用动画的效果。
可以,把当前角度或透明度以变量的形式在元素上提供,动画里以该变量为起点做动画即可。
目前Animate.css
并未提供该功能,后续如果设计器提供自己的动画库时会这样做。
如果需要修改设计器的外观,可修改tmpl/assets/_var.less
提取的变量即可,具体可查看文件内的变量注释。
通常只需要修改品牌色,其它颜色自适应,如果有较强的视觉要求,则可自行调整其它颜色变量
项目支持多语言设置,但目前仅提供了中文包,如上图。
可自行提供如英文包放入并在tmpl/i18n/index.ts
中引用即可
2022-08-16已支持英文语言包,目前用于测试,只做了少量翻译。设计器实现的是无刷新语言切换,只需要仿照现有的语言包扩展其它语言即可完成多国语言版。
风险点:中文翻译成其它语言时,有可能会很长,导致界面不美观,需要根据不同的语言进行适当的界面调整
lodop无法打印,不显示任何内容
该issure仅说明文本、图片、平铺图、二维码、条形码的静态内容和动态数据绑定相关的操作
对于基础元素,文本、图片、平铺图、二维码、条形码目前也支持数据绑定,但仅支持绑定单条数据,不支持绑定数组。
以下使用文本元素来介绍相关的静态内容和数据绑定操作,其它元素类似
在选中文本元素的情况下,可通过属性面板中的内容输入框输入相应的静态内容,也可以在选中文本元素的情况下,按下Space,即空格键,则文本元素上方会显示输入框,此时输入静态文本即可。
其它元素,图片、平铺图、二维码、条形码目前只能在属性面板中输入静态内容
添加文本到设计区
如果数据源面板未打开的情况下打开数据源面板
通过图示中的2选择合适的数据源,在3区域选择合适的绑定字段,鼠标按下相关的字段,拖到属性面板中4后面的矩形区域内,即完成了数据绑定。
也可以在3区域选择合适的绑定字段,鼠标按下相关的字段,直接拖到1,文本元素上,当拖到文本元素上时,会有相应的界面提示,如下图
此时松开即可完成数据绑定
当需要解除元素的数据绑定时,需要在属性面板中,如上上图中的4后的矩形区域内,把相应的字段拖出矩形区域松开鼠标即可完成解除绑定。
目前这些基础元素即支持静态内容的输入又支持动态数据绑定,当二者存在时,如何显示?
在设计器里,二者的行为是互斥的,即当你使用静态内容后,数据绑定功能会被隐藏和禁用,在这种情况下你无法完成数据绑定。同样当数据绑定后,你也无法使用输入静态内容的功能。
在展示或打印的时候,如果你在数据中即指定了静态内容又指定了绑定数据,则优先展示绑定的数据
浏览器并不能准确的把设计器设计出来的内容打印出来,即使使用chrome,在对内容溢出隐藏的情况下打印,效果并不像网页中见到的那样。
要想获得更精确的打印,需要先对内容做转换,转换成图片或pdf。其实有了图片,转pdf是非常容易的,所以要优先生成图片。
目前在打印页面的内容转换存在诸多问题,后续提升可考虑以下3种方案。
最终渲染时,抛弃传统的dom
方式,把所有可设计元素画在canvas
上。这样后续在转换图片或pdf时,均不会产生错位、边线粗细不一等问题。
因目前所有数据均为json
描述,因此通过该方式仅仅是开发工作量的问题,技术上并没有难度,只是工作量较大且周期长,需要有人协助。
服务端渲染转成图片。全在网页客户端里处理,开发工作量大,那就通过接口借助服务端的能力。
可向服务端提交json
数据或完整的html
,由服务端生成相应的图片,具体生成方案服务端决定。
这样的工作量全在服务端,需要综合评估客户端与服务端的工作量,看采用哪种方式更省时间。
通过开发客户端或命令行的形式,如使用nodejs
,一方面提供http
或websocket
用于与设计器通讯,一方面使用如puppeteer
的插件,在收到任务后,把网页内容转换成图片并回传给设计器。
目前感觉可使用方案3,在nodejs
下快速开发测试一下。
目前设计器与预览器分别打包发布,虽然可以直接在设计器中把预览器集成进去,但这样不利于单独使用预览页面及后续的预览器扩展
设计器支持绝对布局和流式布局,因二者布局相差较大,故分仓库开发维护。
当前仓库是绝对布局的设计器,流式布局的可参考这个仓库:https://github.com/xinglie/page-designer
目前精力主要在绝对布局的设计器上,即该仓库的项目
设计器的目标是尽可能支持同质化的所有需求,包括不限于报表、海报、打印、物联网等所有2d场景下的可视化设计
未来会支持3d的场景设计
同样的设计数据,不同的预览器,最终展示会有差异。在不同的业务场景下需要做不同的加工,为了使用方便,对预览器进行了分类处理
页面预览是最简单的对设计数据的还原,因开发没有任何难度且需求非常小众,该预览器未集成到设计器中,如果需要使用可参考:#38
设计器中默认使用是固定分页预览器,根据页面大小,自动对需要分页展示的设计元素进行分页处理。
该固定分页预览器会对特定元素如数据表格
进行分页展示,分页后其它不分页元素会固定重复。
该预览器常用于多列分栏且分页后部分元素固定重复展示,这也是设计器默认的预览器
该预览器下所有数据使用http接口
对填充数据后的元素进行流式分页,比如数据表格
填充数据后,其它元素会相对填充数据后的元素进行位置偏移分页。
该预览器常用于报表或订单类型的打印,上下排列且内容会随数据变化的情况下使用。
该预览器下所有数据使用http接口
该预览器针对标签纸所做,通常设计阶段只针对一个标签设计,在打印时,需要根据配置,一行打印多个标签。
该预览器下所有数据使用http接口
对常用试卷(A3横版)做的预览器,移除不必要的按钮,让预览器更专注
设计器中也提供了IoT预览器,默认使用WebSocket进行数据交换,同时在该预览器里对数据交换层做了抽象处理,支持包括不限于ws、http、mqtt等协议,无论您使用哪种协议,均可以直接对接
如果没办法像Iot预览器那样使用WebSocket进行数据交换,可以选择该模式使用客户端轮询的方式进行数据更新。
该大屏模式下仍然使用传统的http接口,但加入了自动轮询请求的功能,同样可以更新元素绑定的数据,是对无法使用WebSocket时的一个备选方案
version 202106220825
单元格绑定了一个长字符串,结果点打印时预览发现不能换行,属性那里也没有自动换行,在保存的stage中发现autoReturn为true。
另外使用数据表格的头时,能够自动换行,但绑定内容的宽高并不像单元格一样随着单元格的宽高变化。单元格高度增加/减少了,但绑定内容没有增加/减少。修改单元格的宽高之后还需要再去修改里面绑定内容的宽高。这个是有意为之的吗?
添加到设计区中的元素,在拖动时,会和非拖动元素自动对齐,示意图如下
其中平铺图片
是正在拖动中的元素,当元素的顶、中间、底边以及左、中间、右边与另外元素的关键边靠近时,会自动吸附对齐。
吸附阈值目前设定为8px
,越小越容易脱离吸附,越大越不容易脱离吸附。
当元素旋转后,将以元素所在的矩形进行相应的对齐处理。无论旋转与否,均支持4个顶点、4条边中间点及元素中心点,水平9条垂直9条线的对齐方式。为了解决对齐线过多的问题,目前支持顶点、边中间及中心点通过配置来决定是否参与对齐。
优先鼠标下的元素参与拖动对齐(可配置为全部移动元素为拖动对齐),仅非移动元素才能成为吸附对齐对象
容器及子元素如果不参与移动,则所有子元素也可以成为对齐吸附对象。
网络功能已下线,代码已注释,如果有需求可自行放开网格代码的注释
当吸附网格与拖动对齐均打开时,对齐优先级高
设计区及容器的格子(小设计区)也支持拖动对齐
在拖动过程中,如果按下alt键,则可以临时停用吸附对齐。如果通过设计区配置为默认拖动不对齐,在拖动过程中,如果按下alt键,则可以临时启用吸附对齐
感谢大佬这么棒项目!
目前发现打印方式只能在打印的页面 复制粘贴模板JSON,然后进行打印,找了下没发现相关说明,想请教下我能不能在我的系统定义一个打印按钮,点击后传入后端的动态数据打开打印界面进行打印呢
对于像”文本“及数据集合下的”单元格“、“数据表格”等支持数据绑定的元素,在把数据源中的数据显示出来的时候,需要对显示格式进行控制
因为对绑定的数据显示控制通常只发生在“文本”上,比如需要把数字显示成千分位、时间戳显示成友好的时间格式等,以下仅说明
“文本”的显示格式操作。其它元素的数据绑定,后期如果需要对数据源进一步加工,则会增加钩子的形式来进行二次处理。
首先添加支持显示“文本”格式及数据绑定的元素,如数据分组下的“单元格”元素,添加到设计区。
显示格式仅用于对绑定后显示数据时的控制,因此需要先绑定数据才能使用
以下是设计区添加“单元格”元素并对某个格子绑定“报表字段测试”中某个字段后的效果
可以看到我们对第一行第二列单元格绑定了“报表字段测试”中的“点击量”这个字段,右下角“文本”图标指示当前格子中数据最终会以文本的内容方式显示。你可以在属性面板中根据需要,修改成图片,二维码等其它最终需要显示的内容。
在格子内容是“文本”的情况下,在下方有一个“显示格式”的属性,如下图
根据提示,点击后弹出“显示格式”的对话框
可以根据数据源是什么样的数据,如数字、时间、货币等,选择自己喜欢的格式控制,点击应用即可,比如我们选择数据中,整数部分使用千分位格式。
最后点右上角的打印,来到打印前使用真实数据填充的页面,可以看到真实的数据根据千分位的格式要求,展示如下
在显示格式里,如果没有自己想要的格式,可以进行定制,把常用格式内置进去。
也可以使用自定义,自定义是一个函数,可以完成任何需要的格式,自行体会。
代码编译降级到es2018
,所以需要除IE
之外的其它主流浏览器才可以,未来也不会支持IE
,当然Chromium
版IE
应该是支持,这个没有测试
不同浏览器如chrome、safari、firefox,以及同浏览器不同版本渲染出来的最终界面并非完全一致,渲染结果以最终使用的浏览器为准,以及相关的打印功能。
编辑区大小限制为10000px X 10000px ,以配置的形式提供,可自己调整
先定义3
个概念
指程序需要大量的运算,界面无法响应用户的任何操作。如点击某个按钮,浏览器失去响应,此时不能使用键盘输入,不能使用鼠标滚动页面等。后续处理完运算后,才能继续响应用户的操作
指程序需要大量的运算,界面不能及时响应用户的操作。如当前程序正在后台运算,用户使用键盘输入时或滚动页面时不流畅。
技术方案采用数据与界面分离的方式,数据变化后界面不会立即变化,而是使用分割任务异步更新。异步更新的速度取决于电脑的性能,性能越好异步更新的越快。
卡顿时用户仍然可以继续操作,但卡死时不可以
该可视化脚手架采用前后端分离的架构,使用JSON
交换数据。
同时可视化的技术方案采用数据与界面分离的方式,用户的所有操作及时更新JSON
数据,同时再异步更新界面。
这样只需要1
份JSON
数据既可以方便存储同时也方便还原界面。
当编辑区元素添加越来越多时,程序需要更多的内存保存数据,同时异步更新界面的时间也会变长,卡顿现象可能会出现。理论上越多元素,越容易出现卡顿,浏览器消除卡顿时间也越长。
但无论如何,不会卡死。
像我这台电脑,添加200
个图表或500
个普通元素后,全选拖动有卡顿出现。
为了更直观的告诉用户当前程序是否处于后台更新繁忙阶段,当出现不能及时更新界面时,会在程序的状态栏最右侧显示“系统正忙...”标识,告诉用户程序已经开始出现卡顿,不能及时响应您的操作了。
你可以试一下自己的电脑,看添加多少元素后会出现提示
即使采用异步更新,由于不同的电脑和浏览器,当元素过多时,report-designer无法保证一定提供流畅的操作。
鼠标在编辑区中按下,然后拖动。鼠标会拖出一个虚线矩形方框,当鼠标拖出的虚线方框与元素所在的矩形相交或包含关系时,则对应的元素进入被选中状态。
当元素被旋转后,部分元素所在的矩形也会随着旋转,同样旋转后的矩形也需要与鼠标拖出的虚线矩形相交或包含时,元素才进入被选中状态
鼠标在拉框选择的时候,按下了Shift键,则本次拉框选择会叠加之前选中的元素。即进入多选模式
任何操作如果有可能给用户后悔操作时,均有后悔操作。所有功能如果可以给快捷键时,均有相应的快捷键,尤其对于一些不便于鼠标操作时,肯定有对应的快捷键。
鼠标直接点击目标元素,目标元素进入选中状态。
在按下Shift或Ctrl的同时,使用鼠标点击目标元素,进入多选状态。当目标元素处于未选中状态时,进入选中状态。如果目标元素已处于选中状态,会取消选中状态。
依z
轴从小到大选择编辑区中的元素,当编辑区中的元素过多且有重叠,不方便使用鼠标选择时有用。如果按下Tab同时按下了Shift则按z
轴从大到小的顺序依次选中元素
当鼠标hover
在结构树面板中的元素时,会在编辑区显示一个半透明主题色矩形,告诉使用者当前对应是编辑区哪个元素。
当鼠标单击结构树面板中的元素时,该元素进入选中状态。
在按下Shift或Ctrl的同时点击结构树面板中的元素,进入多选状态。鼠标下的元素如果处于未选中状态时,进入选中状态。否则会取消选中状态。
当元素处于单选、多选、组合等状态时,其被选中元素的边框会表现出不同的显示,方便使用人员进行区分。
如果需要打印设计,需要把打印设计器的尺寸从默认的px
(像素)单位转换成mm
(毫米)单位,这是因为不同系统单位尺寸内所容纳的像素数是不一样的,如果使用px
有可能造成打印尺寸不正确的问题
在设计器中设计好的元素,在打印时会自动计算出每一页的位置和数据,所以务必把打印机默认的页边距等之类的设置为0
打印时,会自动把设计器中的元素按设置好的页面大小进行分页,因此您应该直接把页面尺寸设置为目标纸张的尺寸,如A4
或A3
,这样在打印分页时就不会被浏览器自动把元素放到错误的分页上
分页打印时,请使用chrome浏览器,其它浏览器可能会有问题
该功能方便把设计器中元素的渲染层拿出来,放到其它页面中单独显示
在设计器中设计好元素后,比如数据表格,进行了相关的行和列的设置,绑定了数据源,默认它可以在设计器附带的打印页面中展示。
如果想把这个数据表格单独拿出来,放在现有的页面中,则可以使用该功能。
首先在设计器中对需要单独展示的元素做设计,完成后单独拿到该元素的JSON
描述数据。
比如我们使用文本
元素来在其它页面中单独展示,则在设计器中只放一个文本
元素进行设计。完成设计后,在示例页面中点击保存,弹出展示编辑区数据的对话框,在这里面找到文本元素的JSON
数据,把该元素的这个完整的JSON
数据拿出来,以备在其它页面中使用。
示例图片中截图即是某一个文本元素的完整
JSON
数据描述
线上demo页面:https://xinglie.github.io/report-designer/standalone.html
源码页面:https://github.com/xinglie/report-designer/blob/master/standalone.html
打包时,会对项目中的所有元素展示层单独打包到dist/printer.js
文件里,方便在其它页面引入使用。
比如在示例页面中,先引入独立使用的js
文件dist/printer.js
,然后调用printer.element
方法,则会在相应的节点里,把指定的元素展示层显示进来。
printer.element接受2个参数 printer.element:(nodeOrId,elementJSONData)=>void
nodeOrId
:页面上渲染元素的DOM
节点或节点id
elementJSONData
:元素数据,即前文提到的该元素设计器中产出的JSON
数据
该方法无返回值
如果元素本身绑定了数据,则需要外部请求数据,和JSON
数据一起传进来,因为设计元素的展示层自身并不请求数据,需要外部准备好。
如果需要对元素拆分,则需要自己根据props
的配置信息,自行拆分,多配置几个节点即可。
并非所有的元素都支持单独拿出来使用,比如页码器,比如流程图中的连接线等,当然,这些元素在传入属性时,补充好数据也是支持单独使用的
只有处于同一个容器内的元素才支持组合操作
因为容器内的元素使用坐标是相对于容器的,所以只有同一个相对坐标固定的才可以使用组合。比如同一个编辑区内的元素或同一个容器的格子内。
组合支持工具栏、右键及快捷键进行组合操作
同一容器内的元素,即使不同的格子,也支持组合操作。
组合后的元素移动其中一个,其它元素也跟随移动
当组合内的元素与组合外的元素有对齐操作时,组合内的元素整体移动,保持相对位置
当组合内的元素对齐时,此时表示修改当前组合内部分元素的位置,按对齐操作进行相应的位置移动
组合后的元素,支持选中其中一个元素,通过右侧属性面板修改其中的属性,当通过面板修改时,修改仅影响到当前元素。如修改x,y坐标,则只有当前选中的元素移动。
这样做的目的是:可以对组合后的元素有一个修改的反悔空间,像x,y坐标的修改,如果修改当前选中的元素,组合中的其它元素也一起修改,就会造成就想单独移动一下组合中的某个元素,就需要先解散再修改,十分不便。如果选中一个但想同时移动整个组合,可以使用鼠标、键盘来整体移动,属性面板则作为单个修改的通道。
可以选中组合后的部分元素进行删除,当删到组合中只有一个元素时,则自动解除组合
在有权限设置的系统里,比如管理员和普通用户,管理员可预设一些必须存在的元素及元素位置,普通用户可在此基础上增加其它需要的元素。
管理员添加的元素在普通用户那里只读,不能调整位置、改变大小、删除等操作
设计器已支持元素只读,可查看只读示例,只读需要通过代码来设置,目前无法通过界面指定
只读元素无法调整z轴,但普通用户新增的元素支持和这些只读元素调整z轴,毕竟谁遮盖谁需要交与最终使用者决定
容器在只读的情况下也允许向格子内增加元素
如果容器元素未设置只读,而子元素设置只读,则容器可以被删除,连同只读的子元素。可设置为子元素如果有只读,则不允许删除容器
只读元素可以提供对齐功能,方便在拖动其它元素时与这些只读元素对齐
如设计区有容器,且只读,但容器内放入了普通元素,则清空时,清除所有非只读元素
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.