milestone相关前端控件的设计方案
原来的需求是模拟visio里面做出来的时间线的效果,所以我就做成了下面那种方案;这几天闲逛,看到别人做的不错的设计,我这里记下来;
我初步看了一下前端代码绘制部分基于svg d3.js;
下面我来说说我认为他的这种设计到底好在哪里,从用户视角:
采用明显的颜色来区分,已完成迭代,当前迭代,未开始迭代
虽然我那个设计中也采用了颜色进行状态区分,但是线条小,视觉上不如这个明显;
环形的进度显示相对于单纯的百分比数值显示更能聚焦人的注意力,
不仅记录进度还加入了相关的代码量和工作量记录,将用户可能关注的相关要素集中呈现,避免二次对照的过程;
当区段的长度相对小时,隐藏了代码量部分的显示,改成了鼠标浮动时显示完整信息;
鼠标浮动于当前时间点是,提示总体的一些进度和汇总信息;
还可以注意到一些这样细节,同一段的的斜杠前后的字体大小或者颜色的变化的设计,都一样或者过于整齐的设计容易让人产生视觉疲劳;
其他的一些点,状态图的信息提示栏提供了更详细的描述信息;
采用了更多的进度和趋势的图形辅助,更直观明了;
还有一个我认为不错的特点,右上角的播放循环展板的功能;
看了一下这个项目的前端公共依赖:
echarts.js
EventEmitter.min.js//EventEmitter v5.2.5
jquery-3.3.1.min.js//jQuery v3.3.1
jquery-ui.min.js//jQuery UI - v1.11.0
jquery.gridly.js//1.2.9
bootstrap.min.js//Bootstrap v3.3.7
Bootstrap: popover.js v3.2.0
Bootstrap: tooltip.js v3.2.0
bootstrap-slider.min.js//10.0.2
pnotify.js
bootstrap-table.js//1.12.1
jquery.dataTables.js//DataTables 1.10.4
dataTables.bootstrap.js
dataTables.rowsGroup.js//RowsGroup for DataTables v2.0.0
ColVis.min.js//1.0.8
DT_bootstrap.js
ckeditor.js//2003-2018
ckeditor/styles.js
ckeditor/lang/zh-cn.js
d3.js//3.2.8
jqPaginator.js
select2.min.js
bootstrap-multiselect.js//Bootstrap Multiselect v0.9.8
基本上是使用jquery+bootstrap的前端结构,并没有使用一些当前流行的前端框架,但是代码逻辑还是清晰的;
/*-------------------------------------------------------------------------------------------------*/
less教程
https://www.ibm.com/developerworks/cn/web/1207_zhaoch_lesscss/
交互设计文档设计的一些查询记录
https://cloud.tencent.com/developer/article/1165820
https://www.cnblogs.com/JoannaQ/p/3900463.html
https://www.ctolib.com/topics-36574.html
https://zhuanlan.zhihu.com/p/21577848
http://www.yzsekj.com/cn_asp/m_newsview.asp%3Ftypeid%3D60%26id%3D83
https://wemp.app/posts/7b00dafd-a935-4c9a-a6cb-0bc0587ce6de
/*--------------------------------------------------------------------------------------------------*/
/*------------------------------------分割线-----------------------------------------------------*/
/*-------------------------------------------------------------------------------------------------*/
基于angularjs和mxgraph的里程碑计划控件
控件效果:
控件实现:
首先下载 :https://github.com/jgraph/mxgraph 最新的版本
需要其中的mxgraph-master\javaScript\examples\grapheditor\www目录中的所有和src中的mxClient.js文件,
控件模板:
年 | {{year}} | 操作 |
---|---|---|
月 | {{month}} | |
{{tData.title}} | //这里要注意这里$index 如果放到里面回合checkbox扩展的相关功能冲突,$index始终为用tdata为参数始终为第一个的问题 //同时写在外层也会有触发两次的问题使用preventdefeat处理 |
控制器:
angular.module('xxx.milestone', []).component('mview', { controller: ['$scope', '$http', '$window', '$stateParams', '$timeout','$compile', 'xxxService', function($scope, $http, $window, $stateParams, $timeout,$compile, xxxService) { var tid = 0; var oldtid = tid; Object.defineProperty(this, 'tid', { get: function() { return tid; }, set: function(newVal) { if(oldtid!=0 && oldtid == newVal){ return; } oldtid = newVal; tid = newVal; console.log('tid changed:', newVal); $scope.timelineId = tid; $scope.initData(); } }); var contextpath = window.Ruban.contextPath; $scope.RangeYear = []; $scope.RangeMonth = []; $scope.timelineData = []; $scope.addMile = {}; $scope.xml = ""; $scope.timelineId = 1; $scope.initDraw = false; $scope.ht = 300; $scope.contentRestore = {}; $scope.initData = function () { var param = { "timelineId": $scope.timelineId }; $scope.ht = $scope.timelineId.split(",").length * 300; var url = contextpath + 'api/private/xxxx/getTimeline.json'; xxxService.commonPostJQlike(url, param, function (response) { if(!response.data.success){ window.location.href=contextpath +"xxxHome.html#!/error"; return; } $scope.timelineData = response.data.data; $scope.xml = response.data.xml; var bgDate = new Date($scope.timelineData[0].bg); var edDate = new Date($scope.timelineData[0].ed); $scope.RangeYear = []; $scope.RangeMonth = []; for(var i = bgDate.getFullYear();i < edDate.getFullYear();++i){ $scope.RangeYear.push(i); for(var j=1;j<=12;++j){ $scope.RangeMonth.push(j); } } if($scope.RangeMonth.indexOf(edDate.getFullYear())==-1){ $scope.RangeYear.push(edDate.getFullYear()); for(var j=1;j<=12;++j){ $scope.RangeMonth.push(j); } } $timeout(function() { if($scope.initDraw==false){//attan drawInit($scope.xml); $scope.initDraw = true; }else{ //$('#eContainer').html($scope.contentRestore["htm"]); drawInit($scope.xml);//updateDraw--pro in this scene //这里不用updateDraw是因为当控件在ng-repeat中显示的时候,angularjs刷新子元素的一些过程导致开始的mxgraph绑定失效 } date(); }); }); }; $scope.addMileStone = function(e,cid) { e.preventDefault(); $scope.currentStone = $scope.timelineData[cid]; $scope.addMile = {}; $("#addMileModal").modal(); }; $scope.submitMileAdd = function() { $("#add_mile").attr("disabled", "disabled"); var req = { "timelineId":$scope.currentStone.id, "addMile.planDesc":$scope.addMile.planDesc, "addMile.planDate":$scope.addMile.planDate }; var url=contextpath+"api/private/xxxxx/addMileView.json"; xxxService.commonPostJson(url,req,function () { .... }); }; $scope.updateMileStone = function(e,cid) { e.preventDefault(); $scope.currentStone = $scope.timelineData[cid]; $timeout(function() { date();//用于刷新新增的日期控件功能 }); $("#updateMileModal").modal(); }; $scope.submitMileUpdate = function() { $("#update_mile").attr("disabled", "disabled"); var req = { "timelineId":$scope.currentStone.id, "milestone":$scope.currentStone.milestone, "title":$scope.currentStone.title }; var url=contextpath+"api/private/xxxxx/updateMileView.json"; xxxService.commonPostJson(url,req,function () { .... }); }; $scope.showPlan = function(e,cid) { e.preventDefault(); //console.log(cid); maybe syli double $scope.currentStone = $scope.timelineData[cid]; var req = { "timelineId":$scope.currentStone.id, "showplan":!$scope.currentStone.showplan }; var url=contextpath+"api/private/xxxxx/updateMileView.json"; xxxService.commonPostJson(url,req,function () { .... }); }; $scope.showAct = function(e,cid) { e.preventDefault(); $scope.currentStone = $scope.timelineData[cid]; var req = { "timelineId":$scope.currentStone.id, "showact":!$scope.currentStone.showact }; var url=contextpath+"api/private/xxxx/updateMileView.json"; xxxService.commonPostJson(url,req,function () { .... }); }; }], controllerAs: 'MilestoneController', templateUrl: window.Ruban.contextPath+'pages/xxxx/milestone.html', bindings: { tid: '@' } });
使用形式:
后端的一些实现:
主要是使用dom4j写了一个MxGraphService的类来对显示到前端的mxgraph绘制对应的xml文件,
public static String formatXmlByInfo(List
//说明根据数据库中由timelineId查询到对应的里程碑信息来请求格式化绘图xml节点信息
public static List
//id 为用来递增为绘图图元的id,该函数用来格式化返回最基本的中间的时间线
public static List
//返回指示当前日期的位置图元
public static List
//返回计划里程碑图元
public static List
//返回实际完成时间点图元
说明:上面的格式化过程其实很简单,具体是解析参数化过后的样本结构xml获得相应的xml节点返回,注意返回的xml Node需要clone以便添加到最终的根节点;
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。