Click here to Skip to main content
Click here to Skip to main content

Real Time SPC Web Application for iPad/Android Tablet using JQUERY/AJAX/AJAX Enabled WCF Service

By , 15 Jul 2012
 

Real Time SPC

Introduction

Couple of months back I wrote an article titled TaskTracker OffLine Web Application for Mobile using HTML5,JQUERY-UI and KNOCKOUT.js In that the focus of the article  was offline programming using HTML5 and explore the features of different powerful frameworks such as JQUERY,JQUERY-UI and KNOCKOUT. This article is an extension of it and covers some additional features such as HTML5 Canvas,Integration with back-end database using JQUERY AJAX and AJAX Enabled WCF Service. Key features explored in this article are given below.

  • Application Cache, Webstorage and Canvas features of HTML5 are used in this application
  • Jquery AJAX makes your asynchronous programming easier and enables you to interact with Web Services from the Javascript.
  • AJAX Enabled WCF Service and Entity Framework

Background 

SPC is a very important part of quality control in any manufacturing process.Currently the data capture process for doing SPC analysis  is mostly manual.This is mainly due to harsh environment in the shop floor and it is difficult to use conventional computer or laptop there.So with the advancement in smart phone technology it is now possible to write an application for this purpose to automate the data capture process and do the quick SPC Analysis in real time.Also with key features such as offline programming of HTML5 you can now save data locally in the absence of internet and then save it to back end database once connected to internet for future analysis.

Hence Real Time SPC (Statistical Process Control) Application for iPad/Android Tablet will be very useful to Engineering,Manufacturing or Process Industries.This will enable quality inspectors and operators of this industry to capture data in real time from the shop floor and do quick SPC analysis and check control  charts in Real Time to ensure that the manufacturing process is in control. You can check the working version of the application here.

Design Overview

The application is built using popular MVVM design pattern. MVVM is a design pattern very similar to old MVC design pattern and addresses the separation of concerns. Like MVC it has model,view,but controller role is done by ViewModel. View Model is responsible for handling user interactions and also interacts with model and updates the view. It can have additional attributes apart from Model which can be view specific. Also in a complex web application comprising of multiple views,each view can have corresponding view model. In our application there is only one view and one view model. The  key files of the application are newmain.html,SPCNewController.js,StorageController.js,controlCharts.js, SPCAjaxHelper.js and SPCService.svc  The class diagram of the application is shown in Figure 1.

Class Diagram of Real Time SPC

From the figure 1, RealTimeSPCUI class is a conceptual class and represents the UI for the application and is implemented as plain html. SPCViewModel is a key class responsible for handling all the user interactions and updating the view and interacts with model. Measurement is an entity class which acts as a model for this application.StorageController is a wrapper class and is responsible for saving and retrieving data from WebStorage.

XBarRangeChart is class responsible for control charts. SPCAjaxHelper is a Helper class for handling JQuery  AJAX interaction with WCF Service class SPCService

Since Java script is not like conventional object oriented programming languages such as C++, C# or Java and it does not have Class construct. So all the classes are implemented differently. I will first explain the  business layer implementation,then the data layer and finally UI

Business Layer

Business layer consists of one key entity Measurement and represents Model. Another important class is a SPCViewModel Below section shows the implementation details of Measurment class.

// Declare Measurment class
 function Measurement() {
    var self = this;
    self.parameter= ko.observable("");
    self.id = 1,
        self.TimeStamp = ko.observable($.datepicker.formatDate('yy-mm-dd',new Date())),
        self.PartNo = ko.observable(""),
        self.Machine= ko.observable(""),
        self.Operator=ko.observable(""),
        self.Parameter= ko.observable("Inner Diameter");
        self.P1=ko.observable(0),
        self.P2=ko.observable(0),
        self.P3=ko.observable(0),
        self.P4=ko.observable(0),
        self.P5=ko.observable(0),
        self.PAve = ko.dependentObservable(function () {
            var aveValue=(eval(self.P1())+eval(self.P2())+eval(self.P3())+eval(self.P4())+eval(self.P5()))/5;


             return Math.round(aveValue*1000)/1000;
        });
        self.PRange = ko.dependentObservable(function () {
            var m= Math.max(self.P1(),self.P2(),self.P3(),self.P4(),self.P5());
            var n= Math.min(self.P1(),self.P2(),self.P3(),self.P4(),self.P5());
               return Math.round((m-n)*1000)/1000;
        });
}

