graph2D.component.ts 30.6 KB
Newer Older
1
import { Component, ViewChild, ElementRef } from '@angular/core';
Diego Rey's avatar
Diego Rey committed
2
3
import { GHCIService } from '../../../shared/services/ghci.service';
import functionPlot from 'function-plot';
4
import { Animation, Setting, toJSON, triggerDownload } from './graph2D.helper';
Diego Rey's avatar
Diego Rey committed
5

6
7
@Component({
    moduleId: module.id,
Diego Rey's avatar
Diego Rey committed
8
9
    selector: 'graph2D-component',
    templateUrl: './graph2D.component.html',
10
    styleUrls: ['./graph2D.component.scss'],
11
    host: {
12
        '(window:resize)': 'onResize($event)'
13
14
    }
})
Diego Rey's avatar
Diego Rey committed
15
export class Graph2DComponent {
Diego Rey's avatar
Diego Rey committed
16

17
    // Ghci Service
18
19
    private ghciServiceSub: any;

20
21
22
23
24
25
26
27
28
29
30
31
32
    // Chart Container - DOM Element
    @ViewChild('graph2DContainer')
    private graph2DRef: ElementRef;

    // Chart Instance
    private instance: any;

    // Settings
    settings: Setting = {
        axis: true,
        grid: true,
        tip: true
    }
33

34
35
36
37
38
39
    private funciones= [];

    private id = 0;

    private conjunto= [];

40
    // Animation state
41
    animation: Animation = {
42
43
44
45
        data: [],
        timer: null,
        currentFrame: 0,
        speed: 1000,
Diego Rey's avatar
Diego Rey committed
46
        speedX: 1.0,
47
        playing: false,
48
49
50
        init: false,
        boton: true,
        zoo: 2000
51
    };
52
53
    //Nuevo

Diego Rey's avatar
Diego Rey committed
54

55
56
57
58
59
60
    public setZoom = () => {
        this.animation.zoo = this.animation.zoo ;
    }
    public multiGraf = () => { 
        this.animation.boton = !this.animation.boton;
    }
61
    public constructor(private ghciService: GHCIService) {
62
        this.ghciServiceSub = ghciService.messages.subscribe(
Diego Rey's avatar
Diego Rey committed
63
            canvas => {
64
65
66
67
                // Stop Animation
                if (this.animation.init) {
                    this.stopAnimation();
                }
68
69
70
71
72
73
                switch(canvas.tipo) { 
                    case 'graph': {
                        var jsonCanvas = JSON.parse(canvas.resultado);
                        let fun = eval(this.generarFuncion(jsonCanvas));
                        var conjs = this.obtenerConjunto(jsonCanvas.funs[0]);
    
74
                        var d = conjs + "}"; //Leo
75
76
77
78
79
    
                        var obj = JSON.parse(d);
                        //Para las funciones 
                        if (obj.conj.sets.fdom == "function(x)") {
                            var nom = jsonCanvas.funs[0].dom;
80
81
                            var elemento1 = this.recursionfuncion(jsonCanvas.funs[0].sets, nom);
                            obj.conj.sets.fdom = function (x) { return eval(elemento1) }
82
                        }
83
84
                        if (obj.conj.sets.fcod == "function(x)") {
                            var nom = jsonCanvas.funs[0].cod;
85
86
                            var elemento2 = this.recursionfuncion(jsonCanvas.funs[0].sets, nom);
                            obj.conj.sets.fcod = function (x) { return (eval(elemento2)) }
87
                        }
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
                        //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';
                        }
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141

                        if(this.animation.boton && obj.conj.cod != 'Numer' && obj.conj.dom != 'Numer'){
                            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,
142
143
144
145
146
147
                                sampler: 'builtIn',
                                fn: function(scope) {
                                  return fun(scope.x)
                                },
                                graphType: tipoGraf,
                                color: color
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
                            });

                        }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
                            });
                        }
165
                        let bounding = this.getBounding();
