graph2D.component.ts 29.9 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
46
        data: [],
        timer: null,
        currentFrame: 0,
        speed: 1000,
        playing: false,
47
48
49
        init: false,
        boton: true,
        zoo: 2000
50
    };
51
52
    //Nuevo

Diego Rey's avatar
Diego Rey committed
53

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

                        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,
141
142
143
144
145
146
                                sampler: 'builtIn',
                                fn: function(scope) {
                                  return fun(scope.x)
                                },
                                graphType: tipoGraf,
                                color: color
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
                            });

                        }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
                            });
                        }
164
                        let bounding = this.getBounding();
165
                        console.log(bounding);
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
285
286
287
288
    }

    onClickMe(event) {
        console.log('click');
    }

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

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

356
    /**
357
358
359
360
361
362
363
364
365
366
367
368
369
370
     * @name increaseSpeed
     * @desc Increase Speed Animation
     */
    public increaseSpeed = function() {
        this.animation.speed *= 1.5;
        console.log(this.animation.speed);  
    }


    /**
     * @name toggleGrid
     * @desc Show and Hide Grid
     */
    public toggleGrid = function () {
371
        this.instance.toggleGrid();
372
373
374
375
376
377
378
    }

    /**
     * @name toggleAxis
     * @desc Show and Hide Axis
     */
    public toggleAxis = function () {
379
        this.instance.toggleAxis();
380
381
382
383
384
385
386
    }

    /**
     * @name toggleTip
     * @desc Show and Hide Tip
     */
    public toggleTip = function () {
387
        this.instance.toggleTip();
388
389
390
    }

    /**
391
392
393
394
     * @name zoomOut
     * @desc Zoom Out Button Control
     */
    public zoomOut = function () {
Diego Rey's avatar
Diego Rey committed
395
        this.instance.zoomOut();
396
    }
397
398
399
400
401
    /**
     * @name zoomIn
     * @desc Zoom In Button Control 
     */
    public zoomIn = function () {
Diego Rey's avatar
Diego Rey committed
402
403
        this.instance.zoomIn();
    }
