CBoard框架使用总结七--添加首页图表

来源:互联网 发布:贴吧找图软件 编辑:程序博客网 时间:2024/06/03 05:09

文章内容

  1. 原理概括
  2. 数据库调整
  3. 前端实现
  4. 总结

1.原理概括

在实际运用中我们可能不希望首页空白,同时希望用户客户化的配置自己想显示的图表,于是有了文章下面将要谈及的内容。

首先,由于是用户级的设置,需要在数据库建立对应的配置表(比如dashboard_user_option),用于保存用户相关配置;

其次,需要用户主页布局配置功能界面,可以参考引用系统原有的“看板设计”功能;

最后,就是图表的渲染了,同样可以借鉴现有的看板的实现(webapp\org\cboard\controller\dashboard\dashboardViewCtrl.js),其次就是确定显示的位置了,由于现有前端框架使用的是adminLTE,基于angularJS路由机制实现功能界面的跳转,所以,首页的布局可以放在ui-view中,在切换功能时,实现可以进行覆盖;

2.数据库实现

数据库的调整主要是增加由于保存用户配置的数据库表;

示例:

字段名 描述 备注 id 主键 user_id 用户ID 使用中,我们统一了主键类型为BIGINT(20) opt_key 配置键 用户每一项配置保证键值唯一 opt_value 配置值 create_by 创建者 create_date 创建日期 … … …

然后就是基于Mybatis自动生成Dao层相关代码;

3.前端实现

3.1.主页图表显示

在主页中我们对图表有的功能进行了简化,比如导出功能,行参数等;

通过分析看板界面的实现,我们发现几个主要的函数:

var loadCharts = function(){}//获取图表配置并解析,调用loadWidget方法var loadWidget = function (reload)//遍历图表,调用buildRender方法绘制图表var buildRender = function (w, reload)//通过chartService服务实现各类图表绘制$scope.modalChart = function (widget)//图表弹窗显示

需要注意的是,图表配置的JSON格式,我们并未对原有格式进行调整

每一个widget对象还有两个比较重要的状态控制

widget.loading = true;   widget.show = true;

分别用于加载框和隐藏控制

其次,是前端布局模板,同样可以借鉴看板功能(webapp\org\cboard\view\dashboard\layout\grid.html)

示例:
主页模板文件(webapp\starter\home-page.html)

<!-- Content Wrapper. Contains page content --><section class="content-header"></section><div id="inner-container" class="content">    <div class="row" ng-repeat="row in charts.rows track by $index" ng-style="{height:row.height+'px'}">        <div ng-repeat="widget in row.widgets track by $index">            <div ng-if="widget.show">                <dashboard-widget ng-show="widget.loading == false"></dashboard-widget>            </div>            <div ng-if="widget.loading || !widget.show" class="col-md-{{widget.width}}" style="height: 50px;">                <div class="box box-solid">                    <div class="box-header">                        <i class="fa fa-bar-chart-o"></i>                        <h3 class="box-title">{{widget.name}}</h3>                        <div class="box-tools pull-right">                            <button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>                            </button>                        </div>                    </div>                    <div class="box-body" ng-style="{height:row.height?row.height:300+'px'}">                        <i class="fa fa-spinner fa-spin"></i> {{"COMMON.LOADING" | translate}}                    </div>                </div>            </div>        </div>    </div></div>

将设计好的模板文件引入到ui-view(webapp\starter.html)中:

<!-- Content Wrapper. Contains page content -->    <div class="content-wrapper" id="content-wrapper-id">        <div id="loading-bar-container"></div>        <ui-view>        <!-- Home Page -->            <div ng-include="'starter/home-page.html'"></div>        </ui-view>    </div>

测试的话,可以复制dashboard_board表中的配置,下一节完成主页配置功能;

3.2.首页图表配置

好吧,也是copy代码。

配置界面模板:
webapp\org\cboard\view\config\board.html
webapp\org\cboard\view\config\board\grid\grid.html

配置界面控制器逻辑:
webapp\org\cboard\controller\config\boardCtrl.js

因为只是完成主页配置,保存设置之后的JSON配置,简化之后如下:

配置界面模板:

文件:webapp\org\cboard\view\config\homePage.html