166
167
                        this.instance = functionPlot({
                            target: '#graph2D-container',
168
169
                            width: bounding.width,
                            height: bounding.height,
170
171
172
173
174
175
176
177
178
179
                            tip: { color: 'green' },
                            xAxis: { label: 'x - axis',
                                scale: 'linear',
                                domain: { initial: [-4, 4],
                                        type: 'discrete' },
                                yAxis: { domain: [-4, 4] }
                            },
                            conj:this.conjunto,
                            data: this.funciones,
                            zoom:this.animation.zoo,
180
181
182
183
184
                            plugins: [
                                functionPlot.plugins.zoomBox()
                            ]
                        })
                        break; 
185
                    }
186
                    case 'canvas': {
187
                        var shapesData = JSON.parse(canvas.resultado);
188
                        var shapesDataNormalized = this.normalizeShapesData(shapesData);
189
190
                        let bounding = this.getBounding();
                        this.cleanPlot();
191
192
                        this.instance = functionPlot({
                            target: '#graph2D-container',
193
194
195
                            width: bounding.width,
                            height: bounding.height,
                            grid: true,
196
197
198
199
200
201
202
203
204
205
206
207
208
209
                            xAxis: {
                                label: 'x - axis',
                                scale: 'linear',
                                domain: {
                                    initial: [-10, 10],
                                    type: 'discrete'
                                }
                            },
                            data: shapesDataNormalized,
                            plugins: [
                                functionPlot.plugins.zoomBox()
                            ]
                        })
                        break; 
210
                    }
211
212
                    case 'animacion': {
                        this.cleanPlot();                  
213
214
215
                        var animationData = canvas.resultado.map(res => JSON.parse(res));
                        for (var frame of animationData) {
                            this.animation.data.push(this.normalizeShapesData(frame));
216
                        }
217
218
                        this.runAnimation();
                        this.animation.init = true;
219
220
                        break; 
                    }
221
                }
Diego Rey's avatar
Diego Rey committed
222
223
            },
            error => {
224
225
226
            }
        )
    }
Diego Rey's avatar
Diego Rey committed
227

228
229
230
231
232
233
    /**
     * Angular lifecycle hook.
     * called after Angular has fully initialized a component's view.
     */
    ngAfterViewInit() {
        if (!this.instance) {
234
            let bounding = this.getBounding();
235
236
            this.instance = functionPlot({
                target: '#graph2D-container',
237
238
239
                width: bounding.width,
                height: bounding.height,
                grid: true,
240
241
242
243
244
245
246
247
                xAxis: {
                    label: 'x - axis',
                    scale: 'linear',
                    domain: {
                        initial: [-10, 10],
                        type: 'discrete'
                    }
                },
248
                data: []
249
250
251
252
253
254
255
256
257
258
259
260
261
262
            })
        }
    }

    /**
     * Angular lifecycle hook.
     * called when a directive, pipe, or service is destroyed.
     */
    ngOnDestroy() {
        if (this.ghciServiceSub) {
          this.ghciServiceSub.unsubscribe();
        }
    }

263
264
265
266
267
268
    /**
     * On Resize Event.
     */
    onResize(event){
        let instance = this.instance;
        let bounding = this.getBounding();
269
        if (bounding.width > 0) {
270
271
272
            instance.options.width = bounding.width;
            instance.options.height = bounding.height;
            instance.build();
273
        }
274
275
276
277
278
279
280
281
282
283
284
    }

    /**
     * @name getBounding
     * @desc get the measures of the container of the graph
     */
    private getBounding = function() {
        const {width, height} = this.graph2DRef.nativeElement.getBoundingClientRect();
        return {width, height}
    }

