From 68c4fc59ffb3469a71f427d1cfcf08071c444f5d Mon Sep 17 00:00:00 2001
From: Diego Rey <diego.despaux@izundo.com>
Date: Sat, 11 Aug 2018 19:37:46 -0300
Subject: [PATCH] Added Animation handler for 2D component

---
 Frontend Angular 4/package-lock.json          |   4 +-
 .../plotter/graph2D/graph2D.component.html    |   9 +-
 .../plotter/graph2D/graph2D.component.ts      | 284 ++++++++++--------
 .../layout/plotter/graph2D/graph2D.helper.ts  |   8 +
 4 files changed, 182 insertions(+), 123 deletions(-)
 create mode 100644 Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.helper.ts

diff --git a/Frontend Angular 4/package-lock.json b/Frontend Angular 4/package-lock.json
index 318c9c9..19ab35b 100644
--- a/Frontend Angular 4/package-lock.json	
+++ b/Frontend Angular 4/package-lock.json	
@@ -4139,8 +4139,8 @@
       "dev": true
     },
     "function-plot": {
-      "version": "git+https://github.com/diego-rey/function-plot.git#e81bedcbbdfe8cdd7c356a1bca4664ad7db5a371",
-      "from": "git+https://github.com/diego-rey/function-plot.git#feature/integration-domain-shape",
+      "version": "git://github.com/diego-rey/function-plot.git#d8b7147168ab7a595f8323d28ffc944735117606",
+      "from": "git://github.com/diego-rey/function-plot.git#feature/integration-domain-shape",
       "requires": {
         "array-range": "^1.0.1",
         "built-in-math-eval": "^0.3.0",
diff --git a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.html b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.html
index 9260662..4cc1455 100755
--- a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.html	
+++ b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.html	
@@ -1,8 +1,13 @@
 <div class="card">
     <div class="card-block contenedor-canvas" >
         <button ngbPopover="Zoom +"  triggers="mouseenter:mouseleave" data-placement="bottom" class="btn btn-sm btn-secondary" style="float:right; margin-right: 165px; margin-top: -55px" (click)=zoomIn() ><i class="fa fa-plus"></i></button>
-        <button ngbPopover="Zoom -"  data-placement="bottom" triggers="mouseenter:mouseleave" class="btn btn-sm btn-secondary" style="float:right; margin-right: 132px; margin-top: -55px" (click)=zoomOut() ><i class="fa fa-minus"></i></button>
-              
+        <button ngbPopover="Zoom -"  triggers="mouseenter:mouseleave" data-placement="bottom" class="btn btn-sm btn-secondary" style="float:right; margin-right: 132px; margin-top: -55px" (click)=zoomOut() ><i class="fa fa-minus"></i></button>
+        
+        <button class="btn btn-sm btn-secondary" data-placement="bottom" *ngIf="!animation.playing && animation.data.length>0" style=" float:left; margin-top: -5px; margin-right: 5px" (click)="runAnimation()" ><i class="fa fa-play"></i></button>
+		<button class="btn btn-sm btn-secondary" data-placement="bottom" *ngIf="animation.playing && animation.data.length>0" style=" float:left; margin-top: -5px; margin-right: 5px" (click)="pauseAnimation()" ><i class="fa fa-pause"></i></button>
+
+		<ngb-progressbar style="float: left; width: 90%" *ngIf="animation.data.length>0" type="info" [value]="((animation.currentFrame+1)/animation.data.length)*100"></ngb-progressbar>
+
         <div id="graph2D-container" style="height: 100%; width: 100%;">
         </div>
     </div>
diff --git a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.ts b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.ts
index 7d48000..25e86cc 100755
--- a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.ts	
+++ b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.ts	
@@ -1,6 +1,7 @@
 import { Component } from '@angular/core';
 import { GHCIService } from '../../../shared/services/ghci.service';
 import functionPlot from 'function-plot';
+import { Animation } from './graph2D.helper';
 
 @Component({
     moduleId: module.id,
@@ -12,137 +13,184 @@ import functionPlot from 'function-plot';
 })
 export class Graph2DComponent {
 
-    private instance: {};
+    private instance: null;
+
+    private animation: Animation = {
+        data: [],
+        timer: null,
+        currentFrame: 0,
+        speed: 1000,
+        playing: false,
+        init: false
+    };
 
     public constructor(private ghciService: GHCIService) {
         ghciService.messages.subscribe(
             canvas => {
-
-                if (canvas.tipo == 'graph') {
-                    var jsonCanvas = JSON.parse(canvas.resultado);
-                    let fun = eval(this.generarFuncion(jsonCanvas));
-                    var conjs = this.obtenerConjunto(jsonCanvas.funs[0]);
-
-                    var d = conjs + "}";
-
-                    var obj = JSON.parse(d);
-                    //Para las funciones 
-                    if (obj.conj.sets.fdom == "function(x)") {
-                        var nom = jsonCanvas.funs[0].dom;
-                        var elemento = this.recursionfuncion(jsonCanvas.funs[0].sets, nom);
-                        obj.conj.sets.fdom = function (x) { return eval(elemento) }
-                    }
-                    if (obj.conj.sets.fcod == "function(x)") {
-                        var nom = jsonCanvas.funs[0].cod;
-                        var elemento = this.recursionfuncion(jsonCanvas.funs[0].sets, nom);
-                        obj.conj.sets.fcod = function (x) { return (eval(elemento)) }
-                    }
-                    //para Enumerados
-                    if (obj.conj.dom == 'Numer') {
-                        var cantElementos = obj.conj.sets.fdom.length;
-                        var j = 0;
-                        for (var fun of obj.conj.sets.fdom) {
-                            //var newstr = nuevo2.replace(fun, j); 
-                            j = j + 1;
+                switch(canvas.tipo) { 
+                    case 'graph': {
+                        var jsonCanvas = JSON.parse(canvas.resultado);
+                        let fun = eval(this.generarFuncion(jsonCanvas));
+                        var conjs = this.obtenerConjunto(jsonCanvas.funs[0]);
+    
+                        var d = conjs + "}";
+    
+                        var obj = JSON.parse(d);
+                        //Para las funciones 
+                        if (obj.conj.sets.fdom == "function(x)") {
+                            var nom = jsonCanvas.funs[0].dom;
+                            var elemento = this.recursionfuncion(jsonCanvas.funs[0].sets, nom);
+                            obj.conj.sets.fdom = function (x) { return eval(elemento) }
                         }
-
-                    }
-                    if (obj.conj.cod == 'Numer') {
-                        var cantElementos = obj.conj.sets.fcod.length;
-                        var j = 0;
-                        for (var fun of obj.conj.sets.fcod) {
-                            //var newstr = nuevo2.replace(fun, j); 
-                            j = j + 1;
+                        if (obj.conj.sets.fcod == "function(x)") {
+                            var nom = jsonCanvas.funs[0].cod;
+                            var elemento = this.recursionfuncion(jsonCanvas.funs[0].sets, nom);
+                            obj.conj.sets.fcod = function (x) { return (eval(elemento)) }
                         }
-
+                        //para Enumerados
+                        if (obj.conj.dom == 'Numer') {
+                            var cantElementos = obj.conj.sets.fdom.length;
+                            var j = 0;
+                            for (var fun of obj.conj.sets.fdom) {
+                                //var newstr = nuevo2.replace(fun, j); 
+                                j = j + 1;
+                            }
+    
+                        }
+                        if (obj.conj.cod == 'Numer') {
+                            var cantElementos = obj.conj.sets.fcod.length;
+                            var j = 0;
+                            for (var fun of obj.conj.sets.fcod) {
+                                //var newstr = nuevo2.replace(fun, j); 
+                                j = j + 1;
+                            }
+    
+                        }
+    
+                        var colores = ['pink', 'red', 'blue', 'orange', 'green']
+                        var num = this.getRandomArbitrary(0, 4);
+                        var color = colores[num];
+    
+                        var tipoGraf;
+                        if (obj.conj.baseDom != 'R'){
+                            tipoGraf = 'scatter';
+                        }else{
+                            tipoGraf = 'polyline';
+                        }
+                        this.instance = functionPlot({
+                            target: '#graph2D-container',
+                            width: 620,
+                            height: 450,
+                            conj:obj.conj,
+                            data: [{
+                                sampler: 'builtIn',
+                                fn: function(scope) {
+                                  return fun(scope.x)
+                                },
+                                graphType: tipoGraf,
+                                color: color
+                            }],
+                            plugins: [
+                                functionPlot.plugins.zoomBox()
+                            ]
+                        })
+                        break; 
                     }
-
-                    var colores = ['pink', 'red', 'blue', 'orange', 'green']
-                    var num = this.getRandomArbitrary(0, 4);
-                    var color = colores[num];
-
-                    var tipoGraf;
-                    if (obj.conj.baseDom != 'R'){
-                        tipoGraf = 'scatter';
-                    }else{
-                        tipoGraf = 'polyline';
+                    case 'canvas': {
+                        console.log('TIPO', canvas.tipo);
+                        var shapesData = JSON.parse(canvas.resultado);
+                        var shapesDataNormalized = this.normalizeShapesData(shapesData);
+    
+                        this.instance = functionPlot({
+                            target: '#graph2D-container',
+                            width: 800,
+                            height: 700,
+                            xAxis: {
+                                label: 'x - axis',
+                                scale: 'linear',
+                                domain: {
+                                    initial: [-10, 10],
+                                    type: 'discrete'
+                                }
+                            },
+                            data: shapesDataNormalized,
+                            plugins: [
+                                functionPlot.plugins.zoomBox()
+                            ]
+                        })
+                        break; 
                     }
-                    this.instance = functionPlot({
-						target: '#graph2D-container',
-						width: 620,
-						height: 450,
-						conj:obj.conj,
-						data: [{
-							sampler: 'builtIn',
-							fn: function(scope) {
-							  return fun(scope.x)
-							},
-							graphType: tipoGraf,
-							color: color
-						}],
-						plugins: [
-							functionPlot.plugins.zoomBox()
-						]
-					})
-
-                    // EXAMPLE - SHAPE
-                    // this.instance = functionPlot({
-                    //     target: '#graph2D-container',
-                    //     width: 700,
-                    //     height: 700,
-                    //     xAxis: {
-                    //       label: 'x - axis',
-                    //       scale: 'linear',
-                    //       domain: {
-                    //         initial: [-10, 10],
-                    //         type: 'discrete'
-                    //       }
-                    //     },
-                    //     data: [{
-                    //       shape: {
-                    //         w : 6.0,
-                    //         h : 3.0,
-                    //         x : 0,
-                    //         y : 0,
-                    //         color :"red",
-                    //         rotation : 0.125
-                    //       },
-                    //       graphType: 'shape',
-                    //       shapeType: 'rect'
-                    //     }],
-                    //     plugins: [
-                    //         functionPlot.plugins.zoomBox()
-                    //     ]
-                    // })
-                } else if (canvas.tipo == 'canvas') {
-                    var shapesData = JSON.parse(canvas.resultado);
-                    console.log('Shapes Data:', shapesData);
-                    var shapesDataNormalized = this.normalizeShapesData(shapesData);
-                    console.log('Shapes Normalized', shapesDataNormalized);
-
-
-                    this.instance = functionPlot({
-						target: '#graph2D-container',
-                        width: 800,
-                        height: 700,
-                        xAxis: {
-                            label: 'x - axis',
-                            scale: 'linear',
-                            domain: {
-                                initial: [-10, 10],
-                                type: 'discrete'
+                    case 'animacion': {
+                        console.log('TIPO', canvas.tipo);
+                        
+                        if(!this.animation.init) {
+                            this.animation.init = true;
+                            var animationData = canvas.resultado.map(res => JSON.parse(res));
+                            for (var frame of animationData) {
+                                this.animation.data.push(this.normalizeShapesData(frame));
                             }
-                        },
-						data: shapesDataNormalized,
-						plugins: [
-							functionPlot.plugins.zoomBox()
-						]
-					})
+                            this.runAnimation();
+                        }
+                        break; 
+                    }
                 }
             },
             error => {
+            }
+        )
+    }
 
+    /**
+     * @name updateFrame
+     * @desc update data for Function Plot and redraw the graph
+     */
+    public updateFrame = function(d) {
+        if (this.instance) {
+            this.instance.options.data = d;
+            this.instance.draw();
+        } else {
+            this.instance = functionPlot({
+                target: '#graph2D-container',
+                width: 800,
+                height: 700,
+                xAxis: {
+                    label: 'x - axis',
+                    scale: 'linear',
+                    domain: {
+                        initial: [-10, 10],
+                        type: 'discrete'
+                    }
+                },
+                data: d,
+                plugins: [
+                    functionPlot.plugins.zoomBox()
+                ]
             })
+        }
+    }
+
+    /**
+     * @name runAnimation
+     * @desc Run Shapes Animation
+     */
+    public runAnimation = function() {
+        var $this = this;
+        if ($this.animation.timer !== null) return;
+        $this.animation.timer = setInterval(function(){
+            $this.updateFrame($this.animation.data[$this.animation.currentFrame]);
+            $this.animation.currentFrame = ($this.animation.currentFrame + 1) % $this.animation.data.length;    
+        }, $this.animation.speed);
+        $this.animation.playing = true;
+    }
+    /**
+     * @name pauseAnimation
+     * @desc Pause Shapes Animation
+     */
+    public pauseAnimation = function() {
+        var $this = this;
+        clearInterval($this.animation.timer);
+        $this.animation.timer = null;
+        $this.animation.playing = false;
     }
 
     /**
@@ -253,8 +301,6 @@ export class Graph2DComponent {
         return normalized;
     }
 
-
-
     getRandomArbitrary = function (min, max) {
         return Math.round(Math.random() * (max - min) + min);
     }
diff --git a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.helper.ts b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.helper.ts
new file mode 100644
index 0000000..9eb99ba
--- /dev/null
+++ b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.helper.ts	
@@ -0,0 +1,8 @@
+export interface Animation {
+	data?: any,
+	timer?: any,
+	currentFrame: number,
+	speed: number,
+	playing: boolean,
+	init: boolean
+}
-- 
GitLab