graph2D.component.ts 17.7 KB
Newer Older
1
import { Component } from '@angular/core';
Diego Rey's avatar
Diego Rey committed
2
3
4
import { GHCIService } from '../../../shared/services/ghci.service';
import functionPlot from 'function-plot';

5
6
@Component({
    moduleId: module.id,
Diego Rey's avatar
Diego Rey committed
7
8
    selector: 'graph2D-component',
    templateUrl: './graph2D.component.html',
9
    host: {
Diego Rey's avatar
Diego Rey committed
10

11
12
    }
})
Diego Rey's avatar
Diego Rey committed
13
export class Graph2DComponent {
Diego Rey's avatar
Diego Rey committed
14
15
16

    private instance: {};

17
18
    public constructor(private ghciService: GHCIService) {
        ghciService.messages.subscribe(
Diego Rey's avatar
Diego Rey committed
19
20
21
            canvas => {

                if (canvas.tipo == 'graph') {
22
23
                    var jsonCanvas = JSON.parse(canvas.resultado);
                    let fun = eval(this.generarFuncion(jsonCanvas));
24
                    var conjs = this.obtenerConjunto(jsonCanvas.funs[0]);
25

Diego Rey's avatar
Diego Rey committed
26
27
                    var d = conjs + "}";

28
29
                    var obj = JSON.parse(d);
                    //Para las funciones 
Diego Rey's avatar
Diego Rey committed
30
                    if (obj.conj.sets.fdom == "function(x)") {
31
                        var nom = jsonCanvas.funs[0].dom;
Diego Rey's avatar
Diego Rey committed
32
33
                        var elemento = this.recursionfuncion(jsonCanvas.funs[0].sets, nom);
                        obj.conj.sets.fdom = function (x) { return eval(elemento) }
34
                    }
Diego Rey's avatar
Diego Rey committed
35
                    if (obj.conj.sets.fcod == "function(x)") {
36
                        var nom = jsonCanvas.funs[0].cod;
Diego Rey's avatar
Diego Rey committed
37
38
                        var elemento = this.recursionfuncion(jsonCanvas.funs[0].sets, nom);
                        obj.conj.sets.fcod = function (x) { return (eval(elemento)) }
39
40
                    }
                    //para Enumerados
Diego Rey's avatar
Diego Rey committed
41
                    if (obj.conj.dom == 'Numer') {
42
43
                        var cantElementos = obj.conj.sets.fdom.length;
                        var j = 0;
Diego Rey's avatar
Diego Rey committed
44
                        for (var fun of obj.conj.sets.fdom) {
45
46
47
48
49
                            //var newstr = nuevo2.replace(fun, j); 
                            j = j + 1;
                        }

                    }
Diego Rey's avatar
Diego Rey committed
50
                    if (obj.conj.cod == 'Numer') {
51
52
                        var cantElementos = obj.conj.sets.fcod.length;
                        var j = 0;
Diego Rey's avatar
Diego Rey committed
53
                        for (var fun of obj.conj.sets.fcod) {
54
55
56
57
58
59
                            //var newstr = nuevo2.replace(fun, j); 
                            j = j + 1;
                        }

                    }

Diego Rey's avatar
Diego Rey committed
60
61
                    var colores = ['pink', 'red', 'blue', 'orange', 'green']
                    var num = this.getRandomArbitrary(0, 4);
62
63
                    var color = colores[num];

64
65
66
67
68
69
                    var tipoGraf;
                    if (obj.conj.baseDom != 'R'){
                        tipoGraf = 'scatter';
                    }else{
                        tipoGraf = 'polyline';
                    }
Diego Rey's avatar
Diego Rey committed
70
                    this.instance = functionPlot({
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
						target: '#graph2D-container',
						width: 620,
						height: 450,
						conj:obj.conj,
						data: [{
							sampler: 'builtIn',
							fn: function(scope) {
							  return fun(scope.x)
							},
							graphType: tipoGraf,
							color: color
						}],
						plugins: [
							functionPlot.plugins.zoomBox()
						]
					})

Diego Rey's avatar
Diego Rey committed
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
                    // EXAMPLE - SHAPE
                    // this.instance = functionPlot({
                    //     target: '#graph2D-container',
                    //     width: 700,
                    //     height: 700,
                    //     xAxis: {
                    //       label: 'x - axis',
                    //       scale: 'linear',
                    //       domain: {
                    //         initial: [-10, 10],
                    //         type: 'discrete'
                    //       }
                    //     },
                    //     data: [{
                    //       shape: {
                    //         w : 6.0,
                    //         h : 3.0,
                    //         x : 0,
                    //         y : 0,
                    //         color :"red",
                    //         rotation : 0.125
                    //       },
                    //       graphType: 'shape',
                    //       shapeType: 'rect'
                    //     }],
                    //     plugins: [
                    //         functionPlot.plugins.zoomBox()
                    //     ]
                    // })
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
                } else if (canvas.tipo == 'canvas') {
                    var shapesData = JSON.parse(canvas.resultado);
                    console.log('Shapes Data:', shapesData);
                    var shapesDataNormalized = this.normalizeShapesData(shapesData);
                    console.log('Shapes Normalized', shapesDataNormalized);


                    this.instance = functionPlot({
						target: '#graph2D-container',
                        width: 800,
                        height: 700,
                        xAxis: {
                            label: 'x - axis',
                            scale: 'linear',
                            domain: {
                                initial: [-10, 10],
                                type: 'discrete'
                            }
                        },
						data: shapesDataNormalized,
						plugins: [
							functionPlot.plugins.zoomBox()
						]
					})
141
                }
Diego Rey's avatar
Diego Rey committed
142
143
144
145
146
147
            },
            error => {

            })
    }

148
149
150
151
152
    /**
     * @name zoomOut
     * @desc Zoom Out Button Control
     */
    public zoomOut = function () {
Diego Rey's avatar
Diego Rey committed
153
        this.instance.zoomOut();
154
    }
155
156
157
158
159
    /**
     * @name zoomIn
     * @desc Zoom In Button Control 
     */
    public zoomIn = function () {
Diego Rey's avatar
Diego Rey committed
160
161
        this.instance.zoomIn();
    }
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
    /**
     * @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 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; 
                } 
            } 
        }
        return normalized;
    }



Diego Rey's avatar
Diego Rey committed
258
    getRandomArbitrary = function (min, max) {
259
260
        return Math.round(Math.random() * (max - min) + min);
    }
Diego Rey's avatar
Diego Rey committed
261
262
263
264
265
266
267
268
269
270

    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;
271
272
            }
        }
Diego Rey's avatar
Diego Rey committed
273
274
275
276
        funcionString = '(' + grafica.args.join() + ',delta,hayPunto)=>{\n' + funcionString + '}';

        return funcionString;
    }
277

Diego Rey's avatar
Diego Rey committed
278
    generarExpresion = function (exp) {
279
280
        var expresion = '';
        if (exp.kind == 'cnd') {
Diego Rey's avatar
Diego Rey committed
281
            expresion = ' (' + this.generarExpresion(exp.cond) + '?' + this.generarExpresion(exp.exp1) + ':' + this.generarExpresion(exp.exp2) + ') ';
282
        } else if (exp.kind == 'bop') {
Diego Rey's avatar
Diego Rey committed
283
284
285
286
287
288
289
290
291
            if (exp.op == '==') {
                expresion = ' Math.abs((' + this.generarExpresion(exp.exp1) + ') - (' + this.generarExpresion(exp.exp2) + ')) < delta && hayPunto() ';
            } else if (exp.op == '/=') {
                expresion = ' Math.abs((' + this.generarExpresion(exp.exp1) + ') - (' + this.generarExpresion(exp.exp2) + ')) > delta ||  Math.abs((' + this.generarExpresion(exp.exp1) + ') - (' + this.generarExpresion(exp.exp2) + ')) < delta && !hayPunto()  ';
            } 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) + ') ';
            }
292
        } else if (exp.kind == 'uop') {
Diego Rey's avatar
Diego Rey committed
293
            expresion = ' ' + exp.op + ' ' + this.generarExpresion(exp.exp) + ' ';
294
        } else if (exp.kind == 'app') {
295
296
297
298
299
300
301
302
303
304
			
			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() + ') ';

305
        } else if (exp.kind == 'tup') {
Diego Rey's avatar
Diego Rey committed
306
            expresion = ' (' + exp.exps.map(e => this.generarExpresion(e)).join() + ') ';
307
        } else if (exp.kind == 'lit') {
Diego Rey's avatar
Diego Rey committed
308
            expresion = ' ' + exp.val + ' ';
309
        } else if (exp.kind == 'var') {
Diego Rey's avatar
Diego Rey committed
310
            expresion = ' ' + exp.var + ' ';
311
        } else {
Diego Rey's avatar
Diego Rey committed
312
            expresion = ' undefined ';
313
        }
Diego Rey's avatar
Diego Rey committed
314

315
316
        return expresion;
    }
317

Diego Rey's avatar
Diego Rey committed
318
    //Nuevo 20-07-2018
319
320


Diego Rey's avatar
Diego Rey committed
321
    obtenerConjunto = function (grf) {
322
323

        var setf = '\"sets\": {';
Diego Rey's avatar
Diego Rey committed
324
325
        var dominio = '{\"conj\": {';
        if (grf.dom == 'R') {
326
327
            dominio += "\"radio\": 0.3, \"baseDom\": \"R\", \"dom\": \"R\"";
            setf += "\"fdom\": \"R\",";
Diego Rey's avatar
Diego Rey committed
328
        } else if (grf.dom == 'Z') {
329
330
            dominio += "\"radio\": 2, \"baseDom\": \"Z\", \"dom\": \"Z\"";
            setf += "\"fdom\": \"Z\",";
Diego Rey's avatar
Diego Rey committed
331
        } else if (grf.dom == 'N') {
332
333
            dominio += "\"radio\":2, \"baseDom\": \"N\", \"dom\": \"N\"";
            setf += "\"fdom\": \"N\",";
Diego Rey's avatar
Diego Rey committed
334
        } else {
335
            var nom = grf.dom;
Diego Rey's avatar
Diego Rey committed
336
            if (Array.isArray(grf.sets[0][nom])) {
337
338
                var arreglo = grf.sets[0][nom];
                var arreglo2 = [];
Diego Rey's avatar
Diego Rey committed
339
340
                for (var item of arreglo) {
                    arreglo2.push("\"" + item + "\"");
341
342
343
                }
                dominio += "\"radio\":2, \"baseDom\": \"N\", \"dom\": \"Numer\"";
                setf += "\"fdom\": [" + arreglo2 + "], ";
Diego Rey's avatar
Diego Rey committed
344
345
346
            } else {

                dominio += this.recursivoDom(grf.sets, nom);
347
                setf += "\"fdom\":\"function(x)\",";
Diego Rey's avatar
Diego Rey committed
348
            }
349
        }
Diego Rey's avatar
Diego Rey committed
350
351
        dominio += ", ";
        if (grf.cod == 'R') {
352
353
            dominio += "\"baseCod\": \"R\", \"cod\": \"R\" ,";
            setf += "\"fcod\": \"R\"";
Diego Rey's avatar
Diego Rey committed
354
        } else if (grf.cod == 'Z') {
355
356
            dominio += "\"baseCod\": \"Z\", \"cod\": \"Z\" ,";
            setf += "\"fcod\": \"Z\"";
Diego Rey's avatar
Diego Rey committed
357
        } else if (grf.cod == 'N') {
358
359
            dominio += "\"baseCod\": \"N\", \"cod\": \"N\" ,";
            setf += "\"fcod\": \"N\"";
Diego Rey's avatar
Diego Rey committed
360
        } else {
361
            var nom = grf.cod;
Diego Rey's avatar
Diego Rey committed
362
            if (Array.isArray(grf.sets[0][nom])) {
363
364
                var arreglo = grf.sets[0][nom];
                var arreglo2 = [];
Diego Rey's avatar
Diego Rey committed
365
366
                for (var item of arreglo) {
                    arreglo2.push("\"" + item + "\"");
367
368
                }
                dominio += "\"baseCod\": \"N\", \"cod\": \"Numer\" ,";
Diego Rey's avatar
Diego Rey committed
369
370
371
                setf += '\"fcod\":[' + arreglo2 + ']';
            } else {
                dominio += this.recursivoCod(grf.sets, nom);
372
                setf += "\"fcod\": \"function(x)\"";
Diego Rey's avatar
Diego Rey committed
373
            }
374
375
376
377
        }
        return dominio + setf + "}}";
    }

Diego Rey's avatar
Diego Rey committed
378
    recursionfuncion = function (func, nombre) {
379
380
        var fun = func[0][nombre].set;
        var resul = "";
Diego Rey's avatar
Diego Rey committed
381
382
383
384
385
        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);

386
387
388
389
        }
        return resul;
    }

Diego Rey's avatar
Diego Rey committed
390
    recursivoDom = function (sets, nom) {
391
        var domin = "";
Diego Rey's avatar
Diego Rey committed
392
        if (sets[0][nom].set == 'R') {
393
            domin += "\"radio\": 0.3, \"baseDom\": \"R\", \"dom\": \"Func\"";
Diego Rey's avatar
Diego Rey committed
394
        } else if (sets[0][nom].set == 'Z') {
395
            domin += "\"radio\": 2, \"baseDom\": \"Z\", \"dom\": \"Func\"";
Diego Rey's avatar
Diego Rey committed
396
        } else if (sets[0][nom].set == 'N') {
397
            domin += "\"radio\": 2, \"baseDom\": \"N\", \"dom\": \"Func\"";
Diego Rey's avatar
Diego Rey committed
398
        } else {
399
            var nombre = sets[0][nom].set;
Diego Rey's avatar
Diego Rey committed
400
            domin = this.recursivoDom(sets, nombre);
401
402
403
404
        }
        return domin;
    }

Diego Rey's avatar
Diego Rey committed
405
406

    recursivoCod = function (sets, nom) {
407
        var coodo = "";
Diego Rey's avatar
Diego Rey committed
408
        if (sets[0][nom].set == 'R') {
409
            coodo += "\"baseCod\": \"R\", \"cod\": \"Func\",";
Diego Rey's avatar
Diego Rey committed
410
        } else if (sets[0][nom].set == 'Z') {
411
            coodo += "\"baseCod\": \"Z\", \"cod\": \"Func\",";
Diego Rey's avatar
Diego Rey committed
412
        } else if (sets[0][nom].set == 'N') {
413
            coodo += "\"baseCod\": \"N\", \"cod\": \"Func\",";
Diego Rey's avatar
Diego Rey committed
414
        } else {
415
            var nombre = sets[0][nom].set;
Diego Rey's avatar
Diego Rey committed
416
            coodo += this.recursivoDom(sets, nombre);
417
418
419
        }
        return coodo;
    }
Diego Rey's avatar
Diego Rey committed
420
421

    generarF = function (exp) {
422
423
        var expresion = '';
        if (exp.kind == 'cond') {
Diego Rey's avatar
Diego Rey committed
424
            expresion = ' (' + this.generarF(exp.cond) + '?' + this.generarF(exp.exp1) + ':' + this.generarF(exp.exp2) + ') ';
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
        } 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'
440
            } else if (exp.fun == 'sin') {
441
442
443
444
445
446
447
448
449
450
                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
451
            expresion = ' ' + exp.var + ' ';
452
        } else {
Diego Rey's avatar
Diego Rey committed
453
            expresion = ' undefined ';
454
        }
Diego Rey's avatar
Diego Rey committed
455

456
457
458
        return expresion;
    }

Diego Rey's avatar
Diego Rey committed
459
    generarFun = function (graph) {
460
461
462
463
464
465
466
467
468
469
        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
470
        funcionString = '(' + grafica.args.join() + ')=>{\n' + funcionString + '}';
471
472
473

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

475
476
}