285
286
287
288
289
290
291
292
293
    /**
     * @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 {
294
            let bounding = this.getBounding();
295
296
            this.instance = functionPlot({
                target: '#graph2D-container',
297
298
                width: bounding.width,
                height: bounding.height,
299
300
301
302
303
304
305
306
                xAxis: {
                    label: 'x - axis',
                    scale: 'linear',
                    domain: {
                        initial: [-10, 10],
                        type: 'discrete'
                    }
                },
307
                data: d
Diego Rey's avatar
Diego Rey committed
308
            })
309
        }
310
311
        // Update Frame
        this.animation.currentFrame = (this.animation.currentFrame + 1) % this.animation.data.length;
312
313
314
315
316
317
318
319
    }
    /**
     * @name runAnimation
     * @desc Run Shapes Animation
     */
    public runAnimation = function() {
        var $this = this;
        if ($this.animation.timer !== null) return;
320
        $this.updateFrame($this.animation.data[$this.animation.currentFrame]);
321
322
323
324
325
326
327
328
329
330
331
332
333
334
        $this.animation.timer = setInterval(function(){
            $this.updateFrame($this.animation.data[$this.animation.currentFrame]);
        }, $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;
Diego Rey's avatar
Diego Rey committed
335
    }
336
337
338
339
340
341
342
343
344
345
346
347
    /**
     * @name stopAnimation
     * @desc Stop Shapes Animation
     */
    public stopAnimation = function() {
        var $this = this;
        clearInterval($this.animation.timer);
        $this.animation.data = [];
        $this.animation.timer = null;
        $this.animation.currentFrame = 0;
        $this.animation.speed = 1000;
        $this.animation.playing = false;
Diego Rey's avatar
Diego Rey committed
348
        $this.animation.init = false;
349
350
        this.instance.removeAllGraphs();
    }
Diego Rey's avatar
Diego Rey committed
351

Diego Rey's avatar
Diego Rey committed
352
353
354
355
356
    /**
     * @name decreaseSpeed
     * @desc Decrease Speed Animation
     */
    public decreaseSpeed = function() {
Diego Rey's avatar
Diego Rey committed
357
        if (this.animation.speedX > 0.19) {
Diego Rey's avatar
Diego Rey committed
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
            this.animation.speed *= 1.1;
            this.animation.speedX -= 0.1;
            this.pauseAnimation();
            this.runAnimation();
        }
    }
    
    /**
     * @name restoreSpeed
     * @desc Increase Speed Animation
     */
    public restoreSpeed = function() {
        this.animation.speed = 1000;
        this.animation.speedX = 1;
        this.pauseAnimation();
        this.runAnimation();
    }

376
    /**
377
378
379
380
     * @name increaseSpeed
     * @desc Increase Speed Animation
     */
    public increaseSpeed = function() {
Diego Rey's avatar
Diego Rey committed
381
382
383
384
385
386
        if (this.animation.speedX < 10) {
            this.animation.speed *= 0.9;
            this.animation.speedX += 0.1;
            this.pauseAnimation();
            this.runAnimation();
        }
387
388
389
390
391
392
393
394
    }


    /**
     * @name toggleGrid
     * @desc Show and Hide Grid
     */
    public toggleGrid = function () {
395
        this.instance.toggleGrid();
Diego Rey's avatar
Diego Rey committed
396
        this.settings.grid = !this.settings.grid;
397
398
399
400
401
402
403
    }

    /**
     * @name toggleAxis
     * @desc Show and Hide Axis
     */
    public toggleAxis = function () {
404
        this.instance.toggleAxis();
Diego Rey's avatar
Diego Rey committed
405
        this.settings.axis = !this.settings.axis;
406
407
408
409
410
411
412
    }

    /**
     * @name toggleTip
     * @desc Show and Hide Tip
     */
    public toggleTip = function () {
413
        this.instance.toggleTip();
Diego Rey's avatar
Diego Rey committed
414
        this.settings.tip = !this.settings.tip;
415
416
417
    }

    /**
418
419
420
421
     * @name zoomOut
     * @desc Zoom Out Button Control
     */
    public zoomOut = function () {
Diego Rey's avatar
Diego Rey committed
422
        this.instance.zoomOut();
423
    }
424
425
426
427
428
    /**
     * @name zoomIn
     * @desc Zoom In Button Control 
     */
    public zoomIn = function () {
Diego Rey's avatar
Diego Rey committed
429
430
        this.instance.zoomIn();
    }
431
432
433
434
435
436
437
438
439
440
441
442
    /**
     * @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 () {
443
444
445
        if (this.animation.playing) {
            this.stopAnimation();
        } else {
446
447
448
            this.funciones = [];
            this.conjunto = [];
            this.id = 0;
449
450
            this.instance.removeAllGraphs();
        }
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
    }

    /**
     * @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;
    }

491

492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
    /**
     * @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;
    }
535
    /**
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
     * @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;
    }
557
558
559
560
    /**
     * @name normalizeLineData
     * @desc Normalize Line data for Function Plot Library 
     * @param {Object} lineData Data of Line to be normalized
561
562
     * @returns {Object}
     */
Diego Rey's avatar
Diego Rey committed
563
564
565
566
567
568
569
570
571
572
573
574
    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';
575
    
Diego Rey's avatar
Diego Rey committed
576
577
        return $lineNormalized;
    }