// example of creating new instance of these classes
var curMeasurement = new Measurement();
// Important point to remember knockout observables are methods.
// e.g. you need to read machine name,you invoke it as a method.
var machine= curMeasurement.machine(); // see we access the property as function.
// set the property.
curMeasurement.machine('M1'); // setting the observable property.

If you see at the above code you might have noticed that  the class contains only properties as it is an entity class and do not expose any methods. But also you might have noticed that these properties are initialised with knockout constructs.These properties are declared as observables.This will enable these properties bind to UI and will provide two way binding. So any changes done to these properties in UI will automatically update the properties. Or if you change their values programmatically,then it will reflect those changes  in UI. One thing to remember is that the knockout observables are functions and you can't access or initialise them as normal properties. Also notice the declaration for dependent observable properties. These properties are derived from other properties. See the above code showing example of setting and accessing knockout observable property.

Let us now see the implementation details of SPCViewModel.This is the key class responsible for handling user interaction and  will update the UI and model.


  // Only some sections of the code are shown here.
function SPCViewModel() {
    var self = this;
    self.onLine = ko.observable(false);
    self.filterDate = ko.observable("");
    self.filterPoints = ko.dependentObservable(function () {
        var partno = self.lastPart();
        var parameter = self.lastParameter();
        return ko.utils.arrayFilter(self.dataPoints(), function (item) {
            var cp, cparam;
            if ($.isFunction(item.PartNo))
                cp = item.PartNo();
            else
                return false;
            if ($.isFunction(item.Parameter))
                cparam = item.Parameter();
            else
                return false;
            if ((partno === cp) && (parameter === cparam))
                return true;
            else
                return false;
        });
    });
   // Remove Measurment.
  self.removeMeasurement = function (iDP) {
        self.dataPoints.remove(iDP);
        var mDP = ko.toJSON(self.dataPoints);
        self.normalDP = JSON.parse(mDP);
        tsk_ns.storage.saveItem("measurments", mDP);
        self.updateDPArray();
    };
    // Edit measurement
    self.editMeasurement = function (iDP) {
        self.selected(iDP);
        self.currentDP(iDP);
        self.taskMenu("Edit Data");
        $("#accordion").accordion("activate", 0);
        self.editFlag = true;
    };
    
}

SPCViewModel is a core class of this application and is responsible for handling user interactions and interacts with model and updates the view. The above code is not complete source code,but just highlight key methods. The view model has two observable array defined for storing all measurment points. Also note the use of dependent observable to filter the measurment points by filtering criteria.The key methods are responsible for following tasks.

       
  • Retrieve and Save Measurment data to local webstorage.
  •    
  • Retrieve and Save Measurment data to back-end database
  •    
  • Analyse data and display data in tabular fashion
  •    
  • Update Control Charts
  •     
Also note that the status of internet connection is updated in real time and the buttons used to save the data to the database and retrieve history are enabled only when user is connected to internet. Above section shows only some part of the code and I request you to refer the source code for the full implementation details.

Data Layer

Data layer is implemented in two stages. Storing the data to local Webstorage and storing it to the back-end database. Local storage is handled by StorageManager class. Details of it's implementation are given below

// Store Manager Singleton class
// Implemented using revealing module design pattern
var tsk_ns = tsk_ns || {};
tsk_ns.storage = function () {
    // create instance of local storage
    var local = window.localStorage,
    // Save to local storage
        saveItem = function (key, item) {
            local.setItem(key, item);
        },
        getItem = function (key) {
            return local.getItem(key);
        },
        hasLocalStorage = function () {
            return ('localStorage' in window && window['localStorage'] != null);
        };

    // public members
    return {
        saveItem: saveItem,
        getItem: getItem,
        hasLocalStorage: hasLocalStorage

    };


} ();

The above class is just a wrapper to window.localStorage  and provides wrapper method to save and get the data from the local storage. The class has hasLocalStorage method which checks whether browser supports the localStorage.

Saving and retrieval of the data to backend database is implemented using Jquery AJAX and AJAX enabled WCF service. This is implemented using two classes. SPJAjaxHelper.js is a helper class responsible for making all ajax calls to invoke WCF service. SPCService is a class implemented as WCF service. Implementation of these classes are given below.

// Helper to call Jquery AJAX to interact with
// SPCService.svc (AJAX enabled WCF Service.
//
// Below is wrapper to invoke Jquery ajax.
/// <reference path="json2.js">
function CheckIfOnLine(successMethod, failMethod) {
    var sUrl = "SPCService.svc/CheckIfConnected";
   
    $.ajax({
        type: "POST",
        contentType: "application/json; charset=utf-8",
        url: sUrl,
        dataType: "json",
        processdata: false,
        success: successMethod,
        error: failMethod
    });
}

