Wednesday, October 29, 2014

Employee Time Log : Dashboard View using Morris.js

Hi Guys,

I added new page to the Employee Time Log by adding a new dashboard view to it. Hope you like it.

Dashboard View


















Added a New Field as Type Of Work to Group Data

























Solution



1) Create a controller in js -> app.js as following 

appmodule.controller('DashboardController', ["$scope", "$http", "authService", "$filter", DashboardController])


function DashboardController($scope, $http, authService, $filter) {
    var scope = $scope;
    scope.TaskCount = 0;
    scope.AllCount = 0;
   scope.IsLineWeekly = true;
   scope.IsBarWeekly = true;
    scope.authentication = authService.authentication;

    scope.DrawLineChart = function (isWeekly) {

        var responsePromise = $http.get("/Services/EmployeeService.svc/GetWeeklyDashboard?userName=" + scope.authentication.userName
            + "&isWeekly=" + isWeekly);

        responsePromise.success(function (dataVal, status, headers, config) {
            
            $("#morris-area-chart").empty();
                Morris.Line({
                    element: 'morris-area-chart',
                    data: dataVal,
                    xkey: 'Label',
                    ykeys: ['Value'],
                    labels: ['Total (hrs)']
                });
                
                
            
        });
        responsePromise.error(function (data, status, headers, config) {
            alert("AJAX failed!" + status + " " + data);
        });

    }

    scope.DrawBarChart = function (isWeekly) {

        var responsePromise = $http.get("/Services/EmployeeService.svc/GetWeeklyDistribution?userName=" + scope.authentication.userName
            + "&isWeekly=" + isWeekly);

        responsePromise.success(function (dataVal, status, headers, config) {
            $("#morris-bar-chart").empty();
            Morris.Bar({
                element: 'morris-bar-chart',
                data: dataVal,
                xkey: 'Label',
                ykeys: ['Value'],
                labels: ['Hours'],
                barRatio: 0.4,
                xLabelAngle: 35,
                hideHover: 'auto',
                barColors: ['#4B088A'],
                resize: true
            });

           

        });
        responsePromise.error(function (data, status, headers, config) {
            alert("AJAX failed!" + status + " " + data);
        });

    }

    scope.DrawLineChart(true);
    scope.DrawBarChart(true);

    scope.CalculateOverall = function () {
        var responsePromise = $http.get("/Services/EmployeeService.svc/GetWeeklyDistribution?userName=" + scope.authentication.userName
            + "&isWeekly=false");

        responsePromise.success(function (dataVal, status, headers, config) {
            
            var total = 0;
            var isTask = false;
            for (var i = 0; i < dataVal.length; i++) {

                for (attr in dataVal[i]) {
                   

                    if (dataVal[i][attr] == "Task" || isTask) {
                       

                        if (isTask) {
                            scope.TaskCount = parseInt(dataVal[i][attr]);                            
                            total += scope.TaskCount;
                        }

                        if (dataVal[i][attr] == "Task") isTask = true;
                        else isTask = false;
                    }
                    else if(!isNaN(dataVal[i][attr]))
                        total += parseInt(dataVal[i][attr]);
                }
            }
            scope.AllCount = total;
        });
        responsePromise.error(function (data, status, headers, config) {
            alert("AJAX failed!" + status + " " + data);
        });
    }
    scope.CalculateOverall();
   

}

2) Create a new view in Views -> Partials -> Dashboard.html and add the following tags

 <div class="container" >
       <div class="panel panel-primary">
           <div class="panel-heading">
             <h1 >My Dashboard</h1>   
       
            </div>
            <div class="panel-body">
                <div class="col-lg-4">
                    
                    <div class="panel panel-default">
                         <div class="panel-heading">
                                <h3 class="panel-title"><i class="fa fa-bar-chart-o fa-fw"></i> Overall Summary</h3>
                            </div>
                            <div class="panel-body">
                                
                <div class="list-group">
  <a href="#" class="list-group-item">
    <h1 class="list-group-item-heading ">{{ TaskCount }} Hour(s)</h1>
    <h5 class="list-group-item-text">Spent on Tasks This Month</h5>
  </a>
  <a href="#" class="list-group-item">
    <h1 class="list-group-item-heading ">{{ AllCount }} Hour(s)</h1>
    <h5 class="list-group-item-text">Totally Worked This Month</h5>
  </a>
</div>
                                </div>
                        </div>