<!-- Content Wrapper. Contains page content --><div id="inner-container" class="content">    <div class="row">        <div class="col-md-9">        <div class="box">            <div class="box-header with-border">                <h3 class="box-title">{{'HOME_PAGE.CONFIG.TITLE'|translate}}</h3>            </div>            <div class="box-body">                <div class="row">                    <div class="col-md-12">                        <div ng-include="'org/cboard/view/config/homePage/grid.html'"></div>                    </div>                </div>                <!-- /.box-body -->                <div class="box-footer">                    <div class="row">                        <div class="col-md-12">                            <div class="form-group">                                <button type="submit" class="btn btn-danger pull-right" ng-click="cancel()">{{'COMMON.CANCEL'|translate}}</button>                                <button type="submit" class="btn btn-success pull-right" ng-click="saveOption()"                                        style="margin-right: 5px">{{'COMMON.SAVE'|translate}}                                </button>                            </div>                        </div>                    </div>                </div>                <!-- /.box-footer-->            </div>        </div>    </div>    </div></div>

文件: webapp\org\cboard\view\config\homePage\grid.html

<div class="row">    <div class="form-group" style="margin: 5px 15px;">        <button type="submit" class="btn btn-success" ng-click="addRow()">            {{'CONFIG.DASHBOARD.ADD_ROW'|translate}}        </button>    </div></div><div dnd-list="curBoard.layout.rows" dnd-allowed-types="['r']">    <div class="dndPlaceholder row margin">        <div class="box sort-highlight" style="height: 130px"></div>    </div>    <div class="row margin" ng-repeat="row in curBoard.layout.rows">        <div ng-include="'org/cboard/view/config/board/grid/widget.html'"></div>    </div></div><div class="row" ng-if="curBoard.layout.rows.length >= 3">    <div class="form-group" style="margin: 5px 15px;">        <button type="submit" class="btn btn-success" ng-click="addRow()">            {{'CONFIG.DASHBOARD.ADD_ROW'|translate}}        </button>    </div></div>

文件: webapp\org\cboard\controller\config\homePageCtrl.js

cBoard.controller('homePageCtrl', function ($rootScope, $scope, $http, ModalUtils, $filter, $uibModal, $timeout, dataService, $state, $window) {    var translate = $filter('translate');    $scope.curBoard = {layout: {rows: []}};    var getCurBoard = function(){        $http.get("commons/getHomePageWidget.do").success(function(response){            if(response && response.optValue){                $scope.curBoard = angular.fromJson(response.optValue);            }        });    };    var getDatasetList = function () {        $http.get("dashboard/getDatasetList.do")            .then(function (response) {                $scope.datasetList = response.data;                return $http.get("dashboard/getWidgetList.do");            })            .then(function (response) {                    $scope.widgetList = response.data;                    $scope.widgetList = $scope.widgetList.map(function (w) {                        if (w.data.datasetId != null) {                            var dataset = _.find($scope.datasetList, function (ds) {                                return ds.id == w.data.datasetId;                            });                            w.dataset = dataset == null ? 'Lost DataSet' : dataset.name;                        } else {                            w.dataset = "Query";                        }                        return w;                    });                }            );    };    $scope.widgetGroup = function (item) {        return item.categoryName;    };    $scope.addWidget = function (row) {        var w = {};        w.name = '图表名称';        w.width = 12;        w.widgetId = $scope.widgetList[0].id;        row.widgets.push(w);    };    $scope.addRow = function () {        $scope.curBoard.layout.rows.push({type: 'widget', widgets: []});    };    $scope.addNode = function (node) {        $scope.curBoard.layout.rows.push({node: node, type: 'widget', widgets: []});    };    $scope.saveOption = function(){        $http.post("commons/saveHomePageWidget.do",{json:angular.toJson($scope.curBoard)}).success(function(response){            if(response.status == 1){                window.location.replace('starter.html');            }            else{                ModalUtils.alert(response.msg,"modal-warning", "sm");            }        });    };    $scope.cancel = function(){        window.location.replace('starter.html');    };    getCurBoard();    getDatasetList();});

最后,配置路由规则,添加跳转功能按钮,则大功告成;

示例:

设置菜单

配置界面

首页图表显示

4.总结

其实,前面大部分的代码都是在理解原有实现的基础上,进行的copy和简化;


TIP:

其实,我在做的过程中遇到遇到一个棘手的问题:

现在前端功能界面的切换都是基于angularJS路由实现的,包括用户配置的看板,但是当这个数据量比较大时,会比较费时(虽然在有缓存的情况下,页面渲染是一个问题),于是,我们想加入TAB标签页来解决,但是,发现基于angularJS路由机制的TAB标签页供能并不容易实现,要不就放弃路由机制,希望大牛们不吝赐教!!!

原创粉丝点击