function GetMeasurementData(msFilter,successFunction) {
    var sUrl = "SPCService.svc/GetMeasurmentDataArray";
    var ms = { measFilter:msFilter };
    var sparam = JSON.stringify(ms);
  //  alert(sparam);
    InvokeWebService(sUrl, sparam, successFunction);
}
  function UpdateMeasurment(msArray,successMethod)
  {
        var sUrl="SPCService.svc/UpdateMeasurmentArray";
        var ps = { parray: msArray };
        var sparam = JSON.stringify(ps);
    //   alert(sparam);
        InvokeWebService(sUrl,sparam,successMethod);
  };


  function InvokeWebService(sUrl,sparam,successMethod) {
      $.ajax({
          type: "POST",
          contentType: "application/json; charset=utf-8",
          url: sUrl,
          data: sparam,
          dataType: "json",
          processdata: false,
          success:successMethod,
          error: function (result) {
              alert('Service call failed: ' + result.status + ' ' + result.textStatus);
          }
      });
        
      
      };
</reference>

SPCAJAXHelper.js file has three key methods. Checking online status,retrieving measurment data based on filter criteria and saving the data to the database. All these method call InvokeWebService method which in turn calls ajax method of JQuery. Each methods pass appropriate parameters,success callback methods. In case of any error the error message is displayed to the user.

Let us now see the implementation of SPCService. SPCService class exposes following methods

  • CheckIfOnline 
  • GetMeasurmentDataArray
  • UpdateMeasurmentArray

Below code shows the details of each of this methods. Please note the attribute defined for the WCF Service class.See the ServiceContract attribute for the class. Each exposed method is declared with an attribute OperationContract and Any parameters passed to the methods such as entity classes are having attribute of DataContract and each of the properties of entity class are decorated with the attribute DataMember. Also the AspNetCompatibilityRequirements attribute to the class is also required. Also message exchange between WCF service and AJAX calls made from Javascript are using JSON format. Please refer the WebInvoke attribute in below code where message format is defined.

Important point to remember is parameter names passed to invoke the methods should match exact signature of the WCF method. I have created the similar entity classes in Javascript so that same type of parameters can be passed. In our case there are two entities MeasurmentSummary and MeasurmentFilter I won't explain details of each method as the code is self explanatory.