</div>

                
                <div class="col-lg-8">
                     <div class="panel panel-danger">
                            <div class="panel-heading">
                                <h3 class="panel-title" ng-switch on="IsBarWeekly"> 
                                    
      <span  ng-switch-when="true">Weekly Work Distribution </span>
      <span  ng-switch-when="false">Monthly Work Distribution </span>      
  
                                     
                                    <div class="pull-right" style="padding-bottom:10px">
                                   Show Last Seven Days 
                                    <input type="checkbox" ng-model="IsBarWeekly"   ng-change="DrawBarChart(IsBarWeekly)" />
                                    
                                </div>

                                </h3>
                                
                            </div>
                            <div class="panel-body">
                                
                                <div class="table-responsive">
                                <div id="morris-bar-chart"></div>
                                    </div>
                            </div>
                        </div>
                 </div>
                <div class="col-lg-12">
                        <div class="panel panel-warning">
                            <div class="panel-heading">
                                <h3 class="panel-title" ng-switch on="IsLineWeekly"> 
                                     <span  ng-switch-when="true">Weekly Analysis </span>
      <span  ng-switch-when="false">Monthly Analysis </span>  
                                    
                                    <div class="pull-right" style="padding-bottom:10px">
                                   Show Last Seven Days
                                    <input type="checkbox" ng-model="IsLineWeekly" ng-change="DrawLineChart(IsLineWeekly)"  />
                                </div>

                                </h3>
                                
                            </div>
                            <div class="panel-body">
                                
                                <div class="table-responsive">
                                <div id="morris-area-chart"></div>
                                    </div>
                            </div>
                        </div>
                </div>
                </div>
          
                    

</div>

3) Refer https://github.com/morrisjs/morris.js/ and add morris chart to your solution.

4) Add the following code to the Services -> IEmpolyeeService.cs

[OperationContract]
        [WebGet(UriTemplate = "/GetWeeklyDashboard?userName={userName}&isWeekly={isWeekly}",
            ResponseFormat = WebMessageFormat.Json)]
        List<DashboardData<string>> GetWeeklyDashboard(string userName, string isWeekly);

        [OperationContract]
        [WebGet(UriTemplate = "/GetWeeklyDistribution?userName={userName}&isWeekly={isWeekly}",
            ResponseFormat = WebMessageFormat.Json)]
        List<DashboardData<int>> GetWeeklyDistribution(string userName, string isWeekly);

5) Add the following code to the Services -> EmployeeService.svc.cs

Within the namespace

[Serializable]
    [DataContract]
    public class DashboardData<T>
    {
        [DataMember]
        public string Label { get; set; }
        [DataMember]
        public T Value { get; set; }

    } 

Within the Employee Service Class


    [OperationBehavior]
        public List<DashboardData<string>> GetWeeklyDashboard(string userName, string isWeekly)
        {
            List<DashboardData<string>> objReturn = new List<DashboardData<string>>();

            using (EmployeePortalDataContext context = new EmployeePortalDataContext())
            {
                int days = bool.Parse(isWeekly) ? -7 : -30;
                var values = from r in context.EP_TimeLogs
                             where r.CreatedBy.Trim().ToLower() == userName.Trim().ToLower() &&
                             r.StartTime.Date >= DateTime.Now.Date.AddDays(days) 
                             group r by new { Axis = r.StartTime.Date } into g                      
                             select new DashboardData<string> { Label = g.Key.Axis.ToString(),
                             Value = (g.Sum(s=>s.Duration)/60).ToString() };

                objReturn = values.ToList();
               
            }


            return objReturn;
        }

         [OperationBehavior]
         public List<DashboardData<int>> GetWeeklyDistribution(string userName, string isWeekly)
        {
            List<DashboardData<int>> objReturn = new List<DashboardData<int>>();

            using (EmployeePortalDataContext context = new EmployeePortalDataContext())
            {
                int days = bool.Parse(isWeekly) ? -7 : -30;
                var values = from r in context.EP_TimeLogs
                             where r.CreatedBy.Trim().ToLower() == userName.Trim().ToLower() &&
                             r.StartTime.Date >= DateTime.Now.Date.AddDays(days)
                             group r by new { Axis = r.TypeOfWork } into g
                             select new DashboardData<int>
                             { 
                                 Label = Enum.GetName(typeof(TypeOfWork),
                                 g.Key.Axis),
                             Value = Convert.ToInt32((g.Sum(s=>s.Duration)/60)) };

                objReturn = values.ToList();
               
            }


            return objReturn;
        }