Monday 16 November 2015

[tutorial] How to create directive for logic gate OR

In this arctical I am going to show you how to make a directive for logic gate OR.

Directive

In "Angular speech", the directive is piece of code, which solve something useful. It can even manipulate the DOM. It extends HTML language by either new tag or new attribute.

Logic gate OR

A logic gate implements Boolean logic function; the gate OR implements function OR (F = A OR B).

Directive for logic gate OR

The goal is to create useful directive, which implements OR function and has the graphical "interface", the gate itself, implemented as SVG.

Disclaimer: This is a proof-of-concept, not the best solution ever...

The name of the directive should be clear; so I decide to name it "logOr2" (the digit 2 means it uses two inputs). 
I use the isolated scope; this give us the ability to assign the inputs of the directive with the input button, input toggle, input variable, etc. independently to the directive itself.

.directive('logOr2', function(){
    return {
        scope: {
            x: '=',
            y: '=',
            a: '=',
            b: '=',
            out: '=',
            hl: '='
        },

What all this variables mean?
The x, y stands for the x- and y- coordinates inside SVG picture. We can use any position of our gate OR inside SVG.
The a, b are the inputs for logic gate OR.
The out should be used in case we need the result of the A OR B outside the directive (optinal).
The hl variable is for formatting the logic values. Somebody prefers "1, 0", somebody else "H, L" (high, low), somebody "T, F" (true, false).

Because we use this directive as a part of SVG picture, we need use:

        replace: true,
        templateNamespace: 'svg',

Now becomes an interesting part, the link function.

        link: function($scope){
            $scope.x = $scope.x || 0;
            $scope.y = $scope.y || 0;

            $scope.sign = "\u2265"+"1";
            $scope.setHL = function(){
                if ($scope.hl === '1, 0') {
                    $scope.H = 1;
                    $scope.L = 0;
                    return;
                };
                if ($scope.hl === 'H, L') {
                    $scope.H = 'H';
                    $scope.L = 'L';
                    return;
                };            
                if ($scope.hl === 'T, F') {
                    $scope.H = 'T';
                    $scope.L = 'F';
                    return;
                };
            
            }();

            $scope.strLog = function(value){
                if (value === undefined || value === null) return null;
                return value ? $scope.H : $scope.L;
            };
            
            $scope.Q = function(){
                if ($scope.a === undefined || $scope.a === null || $scope.b === undefined || $scope.b === null ) return null;
                var res = $scope.a || $scope.b;
                $scope.out = res;
                return res;
            };

        }

The $scope.x, $scope.y are equal to value defined from HTML code or are set to zero.
The $scope.sign is used as the "mark" or "type" of the logic gate.
The $scope.setHL() is the function for formatting logic values (one, zero) to "1", "0", or "H", "L", or "T", "F".
The $scope.strLog() is the function which return true/false as defined in $scope.setHL() function.
The $scope.Q() is the function with two results; it solves the Boolean OR function as a result of $scope.Q() function; and it assign its value to the output variable $scope.out (see the "scope section" above). The return value of $scope.Q() function is then used inside the SVG part of the directive.

The SVG part is easy to make: the rectangle with two inputs, two outputs, the sign (type of the logic gate) inside and the values (input, output). It should look like:


        template: '<g stroke="black" transform="translate({{x}}, {{y}})">'+
                    '<line x1="10" y1="20" x2="40" y2="20" stroke-width="2"/>' + 
                    '<text x="10" y="17">{{strLog(a)}}</text>' + 
                    '<line x1="10" y1="50" x2="40" y2="50"  stroke-width="2"/>' + 
                    '<text x="10" y="47">{{strLog(b)}}</text>' + 
                    '<rect x="40" y="5" width="40" height="60" fill="none" stroke-width="2" />' + 
                    '<text x="75" y="25" stroke-width="1.5" font-size="1.2em" text-anchor="end">{{sign}}</text>' + 
                    '<line x1="80" y1="35" x2="110" y2="35" stroke-width="2"/>' + 
                    '<text x="100" y="32">{{strLog(Q())}}</text>' + 
                '</g>'

And that's all.

We can use our directive from HTML page as a new tag:

<svg width="120" height="80">
 <log-or2 x="20" y="20" a="lab.data.A" b="lab.data.B" out="lab.out" hl="lab.HighLow()"></log-or2>

</svg>

Where lab.data.A, lab.data.B, lab.out are the variables assigned to the controller using the "controller as" syntax.


My app Boolean Lab

This directive is used in my android app Boolean Lab. It is the laboratory of logic Boolean functions in mobile/tablet; free, no ads, four languages - English, Spanish, Czech, Portugal.





No comments:

Post a Comment