[ServiceContract(Namespace = "SPCAnalysisWeb")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class SPCService
    {
        [OperationContract]
        [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]
        public string CheckIfConnected()
        {
            return "SUCCESS";
        
        }
         // Add more operations here and mark them with [OperationContract]
        [OperationContract]
        [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]
        public MeasurementSummary [] GetMeasurmentDataArray(MeasuremntFilter measFilter)
        {
           // please refer source code for the details.
           return null;
        }

        // Add more operations here and mark them with [OperationContract]
        [OperationContract]
        [WebInvoke(Method = "POST", BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)]
        public string UpdateMeasurmentArray(MeasurementSummary[] parray)
        {
           // Method prototype is shown here.
        }
    }




    [DataContract(Namespace = "SPCAnalysisWeb", Name = "MeasurementFilter")]
    public class MeasuremntFilter
    {
        [DataMember(IsRequired = true, Name = "PartNo")]
        public string PartNo { get; set; }
        [DataMember(IsRequired = true, Name = "Parameter")]
        public string Parameter { get; set; }
      
    }

    [DataContract(Namespace = "SPCAnalysisWeb", Name = "MeasurementSummary")]
    public class MeasurementSummary
    {
        [DataMember(IsRequired = true, Name = "PartNo")]
        public string PartNo { get; set; }
        [DataMember(IsRequired = true, Name = "Machine")]
        public string Machine { get; set; }
        [DataMember(IsRequired = true, Name = "Operator")]
        [DataMember(IsRequired = true, Name = "PAve")]
        public double PAve { get; set; }
        [DataMember(IsRequired = true, Name = "PRange")]
        public double PRange { get; set; }
        

    }
</parameter></measurementsummary></measurementsummary>

Web.config has configuration details for the WCF Service. If you are using Visual studio 2010 IDE then it has a template for AJAX Enabled  WCF Service and it creates all the boiler plate code and configuration for your. Details of Web.Config are given below.

 <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name="ServiceBehavior">
          <serviceMetadata httpGetEnabled="true" />
          <serviceDebug includeExceptionDetailInFaults="true" />
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="SPCAnalysisWeb.SPCServiceAspNetAjaxBehavior">
          <enableWebScript />
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"
      multipleSiteBindingsEnabled="true" />
    <services>
      <service behaviorConfiguration="ServiceBehavior" name="SPCAnalysisWeb.SPCService">
        <endpoint address="" behaviorConfiguration="SPCAnalysisWeb.SPCServiceAspNetAjaxBehavior"
          binding="webHttpBinding" contract="SPCAnalysisWeb.SPCService" />
      </service>
    </services>
  </system.serviceModel>

All the configuration of WCF service is under system.servicemodel section. Key points to note are binding attribute,whose value is set to webHttpBinding. Those who wants to know more about WCF service working and configuration of WCF service please refer to msdn documentation.

I have used Entity framework to interact with the database. But you can also use LINQ-TO SQL.

UI Layer

UI Layer is implemented as plain html file. I have used Accordion widget of JQUERY-UI as well as Tabbed Layout.

Once all the document is loaded it excutes below initialisation code.The code defines validation rules, JQuery-UI initialisation code and binding of view model to UI.

// Document ready
$(function () {
   $('#tabs').tabs();
   
    // Define validation options for taskform
    $('#measForm').validate({
        rules: {
            partno: "required",
            machine: "required",
            operator:"required",

            dp1: {
                required:true,
                number: true
            },
            dp2: {
                required:true,
                number: true
            },
            dp3: {
                required:true,
                number: true,
            },
            dp4: {
                required:true,
                number: true
            },
            dp5: {
                required:true,
                number: true
            }
        }
      });

    $("#hisForm").validate({
        rules: {
            hispart: {
                required:true
            },
            filterdatefrom: {
                required:true,
                date:true
            },
            filterdateto: {
            required:true,
            date:true
                }
        }
    });
      
   
    $("#accordion").accordion({active:1});
   // $("#filterdatefrom,#fromdateto").datepicker();
    $("#taskNew,#taskSave,#taskUpdate,#btnRefresh,#btnRetrieve,#btnTest").button();
    $("#taskNew").button("option", "disabled", false);
    $("#taskUpdate").button("option", "disabled", true);

    var viewModel = new SPCViewModel();
    viewModel.init();
    ko.applyBindings(viewModel);
    //$( "#dialog:ui-dialog" ).dialog( "destroy" );
    $("#dlgSave").dialog({
        autoOpen: false,
        modal: true,
        buttons: {
            Ok: function () {

                $(this).dialog("close");
                viewModel.saveToDatabase();
            }
        }
    });
    var id= setInterval(viewModel.updateOnLineStatus,10000);
});

The above code does initialisation of the gui widgets and field validation for Measurement form. Also Javascript timer is setup to update online status. Finally view model is initialised and binding is applied to the view.

One of the key part of the UI is Control Charts. I have implemented it using HTML Canvas. The key class implementing the charting functionality is  XBarRangeChart.Please refer to the source code for details of the implementation.

I have used different types of bindings such as for-each,  with, form  binding features of knockoutjs. Please refer to the source code for complete details.

Configuring for Offline Working

With HTML5 we can now configure the pages,assets and resources of the application which should be served offline. This is possible by defining the Application Manifest file, which is plain text file. Also in html tag you need to define the manifest attribute to specify name of the manifest file. <html manifest="manfiest.appcache"> I have added manifest file with the extension of .appcache. But you can use any extension. But we need to configure the webserver to include this new extension type as well as specify its MIME type as text/cache-manifest.Please refer code below to refer the content of the manifest file.  

 

Please remember that the fist line in the manifest file shoud be CACHE MANIFEST. Don't put any comments before this line.  Structure of manifest file is simple. It has three sections CACHE,NETWORK and FALLBACK.  All the pages and resources used during off-line need to be specified under CACHE: section. Pages/resources   required only during online are under NETWORK section. In FALLBACK section you can specify alternate pages  in case of fallback. That's it!  

Browser supporting the application cache will initially save all the offline resources on client side and then it will always serve these resources from application cache irrespective of whether you are online or offline. So if any changes done  to these pages will reflect only when manifest file is modified. This is important point to remember. Modify the manifest  file and update the version to indicate to the browser that there is some change so that it will bring latest changes from  the server and save it again on client side.  
 
CACHE MANIFEST
## version 2.3
CACHE:
themes/ui-darkness/jquery-ui-1.8.21.custom.css
themes/ui-darkness/images/ui-bg_flat_30_cccccc_40x100.png
themes/ui-darkness/images/ui-bg_flat_50_5c5c5c_40x100.png
themes/ui-darkness/images/ui-bg_glass_20_555555_1x400.png
themes/ui-darkness/images/ui-bg_glass_40_0078a3_1x400.png
themes/ui-darkness/images/ui-bg_glass_40_ffc73d_1x400.png
themes/ui-darkness/images/ui-bg_gloss-wave_25_333333_500x100.png
themes/ui-darkness/images/ui-bg_highlight-soft_80_eeeeee_1x100.png
themes/ui-darkness/images/ui-bg_inset-soft_25_000000_1x100.png
themes/ui-darkness/images/ui-bg_inset-soft_30_f58400_1x100.png
themes/ui-darkness/images/ui-icons_222222_256x240.png
themes/ui-darkness/images/ui-icons_4b8e0b_256x240.png
themes/ui-darkness/images/ui-icons_a83300_256x240.png
themes/ui-darkness/images/ui-icons_cccccc_256x240.png
themes/ui-darkness/images/ui-icons_ffffff_256x240.png
Styles/spcmain.css
Scripts/jquery-1.7.1.min.js
Scripts/json2.js
Scripts/jquery-ui-1.8.17.custom.min.js
Scripts/jquery-ui-timepicker-addon.js
Scripts/knockout-latest.js
Scripts/ko-protected-observable.js
Scripts/StorageManager.js
Scripts/SPCNewController.js
Scripts/jquery.validate.min.js
Scripts/additional-methods.js
Scripts/ControlCharts.js
Scripts/jquery.dateFormat-1.0.js
Scripts/SPCAjaxHelper.js
Images/app-note-icon.png
Images/Actions-document-edit-icon.png
Images/edit-trash-icon.png
newmain.htm
NETWORK:
SPCService.svc
SPCService.svc.cs


 

Styling for Mobile

 

I don't have to do major change to configure this application for mobile. Only thing you need to specify is viewport  setting in the head section of your html file. I had to define extra style for textarea tag. As its width  was overflowing outside its parent container. Please refer the code below for details.  

 
 // <meta name="viewport" content="width=device-width, initial-scale=1">
 // styling for textarea
 .fixwidth
{
    width:80%;    
}
 

Points of Interest

HTML Canvas is not yet supported by all the browsers. So this code may not work on all the browsers. Luckily all the smartphone and tablets browser support it and I have tested it on iPad,Android and Blackberry tablet.When you download the source code you need to provide the database connection string such as server name,userID and password.

Android Phone/iPhone/iPad Users

Working version of the application is available here. They can bookmark this page. It will work both in off-line mode and online mode.

History

I was thinking of extending my TaskTracker application to provide the support for saving and retrieving the data to the back-end database. But I thought it will be better to do completely new application and also I wanted to explore the feature of HTML Canvas and hence I developed this application which is also useful to manufacturing and process Industry.

 

Conclusion

 

Due to new features in HTML5 it is now easy to develop off-line web applications.The application explores key features of the HTML5,Jquery,Jquery-UI,Jquery-Validation  and KnockoutJs. You can also see how the power of JQUERY AJAX is used to retrieve and save the data to back-end database using AJAX Enabled WCF Service. Also we can use open source framework such as PhoneGap to convert it to native application for different mobile platforms.  Please let me know your comments and suggestions. You can e-mail me for any queries or clarification about  the implementation. Thank you.  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

gokuldas
Software Developer (Senior) Infor
United Kingdom United Kingdom
Member
I am Solution Architect with 20+ years of IT experience in the field of real time,embedded,client/server and web based applications and Business Intelligence . I am currently working with Infor UK Ltd.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionWeb servicesmembersairanga6 Sep '12 - 0:18 
QuestionGood Job!memberSuper Tango30 Jul '12 - 5:13 
QuestionGreat Article!memberMember 139532529 Jul '12 - 1:46 
AnswerRe: Great Article!membergokuldas29 Jul '12 - 11:25 
QuestionCross Site ReferencememberWagid Sheikh16 Jul '12 - 23:38 
AnswerRe: Cross Site Referencemembergokuldas17 Jul '12 - 4:52 
GeneralEr... a little unclear on...memberdave.dolan16 Jul '12 - 6:37 
GeneralRe: Er... a little unclear on...membergokuldas16 Jul '12 - 10:36 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web01 | 2.6.130516.1 | Last Updated 16 Jul 2012
Article Copyright 2012 by gokuldas
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid