Skip to content

Cuisine

Babis Georgiadis edited this page Apr 30, 2017 · 49 revisions

Cuisine is mainly concerned with the construction of the Ui.

Components

AngularJs

The UI was build with AngularJs wich is a structural framework for dynamic web apps. To add AngularJs to your project you just have to download the library from the official website and add it to your javascript folder.

JQuery

JQuery is a fast, small, and feature-rich JavaScript library. We use the CDN library from JQuery to build the Voting-diagrams.

Bootstrap

Bootstrap makes front-end web development faster and easier. We use Bootstrap for the styling of the UI. To add Bootstrap to your project you just have to download the library and add it to your css folder.

CanvasJS

To show the incoming events we use CanvasJS. With CanvasJs and the connection via websockets to luculus and services, we make responsive charts which run across devices.

Structure

struct

Example for loading behaviour

agView

Design

At the same time, we have kept to the colors and shapes of IBM Bluemix. In addition to our own css, we have also used Bootstrap and other libraries to generate a fast development. Since Bluemix used material design we have rebuild styling parts but we also use stylings from other developers to guarantee a unique user experience. Gadgets have also been implemented, e.g. Drag and drop or connection pulping elements with svg. In order To show the user that his activities trigger something and keep in active in the happening.

first concept

ui_ ui

Code-architecture

index.html

All librarys, controller, models and router are bound in the index.html. By using the AngularJs widget "ui-view" the individual html pages are loaded dynamically to the index.html.

  <div ui-view>
        <!--Content here -->
  </div>

app.module

To get structure to our project external libraries are separated from our own doveloped module-libraries.


(function () {
  angular.module('riddle',[

    'riddle.core',
    'riddle.structure',
    'riddle.content',
    'riddle.detail'
  ]);
})();

core.module

In the core module third party libraries are added. We use different kind of vendor libs to provide more funktionality in the Ui. You can just inject angular libs to the root scope by reference the third party libraries in the core model.

(function () {
  angular.module('riddle.core',[
    'ui.router',
    'ui.router.stateHelper',
    'gm.dragDrop',
    'ngSanitize',
    'ngResource',
    'third-party'

  ]);
})();

core.router

The core router is responsible for the routing between the individual html pages and the other routers. In case of non-existent destination addresses, /struct is always called.

(function(){
    angular
        .module('riddle.core')
        .config(function($urlRouterProvider, $stateProvider){

          $urlRouterProvider
          .otherwise('/struct');

        });
})();

public/components

We use the AngularJs pattern for mvc to divide our application into three interconnected parts in order to separate internal representations of information from the ways that information is presented to and accepted from the user.

  • Each Cuisine/public/components/ has its own logic for its modules, controllers, routers and hmtls.
  • Components can also include their own widget which in turn bring their own mvc with them. We've used widget to separate bootstrap modals and their logic.

Cuisine / public / components / detail / widgetEditFilter / widgetEditFilter.ctrl.js

Patterns MVC/MVW

In the context of client-side JavaScript frameworks, you will find these patterns mentioned frequently.

The MVC pattern separates the application concerns into three distinct parts—Model,View, and Controller. Simply put, the Model represents the application data, a View represents the application’s user interface, and a Controller acts like a middleman between the other two parts and also manages the overall application flow.

In the context of JavaScript applications, a Model is usually a JavaScript object or a collection of objects. A View consists of HTML markup from the document object model (DOM) tree. A Controller acts as a layer that connects the Model and the View. The Controller might do tasks such as handling events, validating data, performing some business-specific processing, and changing the model data.

The “Whatever” used by the pattern can be a View Model or a Controller or whatever suits the application requirements. JavaScript frameworks such as AngularJS are based on the MVW pattern.

'Source' (Beginning SOLID Principles and Design Patterns for ASP.NET Developers).

good to know

ui_

detail/service.cDB.js

In order to offer faster data processing and static variables, a service interface was implemented. That offers a browser internal database.