404
405
406
407
408
409
410
411
412
413
414
415
    /**
     * @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 () {
416
417
418
        if (this.animation.playing) {
            this.stopAnimation();
        } else {
419
420
421
            this.funciones = [];
            this.conjunto = [];
            this.id = 0;
422
423
            this.instance.removeAllGraphs();
        }
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
    }

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

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
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
    /**
     * @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;
    }
508
    /**
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
     * @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;
    }
530
531
532
533
    /**
     * @name normalizeLineData
     * @desc Normalize Line data for Function Plot Library 
     * @param {Object} lineData Data of Line to be normalized
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
     * @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.color = $lineData.color;
    //     $lineNormalized.rotation = $lineData.rot;
    //     $lineNormalized.fnType = 'points';
    //     $lineNormalized.polylineType = 'line';
    //     $lineNormalized.graphType = 'polyline';
    
    //     return $lineNormalized;
    // }
551
552
553
554
    /**
     * @name normalizePolygonData
     * @desc Normalize Polygon data for Function Plot Library 
     * @param {Object} textData Data of Polygon to be normalized
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
     * @returns {Object}
     */
    // public normalizePolygonData = function ($textData) {
    //     var $PoligonNormalized: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;
    // }
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594

    /**
     * @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; 
595
596
597
598
599
600
601
602
603
                }
                // case 'line': { 
                //     normalized.push(this.normalizeLineData(shape)); 
                //     break; 
                // }
                // case 'polygon': { 
                //     normalized.push(this.normalizePolygonData(shape)); 
                //     break; 
                // } 
604
605
606
607
608
            } 
        }
        return normalized;
    }

609
610


Diego Rey's avatar
Diego Rey committed
611
    getRandomArbitrary = function (min, max) {
612
613
        return Math.round(Math.random() * (max - min) + min);
    }
Diego Rey's avatar
Diego Rey committed
614
615
616
617
618
619
620
621
622
623

    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;
624
625
            }
        }
626
        funcionString = '(' + grafica.args.join() + ')=>{\n' + funcionString + '}';
Diego Rey's avatar
Diego Rey committed
627
628
629

        return funcionString;
    }
630

Diego Rey's avatar
Diego Rey committed
631
    generarExpresion = function (exp) {
632
633
        var expresion = '';
        if (exp.kind == 'cnd') {
Diego Rey's avatar
Diego Rey committed
634
            expresion = ' (' + this.generarExpresion(exp.cond) + '?' + this.generarExpresion(exp.exp1) + ':' + this.generarExpresion(exp.exp2) + ') ';
635
        } else if (exp.kind == 'bop') {
Diego Rey's avatar
Diego Rey committed
636
            if (exp.op == '==') {
637
                expresion = ' Math.abs((' + this.generarExpresion(exp.exp1) + ') - (' + this.generarExpresion(exp.exp2) + ')) == 0 ';
Diego Rey's avatar
Diego Rey committed
638
            } else if (exp.op == '/=') {
639
                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
640
641
642
643
644
            } 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) + ') ';
            }
645
        } else if (exp.kind == 'uop') {
Diego Rey's avatar
Diego Rey committed
646
            expresion = ' ' + exp.op + ' ' + this.generarExpresion(exp.exp) + ' ';
647
        } else if (exp.kind == 'app') {
648
649
650
651
652
653
654
655
656
657
			
			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() + ') ';

658
        } else if (exp.kind == 'tup') {
Diego Rey's avatar
Diego Rey committed
659
            expresion = ' (' + exp.exps.map(e => this.generarExpresion(e)).join() + ') ';
660
        } else if (exp.kind == 'lit') {
Diego Rey's avatar
Diego Rey committed
661
            expresion = ' ' + exp.val + ' ';
662
        } else if (exp.kind == 'var') {
Diego Rey's avatar
Diego Rey committed
663
            expresion = ' ' + exp.var + ' ';
664
        } else {
Diego Rey's avatar
Diego Rey committed
665
            expresion = ' undefined ';
666
        }
Diego Rey's avatar
Diego Rey committed
667

668
669
        return expresion;
    }
670

Diego Rey's avatar
Diego Rey committed
671
    //Nuevo 20-07-2018
672
673


Diego Rey's avatar
Diego Rey committed
674
    obtenerConjunto = function (grf) {
675
676

        var setf = '\"sets\": {';
Diego Rey's avatar
Diego Rey committed
677
678
        var dominio = '{\"conj\": {';
        if (grf.dom == 'R') {
679
680
            dominio += "\"radio\": 0.3, \"baseDom\": \"R\", \"dom\": \"R\"";
            setf += "\"fdom\": \"R\",";
Diego Rey's avatar
Diego Rey committed
681
        } else if (grf.dom == 'Z') {
682
683
            dominio += "\"radio\": 2, \"baseDom\": \"Z\", \"dom\": \"Z\"";
            setf += "\"fdom\": \"Z\",";
684
        }/* else if (grf.dom == 'N') {
685
686
            dominio += "\"radio\":2, \"baseDom\": \"N\", \"dom\": \"N\"";
            setf += "\"fdom\": \"N\",";
687
        }*/ else {
688
            var nom = grf.dom;
Diego Rey's avatar
Diego Rey committed
689
            if (Array.isArray(grf.sets[0][nom])) {
690
691
                var arreglo = grf.sets[0][nom];
                var arreglo2 = [];
Diego Rey's avatar
Diego Rey committed
692
693
                for (var item of arreglo) {
                    arreglo2.push("\"" + item + "\"");
694
695
696
                }
                dominio += "\"radio\":2, \"baseDom\": \"N\", \"dom\": \"Numer\"";
                setf += "\"fdom\": [" + arreglo2 + "], ";
Diego Rey's avatar
Diego Rey committed
697
698
699
            } else {

                dominio += this.recursivoDom(grf.sets, nom);
700
                setf += "\"fdom\":\"function(x)\",";
Diego Rey's avatar
Diego Rey committed
701
            }
702
        }
Diego Rey's avatar
Diego Rey committed
703
704
        dominio += ", ";
        if (grf.cod == 'R') {
705
706
            dominio += "\"baseCod\": \"R\", \"cod\": \"R\" ,";
            setf += "\"fcod\": \"R\"";
Diego Rey's avatar
Diego Rey committed
707
        } else if (grf.cod == 'Z') {
708
709
            dominio += "\"baseCod\": \"Z\", \"cod\": \"Z\" ,";
            setf += "\"fcod\": \"Z\"";
Diego Rey's avatar
Diego Rey committed
710
        } else if (grf.cod == 'N') {
711
712
            dominio += "\"baseCod\": \"N\", \"cod\": \"N\" ,";
            setf += "\"fcod\": \"N\"";
Diego Rey's avatar
Diego Rey committed
713
        } else {
714
            var nom = grf.cod;
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
                }
                dominio += "\"baseCod\": \"N\", \"cod\": \"Numer\" ,";