578
579
580
581
    /**
     * @name normalizePolygonData
     * @desc Normalize Polygon data for Function Plot Library 
     * @param {Object} textData Data of Polygon to be normalized
582
583
     * @returns {Object}
     */
Diego Rey's avatar
Diego Rey committed
584
585
586
587
588
589
590
591
592
593
594
595
    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';
596
    
Diego Rey's avatar
Diego Rey committed
597
598
        return $polygonNormalized;
    }
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620

    /**
     * @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; 
621
                }
Diego Rey's avatar
Diego Rey committed
622
623
624
625
626
627
628
629
                case 'line': { 
                    normalized.push(this.normalizeLineData(shape)); 
                    break; 
                }
                case 'poly': { 
                    normalized.push(this.normalizePolygonData(shape)); 
                    break; 
                } 
630
631
632
633
634
            } 
        }
        return normalized;
    }

635
636


Diego Rey's avatar
Diego Rey committed
637
    getRandomArbitrary = function (min, max) {
638
639
        return Math.round(Math.random() * (max - min) + min);
    }
Diego Rey's avatar
Diego Rey committed
640
641
642
643
644
645
646
647
648
649

    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;
650
651
            }
        }
652
        funcionString = '(' + grafica.args.join() + ')=>{\n' + funcionString + '}';
Diego Rey's avatar
Diego Rey committed
653
654
655

        return funcionString;
    }
656

Diego Rey's avatar
Diego Rey committed
657
    generarExpresion = function (exp) {
658
659
        var expresion = '';
        if (exp.kind == 'cnd') {
Diego Rey's avatar
Diego Rey committed
660
            expresion = ' (' + this.generarExpresion(exp.cond) + '?' + this.generarExpresion(exp.exp1) + ':' + this.generarExpresion(exp.exp2) + ') ';
661
        } else if (exp.kind == 'bop') {
Diego Rey's avatar
Diego Rey committed
662
            if (exp.op == '==') {
663
                expresion = ' Math.abs((' + this.generarExpresion(exp.exp1) + ') - (' + this.generarExpresion(exp.exp2) + ')) == 0 ';
Diego Rey's avatar
Diego Rey committed
664
            } else if (exp.op == '/=') {
665
                expresion = ' Math.abs((' + this.generarExpresion(exp.exp1) + ') - (' + this.generarExpresion(exp.exp2) + ')) == 0 ||  Math.abs((' + this.generarExpresion(exp.exp1) + ') - (' + this.generarExpresion(exp.exp2) + ')) == 0  ';
Diego Rey's avatar
Diego Rey committed
666
667
668
669
670
            } 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) + ') ';
            }
671
        } else if (exp.kind == 'uop') {
Diego Rey's avatar
Diego Rey committed
672
            expresion = ' ' + exp.op + ' ' + this.generarExpresion(exp.exp) + ' ';
673
        } else if (exp.kind == 'app') {
674
675
676
677
678
679
680
681
682
683
			
			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() + ') ';

684
        } else if (exp.kind == 'tup') {
Diego Rey's avatar
Diego Rey committed
685
            expresion = ' (' + exp.exps.map(e => this.generarExpresion(e)).join() + ') ';
686
        } else if (exp.kind == 'lit') {
Diego Rey's avatar
Diego Rey committed
687
            expresion = ' ' + exp.val + ' ';
688
        } else if (exp.kind == 'var') {
Diego Rey's avatar
Diego Rey committed
689
            expresion = ' ' + exp.var + ' ';
690
        } else {
Diego Rey's avatar
Diego Rey committed
691
            expresion = ' undefined ';
692
        }
Diego Rey's avatar
Diego Rey committed
693

694
695
        return expresion;
    }
696

Diego Rey's avatar
Diego Rey committed
697
    //Nuevo 20-07-2018
698
699


Diego Rey's avatar
Diego Rey committed
700
    obtenerConjunto = function (grf) {
701
702

        var setf = '\"sets\": {';
Diego Rey's avatar
Diego Rey committed
703
704
        var dominio = '{\"conj\": {';
        if (grf.dom == 'R') {
705
706
            dominio += "\"radio\": 0.3, \"baseDom\": \"R\", \"dom\": \"R\"";
            setf += "\"fdom\": \"R\",";
Diego Rey's avatar
Diego Rey committed
707
        } else if (grf.dom == 'Z') {
708
709
            dominio += "\"radio\": 2, \"baseDom\": \"Z\", \"dom\": \"Z\"";
            setf += "\"fdom\": \"Z\",";
710
        }/* else if (grf.dom == 'N') {
711
712
            dominio += "\"radio\":2, \"baseDom\": \"N\", \"dom\": \"N\"";
            setf += "\"fdom\": \"N\",";
713
        }*/ else {
714
            var nom = grf.dom;
Diego Rey's avatar
Diego Rey committed
715
            if (Array.isArray(grf.sets[0][nom])) {
716
717
                var arreglo = grf.sets[0][nom];
                var arreglo2 = [];
Diego Rey's avatar
Diego Rey committed
718
719
                for (var item of arreglo) {
                    arreglo2.push("\"" + item + "\"");
720
721
722
                }
                dominio += "\"radio\":2, \"baseDom\": \"N\", \"dom\": \"Numer\"";
                setf += "\"fdom\": [" + arreglo2 + "], ";
Diego Rey's avatar
Diego Rey committed
723
724
725
            } else {

                dominio += this.recursivoDom(grf.sets, nom);
726
                setf += "\"fdom\":\"function(x)\",";
Diego Rey's avatar
Diego Rey committed
727
            }
728
        }