Cuisine/public/components/detail/service.cDB.js

The interface provides three public methods to separate view logic and database logic from each other.

   return {
              getData: _getData,
              getItem: _getItem,
              addData: _addData
          }

detail/service.api.js

Cuisine/public/components/detail/service.api.js

To get a loose coupling for the http get and post calls, our interface offers two public methods. The api call is triggered by moving the elements in the chain of event handlers and by configuring the individual elements. For example if you add or change the configuration of the filter, correlator and so on

  • The configType is set variable and contains the names of the elements present in the chain.
  • The methods getConfig and postConfig can be used independently for which handler the data is required.

See also:

Link: http://riddle-api.mybluemix.net/

  return {
               api: getConfig(),
               apiPost: postConfig()
         }

function getConfig() {
              return $resource(
                            'http://riddle-api.mybluemix.net/api/v1/config/:configType',{
                              configType:'@configType'
                            },{
                              'getConfig':    {method: 'GET', isArray: true, cache: false}
                            }
              );
            }

            function postConfig() {
              return $resource(
                            'http://riddle-api.mybluemix.net/api/v1/config/:configType',{
                              configType:'@configType'
                            },{
                              'postConfig':    {
                                method: 'POST', isArray: true, cache:false,
                                  headers: {
                                      'content-type':'application/x-www-form-urlencoded'
                                    }
                              }
                            }
              );
}

/components/content/ctrl.js

activate and deactivate of chain

In this controller the http requests for activating and deactivating the chain are dealt with.

  //API calls
  
  var urlLuculus = 'http://lucullus.mybluemix.net/api/v1/start';
  var urlDeactivate = 'http://lucullus.mybluemix.net/api/v1/stop';

Furthermore, the handler chain is set when the user interface is loaded.

Cuisine/public/components/content/ctrl.js

var urlUser = 'http://riddle-api.mybluemix.net/api/v1/config/user';

This output shows how the event handlers are set in the toolbar and in the handler chain.

{"chain":[{"name":"filter","order":1},{"name":"correlator","order":3}],"toolbar":[{"name":"unique filter","order":4},{"name":"dedub","order":2}]}

CanvasJS

We use canvasJsTo display all incoming and outgoing events and to actively participate the user.

        cont.dps = [
          { label: "GateWay",  y: 1  },
          { label: "OpenWhisk", y: 1  },
        ];

        //canvasJS
        var chart = new CanvasJS.Chart("chartContainer", {
          theme: 'theme2',
          animationEnabled: false,   // change to true
          data: [
          {
            // Change type to "bar", "area", "spline", "pie",etc.
            type: "column",
            dataPoints: cont.dps
          }
          ]
        });
      chart.render();

WebSockets

The WebSocket specification specifies an API that creates socket connections between a Web browser and a server. In short, there is a persistent connection between the client and the server and both parties can start sending data at any time. We have used websockets to show all the events that are coming from the iot gateway and which are triggered in openwhisk.

var ws = 'ws://lucullus.mybluemix.net/count';
       ws = new WebSocket(ws);

       ws.onopen = function (e) {
         console.log("onopen:", arguments);
       };

       ws.onclose = function (e) {
         console.log("onclose:", arguments);
       };

       ws.onmessage = function (e) {

         var data = JSON.parse(e.data);
      
           $rootScope.$apply(function() {
             cont.gateWay = data['count_in'];
             cont.opw = data['count_out'];
             cont.dps[0] = { label: "GateWay",  y: cont.gateWay  };
             cont.dps[1] = { label: "OpenWhisk", y: cont.opw  };
            //update Chart
            chart.render();
          });
       };

       ws.onerror = function (e) {
         console.log(e);
         console.log("onerror:", arguments);
       };

See also:

Link: http://riddle-api.mybluemix.net/

User Web Interface

Check the UI:

Link: http://riddle.mybluemix.net/#/struct