Skip to content
Snippets Groups Projects
Select Git revision
  • dd64b11fa14b19da31deb65a957d86ec9abad166
  • master default
  • dja
  • dja_various_fixes
  • dja_differentiate_same_user_connections
  • dja_fix_bugs
  • dja_guest
  • dja_guests
  • dja_sign_out_without_race_conditions
  • dja_subgroups
  • dua_subgroups
  • dja_groups_2
  • dja_groups
  • dja_heroku_11_7_2024
  • dja_share_files
  • dja_execute_files_aux_2
  • dja_execute_files_aux
  • dja_execute_files
  • dja_files_page
  • dja-create-main-button
  • feature/aristas-metadata-vertices
  • v2.0
  • v1.0
23 results

graph2D.component.ts

Blame
  • graph2D.component.ts 32.72 KiB
    import { Component, ViewChild, ElementRef } from '@angular/core';
    import { GHCIService } from '../../../shared/services/ghci.service';
    import functionPlot from 'function-plot';
    import { Animation, Setting, toJSON, triggerDownload } from './graph2D.helper';
    import { TranslateService } from '@ngx-translate/core';
    
    @Component({
        moduleId: module.id,
        selector: 'graph2D-component',
        templateUrl: './graph2D.component.html',
        styleUrls: ['./graph2D.component.scss'],
        host: {
            '(window:resize)': 'onResize($event)'
        }
    })
    export class Graph2DComponent {
    
        // Ghci Service
        private ghciServiceSub: any;
    
        // Chart Container - DOM Element
        @ViewChild('graph2DContainer')
        private graph2DRef: ElementRef;
    
        // Chart Instance
        private instance: any;
    
        // Settings
        settings: Setting = {
            axis: true,
            grid: true,
            tip: true
        }
    
        private funciones= [];
    
        private id = 0;
    
        private conjunto= [];
    
        // Animation state
        animation: Animation = {
            data: [],
            init: false,
            currentFrame: 0,
            fps: 10,
            playing: false,
            timeout: null,
            animationFrame: null,
            speedX: 10,
            boton: true,
            zoo: 2000
        };
        //Nuevo
    
        public easeInOutCubic = function(fps) {
            var t = fps < 6 ? 6 : fps;
            var k = t/60;
            var animation = k<.5 ? 60*(4*k*k*k) : 60*((k-1)*(2*k-2)*(2*k-2)+1);
            console.log(animation);
            return animation;
        }
    
        public setZoom = () => {
            this.animation.zoo = this.animation.zoo ;  
        }
        public multiGraf = () => { 
            this.animation.boton = !this.animation.boton;
        }
        public constructor(private ghciService: GHCIService, public translate: TranslateService) {
            this.ghciServiceSub = ghciService.messages.subscribe(
                canvas => {
                    // Stop Animation
                    if (this.animation.init) {
                        this.stopAnimation();
                    }
                    switch(canvas.tipo) { 
                        case 'graph': {
                            var jsonCanvas = JSON.parse(canvas.resultado);
                            var conjs = this.obtenerConjunto(jsonCanvas.funs[0]);
        
                            var d = conjs + "}"; //Leo
        
                            var obj = JSON.parse(d);
                            //Para las funciones 
                            if (obj.conj.sets.fdom == "function(x)") {
                                var nom = jsonCanvas.funs[0].dom;
                                var elemento1 = this.recursionfuncion(jsonCanvas.funs[0].sets, nom);
                                obj.conj.sets.fdom = function (x) { return eval(elemento1) }
                            }
                            if (obj.conj.sets.fcod == "function(x)") {
                                var nom = jsonCanvas.funs[0].cod;
                                var elemento2 = this.recursionfuncion(jsonCanvas.funs[0].sets, nom);
                                obj.conj.sets.fcod = function (x) { return (eval(elemento2)) }
                            }
    
                            var funcionGenerada = this.generarFuncion(jsonCanvas);
                            console.log(obj)
    
                            //para Enumerados
                            if (obj.conj.dom == 'Numer') {
                                var j = 0;
                                for (var f of obj.conj.sets.fdom) {
                                    var expresionDom = new RegExp('( '+f+' )', 'g'); 
                                    funcionGenerada = funcionGenerada.replace(expresionDom, j.toString()); 
                                    j += 1;
                                }
                            }
                            if (obj.conj.cod == 'Numer') {
                                var j2 = 0;
                                for (var f2 of obj.conj.sets.fcod) {
                                    var expresionCod = new RegExp(f2, 'g'); 
                                    funcionGenerada = funcionGenerada.replace(expresionCod, j2.toString()); 
                                    j2 += 1;
                                }
    
                            }
    
                            let fun = eval(funcionGenerada);
    
                            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';
                            }
    
                            if(this.animation.boton && obj.conj.cod != 'Numer' && obj.conj.dom != 'Numer'){
                                if(this.conjunto.length == 1 && (this.conjunto[0].cod == 'Numer' || this.conjunto[0].dom == 'Numer')){
                                    this.conjunto = [];
                                    this.conjunto.push(obj.conj);
                                    this.id = 0;
                                    this.funciones = [];
                                    this.funciones.push({
                                        id: this.funciones.length,
                                        sampler: 'builtIn',
                                        fn: function(scope) {
                                          return fun(scope.x)
                                        },
                                        graphType: tipoGraf,
                                        color: color
                                    })
                                }else{
                                    if(this.conjunto.length == 1){
                                        this.id = 1;
                                        this.conjunto.unshift({radio: 2, dom:this.conjunto[0].baseDom, cod:this.conjunto[0].baseCod, baseCod:this.conjunto[0].baseCod, baseDom:this.conjunto[0].baseDom, sets:{fdom:this.conjunto[0].baseDom,fcod:this.conjunto[0].baseCod}});
                                        this.funciones[0].id = this.id;
                                        
                                    }
                                    if (this.conjunto.length != 0){ 
                                        if (obj.conj.baseDom == 'R'){
                                            this.conjunto[0].baseDom = 'R';
                                            this.conjunto[0].dom = 'R';
                                            this.conjunto[0].sets.fdom = 'R';
                                        }
                                        if (obj.conj.baseCod == 'R'){
                                            this.conjunto[0].baseCod = 'R';
                                            this.conjunto[0].cod = 'R';
                                            this.conjunto[0].sets.fcod = 'R';
                                        }
                                    }    
                                    this.conjunto.push(obj.conj);
    
                                    this.funciones.push({
                                        id: this.funciones.length + this.id,
                                        sampler: 'builtIn',
                                        fn: function(scope) {
                                        return fun(scope.x)
                                        },
                                        graphType: tipoGraf,
                                        color: color
                                    });
                                }        
                            }else{ 
                                this.conjunto = [];
                                this.conjunto.push(obj.conj);
                                this.id = 0;
                                this.funciones = [];
                                this.funciones.push({
                                    id: this.funciones.length,
                                    sampler: 'builtIn',
                                    fn: function(scope) {
                                      return fun(scope.x)
                                    },
                                    graphType: tipoGraf,
                                    color: color
                                });
                            }
                            let bounding = this.getBounding();
                            this.instance = functionPlot({
                                target: '#graph2D-container',
                                width: bounding.width,
                                height: bounding.height,
                                tip: { 
                                    color: 'green'
                                },
                                xAxis: {
                                    scale: 'linear',
                                    domain: { initial: [-4, 4],
                                            type: 'discrete' },
                                    yAxis: { domain: [-4, 4] }
                                },
                                conj:this.conjunto,
                                data: this.funciones,
                                zoom:this.animation.zoo,
                                plugins: [
                                    functionPlot.plugins.zoomBox()
                                ]
                            })
                            break; 
                        }
                        case 'canvas': {
                            var shapesData = JSON.parse(canvas.resultado);
                            var shapesDataNormalized = this.normalizeShapesData(shapesData);
                            let bounding = this.getBounding();
                            this.cleanPlot();
                            this.instance = functionPlot({
                                target: '#graph2D-container',
                                width: bounding.width,
                                height: bounding.height,
                                grid: true,
                                xAxis: {
                                    scale: 'linear',
                                    domain: {
                                        initial: [-10, 10],
                                        type: 'discrete'
                                    }
                                },
                                data: shapesDataNormalized,
                                plugins: [
                                    functionPlot.plugins.zoomBox()
                                ]
                            })
                            break; 
                        }
                        case 'animacion': {
                            this.cleanPlot();                  
                            var animationData = canvas.resultado.map(res => JSON.parse(res));
                            for (var frame of animationData) {
                                this.animation.data.push(this.normalizeShapesData(frame));
                            }
                            this.runAnimation();
                            this.animation.init = true;
                            break; 
                        }
                    }
                },
                error => {
                }
            )
        }
    
        /**
         * Angular lifecycle hook.
         * called after Angular has fully initialized a component's view.
         */
        ngAfterViewInit() {
            if (!this.instance) {
                let bounding = this.getBounding();
                this.instance = functionPlot({
                    target: '#graph2D-container',
                    width: bounding.width,
                    height: bounding.height,
                    grid: true,
                    xAxis: {
                        scale: 'linear',
                        domain: {
                            initial: [-10, 10],
                            type: 'discrete'
                        }
                    },
                    data: []
                })
            }
        }
    
        /**
         * Angular lifecycle hook.
         * called when a directive, pipe, or service is destroyed.
         */
        ngOnDestroy() {
            if (this.ghciServiceSub) {
              this.ghciServiceSub.unsubscribe();
            }
        }
    
        /**
         * On Resize Event.
         */
        onResize(event){
            let instance = this.instance;
            let bounding = this.getBounding();
            if (bounding.width > 0) {
                instance.options.width = bounding.width;
                instance.options.height = bounding.height;
                instance.build();
            }
        }
    
        /**
         * @name getBounding
         * @desc get the measures of the container of the graph
         */
        private getBounding = function() {
            var {width, height} = this.graph2DRef.nativeElement.getBoundingClientRect();
            if (width === 0) {
                width = document.getElementById('graph2D-container').querySelector('svg').width.baseVal.value;
                height = document.getElementById('graph2D-container').querySelector('svg').height.baseVal.value;
            }
            return {width, height}
        }
    
        /**
         * @name updateFrame
         * @desc update data for Function Plot and redraw the graph
         */
        public updateFrame = function() {
            var $this = this;
            var $data = $this.animation.data[$this.animation.currentFrame];
            if ($this.instance) {
                $this.instance.options.data = $data;
                $this.instance.draw();
            } else {
                let bounding = $this.getBounding();
                $this.instance = functionPlot({
                    target: '#graph2D-container',
                    width: bounding.width,
                    height: bounding.height,
                    xAxis: {
                        label: 'x - axis',
                        scale: 'linear',
                        domain: {
                            initial: [-10, 10],
                            type: 'discrete'
                        }
                    },
                    data: $data
                })
            }
            // Update Frame
            $this.animation.timeout = setTimeout(function() {
                $this.animation.currentFrame = ($this.animation.currentFrame + 1) % $this.animation.data.length;
                $this.animation.animationFrame = requestAnimationFrame($this.updateFrame.bind($this));
            }, 1000/ this.easeInOutCubic($this.animation.fps));
        }
    
        /**
         * @name runAnimation
         * @desc Run Shapes Animation
         */
        public runAnimation = function() {
            if (this.animation.playing) return;
            var $this = this;
            $this.animation.playing = true;
            $this.updateFrame();
        }
    
        /**
         * @name pauseAnimation
         * @desc Pause Shapes Animation
         */
        public pauseAnimation = function() {
            var $this = this;
            cancelAnimationFrame($this.animation.animationFrame);
            clearTimeout($this.animation.timeout);
            $this.animation.timeout = null;
            $this.animation.playing = false;
        }
    
        /**
         * @name stopAnimation
         * @desc Stop Shapes Animation
         */
        public stopAnimation = function() {
            var $this = this;
            $this.pauseAnimation();
            $this.animation.data = [];
            $this.animation.currentFrame = 0;
            $this.animation.init = false;
            this.instance.removeAllGraphs();
        }
    
        /**
         * @name decreaseSpeed
         * @desc Decrease Speed Animation
         */
        public decreaseSpeed = function() {
            var decrease = false;
            if (this.animation.fps > 6) {
                decrease = true;
            }
            if (decrease) {
                if (this.animation.fps > 10) {
                    this.animation.fps -= 1;
                    this.animation.speedX = this.animation.fps / 10;
                } else {
                    this.animation.fps -= 1;
                    this.animation.speedX = this.animation.fps / 10;
                }
                this.pauseAnimation();
                this.runAnimation();
            }
        }
        
        /**
         * @name restoreSpeed
         * @desc Increase Speed Animation
         */
        public restoreSpeed = function() {
            this.animation.fps = 10;
            this.animation.speedX = 1;
            this.pauseAnimation();
            this.runAnimation();
        }
    
        /**
         * @name increaseSpeed
         * @desc Increase Speed Animation
         */
        public increaseSpeed = function() {
            var increase = false;
            if (this.animation.fps < 60) {
                increase = true;
            }
            if (increase) {
                if (this.animation.fps >= 10) {
                    this.animation.fps += 1;
                    this.animation.speedX = this.animation.fps / 10;
                } else {
                    this.animation.fps += 1;
                    this.animation.speedX = this.animation.fps / 10;
                }
                this.pauseAnimation();
                this.runAnimation();
            }
        }
    
    
        /**
         * @name toggleGrid
         * @desc Show and Hide Grid
         */
        public toggleGrid = function () {
            this.instance.toggleGrid();
            this.settings.grid = !this.settings.grid;
        }
    
        /**
         * @name toggleAxis
         * @desc Show and Hide Axis
         */
        public toggleAxis = function () {
            this.instance.toggleAxis();
            this.settings.axis = !this.settings.axis;
        }
    
        /**
         * @name toggleTip
         * @desc Show and Hide Tip
         */
        public toggleTip = function () {
            this.instance.toggleTip();
            this.settings.tip = !this.settings.tip;
        }
    
        /**
         * @name zoomOut
         * @desc Zoom Out Button Control
         */
        public zoomOut = function () {
            this.instance.zoomOut();
        }
        /**
         * @name zoomIn
         * @desc Zoom In Button Control 
         */
        public zoomIn = function () {
            this.instance.zoomIn();
        }
        /**
         * @name recenterPlot
         * @desc center the plot and it returns to the initial state.
         */
        public recenterPlot = function () {
            this.instance.recenter();
        }
        /**
         * @name cleanPlot
         * @desc remove all the graph from the instance.
         */
        public cleanPlot = function () {
            if (this.animation.playing) {
                this.stopAnimation();
            } else {
                this.funciones = [];
                this.conjunto = [];
                this.id = 0;
                this.instance.removeAllGraphs();
            }
        }
    
        /**
         * @name exportPlot
         * @desc Download Plot as an SVG image.
         */
        public exportPlot = function() {
            // Objects
            var svg = document.querySelector('svg');
            var canvas = document.createElement("canvas");
    
            // Set dimensions of the image
            var svgSize = svg.getBoundingClientRect();
            canvas.width = svgSize.width;
            canvas.height = svgSize.height;
    
            // Convert SVG DOM structure to xml
            var ctx = canvas.getContext('2d');
            var data = new XMLSerializer().serializeToString(svg);
    
            // URL Object used to parse, construct, normalise, and encode URLs.
            var DOMURL = window.URL || (<any>window).webkitURL || window;
    
            var img = new Image();
            var svgBlob = new Blob([data], { type: 'image/svg+xml;charset=utf-8' });
            var url = DOMURL.createObjectURL(svgBlob);
    
            img.onload = function () {
                ctx.drawImage(img, 0, 0);
                DOMURL.revokeObjectURL(url);
    
                var imgURI = canvas
                    .toDataURL('image/png')
                    .replace('image/png', 'image/octet-stream');
    
                triggerDownload(imgURI);
            };
            img.src = url;
        }
    
    
        /**
         * @name normalizeRectData
         * @desc Normalize Rectangle data for Function Plot Library 
         * @param {Object} rectData Data of Rectangle to be normalized
         * @returns {Object}
         */
        public normalizeRectData = function ($rectData) {
            var $rectNormalized:any = {};
            var $shape:any = {};
            $shape.w = $rectData.w;
            $shape.h = $rectData.h;
            $shape.x = $rectData.x;
            $shape.y = $rectData.y;
            $rectData.color && ($shape.fill = $rectData.color);
            $rectData.rot !== 'undefined' && ($shape.rotation = $rectData.rot);
    
            $rectNormalized.shape = $shape;
            $rectNormalized.graphType = 'shape';
            $rectNormalized.shapeType = 'rect';
        
            return $rectNormalized;
        }
        /**
         * @name normalizeCircleData
         * @desc Normalize Circle data for Function Plot Library 
         * @param {Object} circleData Data of Circle to be normalized
         * @returns {Object}
         */
        public normalizeCircleData = function ($circleData) {
            var $circleNormalized:any = {};
            var $shape:any = {};
            $shape.r = $circleData.r;
            $shape.x = $circleData.x;
            $shape.y = $circleData.y;
            $circleData.color && ($shape.fill = $circleData.color);
            $circleData.rot !== 'undefined' && ($shape.rotation = $circleData.rot);
    
            $circleNormalized.shape = $shape;
            $circleNormalized.graphType = 'shape';
            $circleNormalized.shapeType = 'circle';
        
            return $circleNormalized;
        }
        /**
         * @name normalizeTextData
         * @desc Normalize Text data for Function Plot Library 
         * @param {Object} textData Data of Text to be normalized
         * @returns {Object}
         */
        public normalizeTextData = function ($textData) {
            var $textNormalized:any = {};
            var $shape:any = {};
            $shape.text = $textData.text;
            $shape.size = $textData.size;
            $shape.x = $textData.x;
            $shape.y = $textData.y;
            $textData.color && ($shape.fill = $textData.color);
            $textData.rot !== 'undefined' && ($shape.rotation = $textData.rot);
    
            $textNormalized.shape = $shape;
            $textNormalized.graphType = 'shape';
            $textNormalized.shapeType = 'text';
        
            return $textNormalized;
        }
        /**
         * @name normalizeLineData
         * @desc Normalize Line data for Function Plot Library 
         * @param {Object} lineData Data of Line to be normalized
         * @returns {Object}
         */
        public normalizeLineData = function ($lineData) {
            var $lineNormalized:any = {};
            var $points = []
            for (var p of $lineData.pts) {
                $points.push([p[0],p[1]]);
            }
            $lineNormalized.points = $points;
            $lineNormalized.stroke = $lineData.color;
            $lineNormalized.rotation = $lineData.rot;
            $lineNormalized.fnType = 'points';
            $lineNormalized.polylineType = 'line';
            $lineNormalized.graphType = 'polyline';
        
            return $lineNormalized;
        }
        /**
         * @name normalizePolygonData
         * @desc Normalize Polygon data for Function Plot Library 
         * @param {Object} textData Data of Polygon to be normalized
         * @returns {Object}
         */
        public normalizePolygonData = function ($polygonData) {
            var $polygonNormalized:any = {};
            var $points = []
            for (var p of $polygonData.pts) {
                $points.push([p[0],p[1]]);
            }
            $polygonNormalized.points = $points;
            $polygonNormalized.fill = $polygonData.color;
            $polygonNormalized.rotation = $polygonData.rot;
            $polygonNormalized.fnType = 'points';
            $polygonNormalized.polylineType = 'polygon';
            $polygonNormalized.graphType = 'polyline';
        
            return $polygonNormalized;
        }
    
        /**
         * @name normalizeShapesData
         * @desc Normalize Shapes data for Function Plot Library 
         * @param {Array} shapesData Data of Shapes to be normalized 
         * @returns {Array}
         */
        public normalizeShapesData = function (shapesData) {
            var normalized:Array<Object> = [];
            for (var shape of shapesData) {
                switch(shape.kind) { 
                    case 'rect': { 
                        normalized.push(this.normalizeRectData(shape)); 
                        break; 
                    } 
                    case 'circle': { 
                        normalized.push(this.normalizeCircleData(shape)); 
                        break; 
                    } 
                    case 'text': { 
                        normalized.push(this.normalizeTextData(shape)); 
                        break; 
                    }
                    case 'line': { 
                        normalized.push(this.normalizeLineData(shape)); 
                        break; 
                    }
                    case 'poly': { 
                        normalized.push(this.normalizePolygonData(shape)); 
                        break; 
                    } 
                } 
            }
            return normalized;
        }
    
    
    
        getRandomArbitrary = function (min, max) {
            return Math.round(Math.random() * (max - min) + min);
        }
    
        generarFuncion = function (graph) {
            var funcionString = '';
            var grafica;
            for (var fun of graph.funs) {
                funcionString = 'var ' + fun.fun + ' = function(' + fun.args.join() + '){\n return ' + this.generarExpresion(fun.bdy) + '}\n' + funcionString;
    
                if (fun.fun == graph.graph) {
                    funcionString += 'return ' + fun.fun + '(' + fun.args.join() + ');\n'
                    grafica = fun;
                }
            }
            funcionString = '(' + grafica.args.join() + ')=>{\n' + funcionString + '}';
    
            return funcionString;
        }
    
        generarExpresion = function (exp) {
            var expresion = '';
            if (exp.kind == 'cnd') {
                expresion = ' (' + this.generarExpresion(exp.cond) + '?' + this.generarExpresion(exp.exp1) + ':' + this.generarExpresion(exp.exp2) + ') ';
            } else if (exp.kind == 'bop') {
                if (exp.op == '==') {
                    expresion = ' Math.abs((' + this.generarExpresion(exp.exp1) + ') - (' + this.generarExpresion(exp.exp2) + ')) == 0 ';
                } else if (exp.op == '/=') {
                    expresion = ' Math.abs((' + this.generarExpresion(exp.exp1) + ') - (' + this.generarExpresion(exp.exp2) + ')) != 0';
                } else if (exp.op == '^') {
                    expresion = ' Math.pow(' + this.generarExpresion(exp.exp1) + ',' + this.generarExpresion(exp.exp2) + ') ';
                } else {
                    expresion = ' (' + this.generarExpresion(exp.exp1) + ')' + exp.op + '(' + this.generarExpresion(exp.exp2) + ') ';
                }
            } else if (exp.kind == 'uop') {
                expresion = ' ' + exp.op + ' ' + this.generarExpresion(exp.exp) + ' ';
            } else if (exp.kind == 'app') {
    			
    			if (exp.fun == 'cos') {
    				exp.fun = 'Math.cos'
    			} else if (exp.fun == 'sin') {
    				exp.fun = 'Math.sin'
    			} else if (exp.fun == 'round') {
    				exp.fun = 'Math.round'
    			}
    			expresion = ' ' + exp.fun + '(' + exp.args.map(e => this.generarExpresion(e)).join() + ') ';
    
            } else if (exp.kind == 'tup') {
                expresion = ' (' + exp.exps.map(e => this.generarExpresion(e)).join() + ') ';
            } else if (exp.kind == 'lit') {
                expresion = ' ' + exp.val + ' ';
            } else if (exp.kind == 'var') {
                expresion = ' ' + exp.var + ' ';
            } else {
                expresion = ' undefined ';
            }
    
            return expresion;
        }
    
        //Nuevo 20-07-2018
    
    
        obtenerConjunto = function (grf) {
    
            var setf = '\"sets\": {';
            var dominio = '{\"conj\": {';
            if (grf.dom == 'R') {
                dominio += "\"radio\": 0.3, \"baseDom\": \"R\", \"dom\": \"R\"";
                setf += "\"fdom\": \"R\",";
            } else if (grf.dom == 'Z') {
                dominio += "\"radio\": 2, \"baseDom\": \"Z\", \"dom\": \"Z\"";
                setf += "\"fdom\": \"Z\",";
            }/* else if (grf.dom == 'N') {
                dominio += "\"radio\":2, \"baseDom\": \"N\", \"dom\": \"N\"";
                setf += "\"fdom\": \"N\",";
            }*/ else {
                var nom = grf.dom;
                if (Array.isArray(grf.sets[0][nom])) {
                    var arreglo = grf.sets[0][nom];
                    var arreglo2 = [];
                    for (var item of arreglo) {
                        arreglo2.push("\"" + item + "\"");
                    }
                    dominio += "\"radio\":2, \"baseDom\": \"N\", \"dom\": \"Numer\"";
                    setf += "\"fdom\": [" + arreglo2 + "], ";
                } else {
    
                    dominio += this.recursivoDom(grf.sets, nom);
                    setf += "\"fdom\":\"function(x)\",";
                }
            }
            dominio += ", ";
            if (grf.cod == 'R') {
                dominio += "\"baseCod\": \"R\", \"cod\": \"R\" ,";
                setf += "\"fcod\": \"R\"";
            } else if (grf.cod == 'Z') {
                dominio += "\"baseCod\": \"Z\", \"cod\": \"Z\" ,";
                setf += "\"fcod\": \"Z\"";
           // } else if (grf.cod == 'N') {
           //     dominio += "\"baseCod\": \"N\", \"cod\": \"N\" ,";
           //     setf += "\"fcod\": \"N\"";
            } else {
                var nom = grf.cod;
                if (Array.isArray(grf.sets[0][nom])) {
                    var arreglo = grf.sets[0][nom];
                    var arreglo2 = [];
                    for (var item of arreglo) {
                        arreglo2.push("\"" + item + "\"");
                    }
                    dominio += "\"baseCod\": \"N\", \"cod\": \"Numer\" ,";
                    setf += '\"fcod\":[' + arreglo2 + ']';
                } else {
                    dominio += this.recursivoCod(grf.sets, nom);
                    setf += "\"fcod\": \"function(x)\"";
                }
            }
            return dominio + setf + "}}";
        }
    
        recursionfuncion = function (func, nombre) {
            var fun = func[0][nombre].set;
            var resul = "";
            if (fun == 'R' || fun == 'Z' || fun == 'N') {
                resul += this.generarF(func[0][nombre].cond);
            } else {
                resul += this.generarF(func[0][nombre].cond) + " && " + this.recursionfuncion(func, fun);
    
            }
            return resul;
        }
    
        recursivoDom = function (sets, nom) {
            var domin = "";
            if (sets[0][nom].set == 'R') {
                domin += "\"radio\": 0.3, \"baseDom\": \"R\", \"dom\": \"Func\"";
            } else if (sets[0][nom].set == 'Z') {
                domin += "\"radio\": 2, \"baseDom\": \"Z\", \"dom\": \"Func\"";
          //  } else if (sets[0][nom].set == 'N') {
          //      domin += "\"radio\": 2, \"baseDom\": \"N\", \"dom\": \"Func\"";
            } else {
                var nombre = sets[0][nom].set;
                domin = this.recursivoDom(sets, nombre);
            }
            return domin;
        }
    
    
        recursivoCod = function (sets, nom) {
            var coodo = "";
            if (sets[0][nom].set == 'R') {
                coodo += "\"baseCod\": \"R\", \"cod\": \"Func\",";
            } else if (sets[0][nom].set == 'Z') {
                coodo += "\"baseCod\": \"Z\", \"cod\": \"Func\",";
           // } else if (sets[0][nom].set == 'N') {
           //     coodo += "\"baseCod\": \"N\", \"cod\": \"Func\",";
            } else {
                var nombre = sets[0][nom].set;
                coodo += this.recursivoDom(sets, nombre);
            }
            return coodo;
        }
    
        generarF = function (exp) {
            var expresion = '';
            if (exp.kind == 'cond') {
                expresion = ' (' + this.generarF(exp.cond) + '?' + this.generarF(exp.exp1) + ':' + this.generarF(exp.exp2) + ') ';
            } else if (exp.kind == 'bop') {
                if (exp.op == '==') {
                    expresion = ' Math.abs((' + this.generarF(exp.exp1) + ') - (' + this.generarF(exp.exp2) + ')) == 0 ';
                } else if (exp.op == '/=') {
                    expresion = ' Math.abs((' + this.generarF(exp.exp1) + ') - (' + this.generarF(exp.exp2) + ')) != 0';
                } else if (exp.op == '^') {
                    expresion = ' Math.pow(' + this.generarF(exp.exp1) + ',' + this.generarF(exp.exp2) + ') ';
                } else {
                    expresion = ' (' + this.generarF(exp.exp1) + ')' + exp.op + '(' + this.generarF(exp.exp2) + ') ';
                }
            } else if (exp.kind == 'uop') {
                expresion = ' ' + exp.op + ' ' + this.generarF(exp.exp) + ' ';
            } else if (exp.kind == 'app') {
                if (exp.fun == 'cos') {
                    exp.fun = 'Math.cos'
                } else if (exp.fun == 'sin') {
                    exp.fun = 'Math.sin'
                } else if (exp.fun == 'round') {
                    exp.fun = 'Math.round'
                }
                expresion = ' ' + exp.fun + '(' + exp.args.map(e => this.generarF(e)).join() + ') ';
            } else if (exp.kind == 'tup') {
                expresion = ' (' + exp.exps.map(e => this.generarF(e)).join() + ') ';
            } else if (exp.kind == 'lit') {
                expresion = ' ' + exp.val + ' ';
            } else if (exp.kind == 'var') {
                expresion = ' ' + exp.var + ' ';
            } else {
                expresion = ' undefined ';
            }
    
            return expresion;
        }
    
        generarFun = function (graph) {
            var funcionString = '';
            var grafica;
            for (var fun of graph.funs) {
                funcionString = 'var ' + fun.fun + ' = function(' + fun.args.join() + '){\n return ' + this.generarF(fun.bdy) + '}\n' + funcionString;
    
                if (fun.fun == graph.graph) {
                    funcionString += 'return ' + fun.fun + '(' + fun.args.join() + ');\n'
                    grafica = fun;
                }
            }
            funcionString = '(' + grafica.args.join() + ')=>{\n' + funcionString + '}';
    
            return funcionString;
        }
    
    
    
    }