Diego Rey's avatar
Diego Rey committed
729
730
        dominio += ", ";
        if (grf.cod == 'R') {
731
732
            dominio += "\"baseCod\": \"R\", \"cod\": \"R\" ,";
            setf += "\"fcod\": \"R\"";
Diego Rey's avatar
Diego Rey committed
733
        } else if (grf.cod == 'Z') {
734
735
            dominio += "\"baseCod\": \"Z\", \"cod\": \"Z\" ,";
            setf += "\"fcod\": \"Z\"";
Diego Rey's avatar
Diego Rey committed
736
        } else if (grf.cod == 'N') {
737
738
            dominio += "\"baseCod\": \"N\", \"cod\": \"N\" ,";
            setf += "\"fcod\": \"N\"";
Diego Rey's avatar
Diego Rey committed
739
        } else {
740
            var nom = grf.cod;
Diego Rey's avatar
Diego Rey committed
741
            if (Array.isArray(grf.sets[0][nom])) {
742
743
                var arreglo = grf.sets[0][nom];
                var arreglo2 = [];
Diego Rey's avatar
Diego Rey committed
744
745
                for (var item of arreglo) {
                    arreglo2.push("\"" + item + "\"");
746
747
                }
                dominio += "\"baseCod\": \"N\", \"cod\": \"Numer\" ,";
Diego Rey's avatar
Diego Rey committed
748
749
750
                setf += '\"fcod\":[' + arreglo2 + ']';
            } else {
                dominio += this.recursivoCod(grf.sets, nom);
751
                setf += "\"fcod\": \"function(x)\"";
Diego Rey's avatar
Diego Rey committed
752
            }
753
754
755
756
        }
        return dominio + setf + "}}";
    }