Diego Rey's avatar
Diego Rey committed
722
723
724
                setf += '\"fcod\":[' + arreglo2 + ']';
            } else {
                dominio += this.recursivoCod(grf.sets, nom);
725
                setf += "\"fcod\": \"function(x)\"";
Diego Rey's avatar
Diego Rey committed
726
            }
727
728
729
730
        }
        return dominio + setf + "}}";
    }

Diego Rey's avatar
Diego Rey committed
731
    recursionfuncion = function (func, nombre) {
732
733
        var fun = func[0][nombre].set;
        var resul = "";
Diego Rey's avatar
Diego Rey committed
734
735
736
737
738
        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);

739
740
741
742
        }
        return resul;
    }

Diego Rey's avatar
Diego Rey committed
743
    recursivoDom = function (sets, nom) {
744
        var domin = "";
Diego Rey's avatar
Diego Rey committed
745
        if (sets[0][nom].set == 'R') {
746
            domin += "\"radio\": 0.3, \"baseDom\": \"R\", \"dom\": \"Func\"";
Diego Rey's avatar
Diego Rey committed
747
        } else if (sets[0][nom].set == 'Z') {
748
            domin += "\"radio\": 2, \"baseDom\": \"Z\", \"dom\": \"Func\"";
Diego Rey's avatar
Diego Rey committed
749
        } else if (sets[0][nom].set == 'N') {
750
            domin += "\"radio\": 2, \"baseDom\": \"N\", \"dom\": \"Func\"";
Diego Rey's avatar
Diego Rey committed
751
        } else {
752
            var nombre = sets[0][nom].set;
Diego Rey's avatar
Diego Rey committed
753
            domin = this.recursivoDom(sets, nombre);
754
755
756
757
        }
        return domin;
    }

Diego Rey's avatar
Diego Rey committed
758
759

    recursivoCod = function (sets, nom) {
760
        var coodo = "";
Diego Rey's avatar
Diego Rey committed
761
        if (sets[0][nom].set == 'R') {
762
            coodo += "\"baseCod\": \"R\", \"cod\": \"Func\",";
Diego Rey's avatar
Diego Rey committed
763
        } else if (sets[0][nom].set == 'Z') {
764
            coodo += "\"baseCod\": \"Z\", \"cod\": \"Func\",";
Diego Rey's avatar
Diego Rey committed
765
        } else if (sets[0][nom].set == 'N') {
766
            coodo += "\"baseCod\": \"N\", \"cod\": \"Func\",";
Diego Rey's avatar
Diego Rey committed
767
        } else {
768
            var nombre = sets[0][nom].set;
Diego Rey's avatar
Diego Rey committed
769
            coodo += this.recursivoDom(sets, nombre);
770
771
772
        }
        return coodo;
    }
Diego Rey's avatar
Diego Rey committed
773
774

    generarF = function (exp) {
775
776
        var expresion = '';
        if (exp.kind == 'cond') {
Diego Rey's avatar
Diego Rey committed
777
            expresion = ' (' + this.generarF(exp.cond) + '?' + this.generarF(exp.exp1) + ':' + this.generarF(exp.exp2) + ') ';
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
        } 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'
793
            } else if (exp.fun == 'sin') {
794
795
796
797
798
799
800
801
802
803
                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
804
            expresion = ' ' + exp.var + ' ';
805
        } else {
Diego Rey's avatar
Diego Rey committed
806
            expresion = ' undefined ';
807
        }
Diego Rey's avatar
Diego Rey committed
808

809
810
811
        return expresion;
    }

Diego Rey's avatar
Diego Rey committed
812
    generarFun = function (graph) {
813
814
815
816
817
818
819
820
821
822
        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
823
        funcionString = '(' + grafica.args.join() + ')=>{\n' + funcionString + '}';
824
825
826

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

828

829

830
831
}