Diego Rey's avatar
Diego Rey committed
757
    recursionfuncion = function (func, nombre) {
758
759
        var fun = func[0][nombre].set;
        var resul = "";
Diego Rey's avatar
Diego Rey committed
760
761
762
763
764
        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);

765
766
767
768
        }
        return resul;
    }

Diego Rey's avatar
Diego Rey committed
769
    recursivoDom = function (sets, nom) {
770
        var domin = "";
Diego Rey's avatar
Diego Rey committed
771
        if (sets[0][nom].set == 'R') {
772
            domin += "\"radio\": 0.3, \"baseDom\": \"R\", \"dom\": \"Func\"";
Diego Rey's avatar
Diego Rey committed
773
        } else if (sets[0][nom].set == 'Z') {
774
            domin += "\"radio\": 2, \"baseDom\": \"Z\", \"dom\": \"Func\"";
Diego Rey's avatar
Diego Rey committed
775
        } else if (sets[0][nom].set == 'N') {
776
            domin += "\"radio\": 2, \"baseDom\": \"N\", \"dom\": \"Func\"";
Diego Rey's avatar
Diego Rey committed
777
        } else {
778
            var nombre = sets[0][nom].set;
Diego Rey's avatar
Diego Rey committed
779
            domin = this.recursivoDom(sets, nombre);
780
781
782
783
        }
        return domin;
    }

Diego Rey's avatar
Diego Rey committed
784
785

    recursivoCod = function (sets, nom) {
786
        var coodo = "";
Diego Rey's avatar
Diego Rey committed
787
        if (sets[0][nom].set == 'R') {
788
            coodo += "\"baseCod\": \"R\", \"cod\": \"Func\",";
Diego Rey's avatar
Diego Rey committed
789
        } else if (sets[0][nom].set == 'Z') {
790
            coodo += "\"baseCod\": \"Z\", \"cod\": \"Func\",";
Diego Rey's avatar
Diego Rey committed
791
        } else if (sets[0][nom].set == 'N') {
792
            coodo += "\"baseCod\": \"N\", \"cod\": \"Func\",";
Diego Rey's avatar
Diego Rey committed
793
        } else {
794
            var nombre = sets[0][nom].set;
Diego Rey's avatar
Diego Rey committed
795
            coodo += this.recursivoDom(sets, nombre);
796
797
798
        }
        return coodo;
    }
Diego Rey's avatar
Diego Rey committed
799
800

    generarF = function (exp) {
801
802
        var expresion = '';
        if (exp.kind == 'cond') {
Diego Rey's avatar
Diego Rey committed
803
            expresion = ' (' + this.generarF(exp.cond) + '?' + this.generarF(exp.exp1) + ':' + this.generarF(exp.exp2) + ') ';
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
        } 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 ||  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'
819
            } else if (exp.fun == 'sin') {
820
821
822
823
824
825
826
827
828
829
                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') {
Diego Rey's avatar
Diego Rey committed
830
            expresion = ' ' + exp.var + ' ';
831
        } else {
Diego Rey's avatar
Diego Rey committed
832
            expresion = ' undefined ';
833
        }
Diego Rey's avatar
Diego Rey committed
834

835
836
837
        return expresion;
    }

Diego Rey's avatar
Diego Rey committed
838
    generarFun = function (graph) {
839
840
841
842
843
844
845
846
847
848
        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;
            }
        }
Diego Rey's avatar
Diego Rey committed
849
        funcionString = '(' + grafica.args.join() + ')=>{\n' + funcionString + '}';
850
851
852

        return funcionString;
    }
Diego Rey's avatar
Diego Rey committed
853

854

855

856
857
}