Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • matefun/Frontend
  • felipe.parodi/Frontend
2 results
Show changes
Showing
with 2854 additions and 1566 deletions
File mode changed from 100644 to 100755
File mode changed from 100644 to 100755
import { Component, OnInit, Input } from '@angular/core';
import { Component, OnInit, Input } from "@angular/core";
@Component({
selector: 'animation-control',
templateUrl: './animation-control.component.html',
styleUrls: ['./animation-control.component.scss']
selector: "animation-control",
templateUrl: "./animation-control.component.html",
styleUrls: ["./animation-control.component.scss"],
})
export class AnimationControlComponent implements OnInit {
@Input() visible: boolean;
@Input() playing: boolean;
......@@ -18,9 +17,7 @@ export class AnimationControlComponent implements OnInit {
@Input() onTogglePlay: Function;
@Input() onChangeSpeed: Function;
constructor() { }
ngOnInit() {
}
constructor() {}
ngOnInit() {}
}
<!-- Buttons Controls -->
<div class="buttons-control">
<button ngbPopover="Zoom +"
class="btn btn-sm btn-secondary btn-zoom-increase"
data-placement="bottom"
triggers="mouseenter:mouseleave"
(click)=zoomIn() >
<i class="fa fa-plus"></i>
</button>
<button ngbPopover="Zoom -"
class="btn btn-sm btn-secondary btn-zoom-decrease"
data-placement="bottom"
triggers="mouseenter:mouseleave"
(click)=zoomOut() >
<i class="fa fa-minus"></i>
</button>
<button ngbPopover="Centrar"
class="btn btn-sm btn-secondary btn-zoom-center"
data-placement="bottom"
triggers="mouseenter:mouseleave"
(click)="recenterPlot()" >
<i class="fa fa-arrows"></i>
</button>
<button ngbPopover="Borrar"
class="btn btn-sm btn-secondary btn-trash"
data-placement="bottom"
triggers="mouseenter:mouseleave"
(click)="cleanPlot()" >
<i class="fa fa-trash"></i>
</button>
<button ngbPopover="Descargar PNG"
class="btn btn-sm btn-secondary btn-download"
data-placement="bottom"
triggers="mouseenter:mouseleave"
(click)=exportPlot() >
<i class="fa fa-download"></i>
</button>
<button id="settings"
class="btn btn-sm btn-secondary btn-setting"
placement="bottom"
closePopoverDirective
[ngbPopover]=popoverCanvas
popoverTitle="Configuración"
#popover="ngbPopover"
tiggers="click">
<i class="fa fa-gear"></i>
</button>
<button
ngbPopover="{{ 'i18n.action.zoom' | translate | titleCase }} +"
class="btn btn-sm btn-secondary btn-zoom-increase"
placement="bottom"
triggers="mouseenter:mouseleave"
(click)="zoomIn()"
>
<i class="fa fa-plus"></i>
</button>
<button
ngbPopover="{{ 'i18n.action.zoom' | translate | titleCase }} -"
class="btn btn-sm btn-secondary btn-zoom-decrease"
placement="bottom"
triggers="mouseenter:mouseleave"
(click)="zoomOut()"
>
<i class="fa fa-minus"></i>
</button>
<button
ngbPopover="{{ 'i18n.action.center' | translate | titleCase }}"
class="btn btn-sm btn-secondary btn-zoom-center"
placement="bottom"
triggers="mouseenter:mouseleave"
(click)="recenterPlot()"
>
<i class="fa fa-arrows"></i>
</button>
<button
ngbPopover="{{ 'i18n.action.delete' | translate | titleCase }}"
class="btn btn-sm btn-secondary btn-trash"
placement="bottom"
triggers="mouseenter:mouseleave"
(click)="cleanPlot()"
>
<i class="fa fa-trash"></i>
</button>
<button
ngbPopover="{{ 'i18n.action.download' | translate | titleCase }} PNG"
class="btn btn-sm btn-secondary btn-download"
placement="bottom"
triggers="mouseenter:mouseleave"
(click)="exportPlot()"
>
<i class="fa fa-download"></i>
</button>
<button
id="settings"
class="btn btn-sm btn-secondary btn-setting"
placement="bottom"
closePopoverDirective
[autoClose]="'outside'"
[ngbPopover]="popoverCanvas"
popoverTitle="{{ 'i18n.object.settings' | translate | titleCase }}"
#popover="ngbPopover"
tiggers="click"
>
<i class="fa fa-gear"></i>
</button>
</div>
<div class="card">
<div class="card-block contenedor-canvas" >
<!-- Download Link -->
<a id="download-plot" class="download-plot" href="#" download="Plot.svg" style="display: none">
Download Canvas
</a>
<div class="card-block contenedor-canvas">
<!-- Download Link -->
<a
id="download-plot"
class="download-plot"
href="#"
download="Plot.svg"
style="display: none"
>
Download Canvas
</a>
<!-- Settings Popover Content -->
<ng-template #popoverCanvas>
<div class="form-group settings-popover-content">
<div class="chart-controls setting-section">
<label>
<input
type="checkbox"
name="grid"
class="form-control form-control-sm"
[checked]= settings.grid
(click)="toggleGrid()">
Grilla
</label>
<label>
<input
type="checkbox"
name="axis"
class="form-control form-control-sm"
[checked]= settings.axis
(click)="toggleAxis()">
Ejes
</label>
<label>
<!-- Settings Popover Content -->
<ng-template #popoverCanvas>
<div class="form-group settings-popover-content">
<div class="chart-controls setting-section">
<label>
<input
type="checkbox"
name="grid"
class="form-control form-control-sm"
[checked]="settings.grid"
(click)="toggleGrid()"
/>
{{ "i18n.object.grid" | translate | titleCase }}
</label>
<label>
<input
type="checkbox"
name="axis"
class="form-control form-control-sm"
[checked]="settings.axis"
(click)="toggleAxis()"
/>
{{ "i18n.object.axes" | translate | titleCase }}
</label>
<!-- <label>
<input
type="checkbox"
name="tip"
class="form-control form-control-sm"
[checked]= settings.tip
(click)="toggleTip()">
Tip
</label>
<label [class.disabled]="funciones.length === 0">
<input
type="checkbox"
[attr.disabled]="funciones.length === 0 ? '' : null"
[checked]=animation.boton
(click)="multiGraf(value)">
Multi gráfica
</label>
</div>
<hr>
<div class="zoom-control setting-section">
<div [class.disabled]="funciones.length === 0" style="display: flex;">
<span style="margin-right: 8px; align-self: center;">
Zoom
</span>
<input
type="number"
class="form-control form-control-sm"
[attr.disabled]="funciones.length === 0 ? '' : null"
[(ngModel)]="animation.zoo"
[max]="1000000"
[min]="8"
(change)="setZoom()"
style="width: 70px;"
/>
</div>
</div>
<hr>
<div class="animation-controls setting-section"
[class.disabled]="animation.data.length === 0">
<label>Velocidad de animación:</label>
<div>
<button class="btn btn-sm btn-secondary"
[attr.disabled]="animation.data.length === 0 ? '' : null"
(click)='decreaseSpeed()'>
<i class="fa fa-minus"></i>
</button>
<button class="btn btn-sm btn-secondary"
[attr.disabled]="animation.data.length === 0 ? '' : null"
(click)='restoreSpeed()'>
<span>1x</span>
</button>
<button class="btn btn-sm btn-secondary"
[attr.disabled]="animation.data.length === 0 ? '' : null"
(click)='increaseSpeed()'>
<i class="fa fa-plus"></i>
</button>
<span class="speed-value">
{{animation.speedX | number:'1.0'}}x
</span>
</div>
</div>
</div>
</ng-template>
<!-- Animation -->
<div class="animation" *ngIf="animation.data.length>0">
<button class="btn btn-sm btn-secondary btn-play"
data-placement="bottom"
*ngIf="!animation.playing"
(click)="runAnimation()" >
<i class="fa fa-play"></i>
</button>
<button class="btn btn-sm btn-secondary btn-pause"
data-placement="bottom"
*ngIf="animation.playing"
(click)="pauseAnimation()" >
<i class="fa fa-pause"></i>
</button>
{{ "i18n.object.tip" | translate | titleCase }}
</label> -->
<label [class.disabled]="funciones.length === 0">
<input
type="checkbox"
[attr.disabled]="funciones.length === 0 ? '' : null"
[checked]="animation.boton"
(click)="multiGraf(value)"
/>
{{ "i18n.msg.figure.multiPlot" | translate | titleCase }}
</label>
</div>
<hr />
<div class="zoom-control setting-section">
<div [class.disabled]="funciones.length === 0" style="display: flex">
<span style="margin-right: 8px; align-self: center">
{{ "i18n.action.zoom" | translate | titleCase }}
</span>
<input
type="number"
class="form-control form-control-sm"
[attr.disabled]="funciones.length === 0 ? '' : null"
[(ngModel)]="animation.zoo"
[max]="1000000"
[min]="8"
(change)="setZoom()"
style="width: 70px"
/>
</div>
</div>
<hr />
<div
class="animation-controls setting-section"
[class.disabled]="animation.data.length === 0"
>
<label>{{ "i18n.msg.figure.animationSpeed" | translate }}:</label>
<div>
<button
class="btn btn-sm btn-secondary"
[attr.disabled]="animation.data.length === 0 ? '' : null"
(click)="decreaseSpeed()"
>
<i class="fa fa-minus"></i>
</button>
<button
class="btn btn-sm btn-secondary"
[attr.disabled]="animation.data.length === 0 ? '' : null"
(click)="restoreSpeed()"
>
<span>1x</span>
</button>
<button
class="btn btn-sm btn-secondary"
[attr.disabled]="animation.data.length === 0 ? '' : null"
(click)="increaseSpeed()"
>
<i class="fa fa-plus"></i>
</button>
<span class="speed-value">
{{ animation.speedX | number: "1.0" }}x
</span>
</div>
</div>
</div>
</ng-template>
<ngb-progressbar
class="progressbar"
type="info"
[value]="((animation.currentFrame+1)/animation.data.length)*100">
</ngb-progressbar>
</div>
<!-- Animation -->
<div class="animation" *ngIf="animation.data.length > 0">
<button
class="btn btn-sm btn-secondary btn-play"
placement="bottom"
*ngIf="!animation.playing"
(click)="runAnimation()"
>
<i class="fa fa-play"></i>
</button>
<button
class="btn btn-sm btn-secondary btn-pause"
placement="bottom"
*ngIf="animation.playing"
(click)="pauseAnimation()"
>
<i class="fa fa-pause"></i>
</button>
<!-- Graph Container -->
<div #graph2DContainer id="graph2D-container">
</div>
<ngb-progressbar
class="progressbar"
type="info"
[value]="((animation.currentFrame + 1) / animation.data.length) * 100"
>
</ngb-progressbar>
</div>
</div>
\ No newline at end of file
<!-- Graph Container -->
<div #graph2DContainer id="graph2D-container"></div>
</div>
</div>
// Buttons Control
.buttons-control {
.btn-zoom-increase, .btn-zoom-decrease, .btn-zoom-center, .btn-trash, .btn-download, .btn-setting {
float: right;
margin-top: -34px;
}
.btn-zoom-increase {
margin-right: 165px;
}
.btn-zoom-decrease {
margin-right: 132px;
}
.btn-zoom-center {
margin-right: 99px;
}
.btn-trash {
margin-right: 66px;
}
.btn-download {
margin-right: 33px;
}
display: flex;
justify-content: flex-end;
margin-top: -43px;
margin-bottom: 16px;
}
// Settings Popover
.settings-popover-content {
width: 12em;
label {
display: block;
&.disabled {
color: #ccc;
}
width: 12em;
label {
display: block;
&.disabled {
color: #ccc;
}
input[type="checkbox"] {
width: 15px;
display: inline-block;
}
input[type="checkbox"] {
width: 15px;
display: inline-block;
}
.setting-section {
margin-bottom: 1em;
}
.animation-controls {
.speed-value {
margin-left: 0.5em;
font-weight: 900;
font-size: 1.2em;
vertical-align: middle;
}
.setting-section {
margin-bottom: 1em;
&.disabled {
color: #ccc;
i.fa,
span {
color: #ccc;
}
}
.animation-controls {
.speed-value {
margin-left: 0.5em;
font-weight: 900;
font-size: 1.2em;
vertical-align: middle;
}
&.disabled {
color: #ccc;
i.fa, span {
color: #ccc;
}
}
}
.zoom-control {
&>.disabled {
color: #ccc;
}
}
.zoom-control {
& > .disabled {
color: #ccc;
}
}
}
// Animation
.animation {
.btn-play, .btn-pause {
float:left;
margin-top: -5px;
margin-right: 5px;
}
.progressbar {
float: left;
width: 90%;
}
.btn-play,
.btn-pause {
float: left;
margin-top: -5px;
margin-right: 5px;
}
.progressbar {
float: left;
width: 90%;
}
}
#graph2D-container {
height: 100%;
width: 100%;
height: 100%;
width: 100%;
}
import { Component, ViewChild, ElementRef } from '@angular/core';
import { GHCIService } from '../../../shared/services/ghci.service';
import functionPlot from 'function-plot';
import { Animation, Setting, toJSON, triggerDownload } from './graph2D.helper';
import { Component, ViewChild, ElementRef } from "@angular/core";
import { GHCIService } from "../../../shared/services/ghci.service";
import * as functionPlot from "function-plot";
import { Animation, Setting, toJSON, triggerDownload } from "./graph2D.helper";
import { TranslateService } from "@ngx-translate/core";
@Component({
moduleId: module.id,
selector: 'graph2D-component',
templateUrl: './graph2D.component.html',
styleUrls: ['./graph2D.component.scss'],
host: {
'(window:resize)': 'onResize($event)'
}
selector: "graph2D-component",
templateUrl: "./graph2D.component.html",
styleUrls: ["./graph2D.component.scss"],
host: {
"(window:resize)": "onResize($event)",
},
})
export class Graph2DComponent {
// Ghci Service
private ghciServiceSub: any;
// Chart Container - DOM Element
@ViewChild("graph2DContainer", { static: true })
private graph2DRef: ElementRef;
// Chart Instance
private instance: any;
// Settings
settings: Setting = {
axis: true,
grid: true,
tip: true,
};
private funciones = [];
private id = 0;
private valores = [];
private conjunto = [];
// Animation state
animation: Animation = {
data: [],
init: false,
currentFrame: 0,
fps: 10,
playing: false,
timeout: null,
animationFrame: null,
speedX: 10,
boton: true,
zoo: 2000,
};
//Nuevo
public easeInOutCubic = function (fps) {
var t = fps < 6 ? 6 : fps;
var k = t / 60;
var animation =
k < 0.5
? 60 * (4 * k * k * k)
: 60 * ((k - 1) * (2 * k - 2) * (2 * k - 2) + 1);
console.log(animation);
return animation;
};
public setZoom = () => {
this.animation.zoo = this.animation.zoo;
};
public multiGraf = () => {
this.animation.boton = !this.animation.boton;
};
public constructor(
private ghciService: GHCIService,
public translate: TranslateService
) {
this.ghciServiceSub = ghciService.messages.subscribe(
(canvas) => {
// Stop Animation
if (this.animation.init) {
this.stopAnimation();
}
switch (canvas.tipo) {
case "graph": {
console.log(canvas.resultado);
// var jsonCanvas = JSON.parse(JSONRepair(canvas.resultado));
// Ghci Service
private ghciServiceSub: any;
// Chart Container - DOM Element
@ViewChild('graph2DContainer')
private graph2DRef: ElementRef;
// Chart Instance
private instance: any;
var jsonCanvas = JSON.parse(canvas.resultado);
var conjs = this.obtenerConjunto(jsonCanvas.funs[0]);
// Settings
settings: Setting = {
axis: true,
grid: true,
tip: true
}
var d = conjs + "}"; //Leo
private funciones= [];
var obj = JSON.parse(d);
private id = 0;
if (obj.conj.baseDom == "Error" || obj.conj.baseCod == "Error") {
break;
}
private conjunto= [];
//Para las funciones
if (obj.conj.sets.fdom == "function(x)") {
var nom = jsonCanvas.funs[0].dom;
var elemento1 = this.recursionfuncion(
jsonCanvas.funs[0].sets,
nom
);
var funcionString = "";
funcionString =
"var " + nom + " = function(x){\nreturn " + elemento1 + "}\n";
funcionString += "return " + nom + "(x);\n";
for (var funs of jsonCanvas.funs) {
funcionString =
"var " +
funs.fun +
" = function(" +
funs.args +
"){\n return " +
this.generarExpresion(funs.bdy) +
"}\n" +
funcionString;
}
funcionString = "(x)=>{\n" + funcionString + "}";
console.log(funcionString);
obj.conj.sets.fdom = eval(funcionString);
}
if (obj.conj.sets.fcod == "function(x)") {
var nom = jsonCanvas.funs[0].cod;
var elemento2 = this.recursionfuncionCod(
jsonCanvas.funs[0].sets,
nom
);
console.log(elemento2);
obj.conj.sets.fcod = function (x) {
return eval(elemento2);
};
var funcionString = "";
funcionString =
"var " + nom + " = function(x){\nreturn " + elemento2 + "}\n";
funcionString += "return " + nom + "(x);\n";
for (var funs of jsonCanvas.funs) {
funcionString =
"var " +
funs.fun +
" = function(" +
funs.args +
"){\n return " +
this.generarExpresion(funs.bdy) +
"}\n" +
funcionString;
}
funcionString = "(x)=>{\n" + funcionString + "}";
obj.conj.sets.fdom = eval(funcionString);
}
// Animation state
animation: Animation = {
data: [],
init: false,
currentFrame: 0,
fps: 10,
playing: false,
timeout: null,
animationFrame: null,
speedX: 10,
boton: true,
zoo: 2000
};
//Nuevo
public easeInOutCubic = function(fps) {
var t = fps < 6 ? 6 : fps;
var k = t/60;
var animation = k<.5 ? 60*(4*k*k*k) : 60*((k-1)*(2*k-2)*(2*k-2)+1);
console.log(animation);
return animation;
}
var funcionGenerada = this.generarFuncion(jsonCanvas);
//para Enumerados
if (obj.conj.dom == "Numer") {
var j = 0;
for (var f of obj.conj.sets.fdom) {
var expresionDom = new RegExp("( " + f + " )", "g");
funcionGenerada = funcionGenerada.replace(
expresionDom,
j.toString()
);
j += 1;
}
}
if (obj.conj.cod == "Numer") {
var j2 = 0;
for (var f2 of obj.conj.sets.fcod) {
var expresionCod = new RegExp(f2, "g");
funcionGenerada = funcionGenerada.replace(
expresionCod,
j2.toString()
);
j2 += 1;
}
}
public setZoom = () => {
this.animation.zoo = this.animation.zoo ;
}
public multiGraf = () => {
this.animation.boton = !this.animation.boton;
}
public constructor(private ghciService: GHCIService) {
this.ghciServiceSub = ghciService.messages.subscribe(
canvas => {
// Stop Animation
if (this.animation.init) {
this.stopAnimation();
}
switch(canvas.tipo) {
case 'graph': {
var jsonCanvas = JSON.parse(canvas.resultado);
var conjs = this.obtenerConjunto(jsonCanvas.funs[0]);
var d = conjs + "}"; //Leo
var obj = JSON.parse(d);
//Para las funciones
if (obj.conj.sets.fdom == "function(x)") {
var nom = jsonCanvas.funs[0].dom;
var elemento1 = this.recursionfuncion(jsonCanvas.funs[0].sets, nom);
obj.conj.sets.fdom = function (x) { return eval(elemento1) }
}
if (obj.conj.sets.fcod == "function(x)") {
var nom = jsonCanvas.funs[0].cod;
var elemento2 = this.recursionfuncion(jsonCanvas.funs[0].sets, nom);
obj.conj.sets.fcod = function (x) { return (eval(elemento2)) }
}
if (obj.conj.baseDom == "R") {
obj.conj.baseCod = "R";
if (obj.conj.cod != "Func") {
obj.conj.cod = "R";
obj.conj.fcod = "R";
}
}
var funcionGenerada = this.generarFuncion(jsonCanvas);
console.log(obj)
//para Enumerados
if (obj.conj.dom == 'Numer') {
var j = 0;
for (var f of obj.conj.sets.fdom) {
var expresionDom = new RegExp('( '+f+' )', 'g');
funcionGenerada = funcionGenerada.replace(expresionDom, j.toString());
j += 1;
}
}
if (obj.conj.cod == 'Numer') {
var j2 = 0;
for (var f2 of obj.conj.sets.fcod) {
var expresionCod = new RegExp(f2, 'g');
funcionGenerada = funcionGenerada.replace(expresionCod, j2.toString());
j2 += 1;
}
let fun = eval(funcionGenerada);
}
var colores = ["violet", "red", "blue", "orange", "green", "black"];
var num = this.getRandomArbitrary(0, 5);
var color = colores[num];
let fun = eval(funcionGenerada);
var colores = ['pink', 'red', 'blue', 'orange', 'green']
var num = this.getRandomArbitrary(0, 4);
var color = colores[num];
var tipoGraf;
if (obj.conj.baseDom != 'R'){
tipoGraf = 'scatter';
}else{
tipoGraf = 'polyline';
}
if(this.animation.boton && obj.conj.cod != 'Numer' && obj.conj.dom != 'Numer'){
if(this.conjunto.length == 1 && (this.conjunto[0].cod == 'Numer' || this.conjunto[0].dom == 'Numer')){
this.conjunto = [];
this.conjunto.push(obj.conj);
this.id = 0;
this.funciones = [];
this.funciones.push({
id: this.funciones.length,
sampler: 'builtIn',
fn: function(scope) {
return fun(scope.x)
},
graphType: tipoGraf,
color: color
})
}else{
if(this.conjunto.length == 1){
this.id = 1;
this.conjunto.unshift({radio: 2, dom:this.conjunto[0].baseDom, cod:this.conjunto[0].baseCod, baseCod:this.conjunto[0].baseCod, baseDom:this.conjunto[0].baseDom, sets:{fdom:this.conjunto[0].baseDom,fcod:this.conjunto[0].baseCod}});
this.funciones[0].id = this.id;
}
if (this.conjunto.length != 0){
if (obj.conj.baseDom == 'R'){
this.conjunto[0].baseDom = 'R';
this.conjunto[0].dom = 'R';
this.conjunto[0].sets.fdom = 'R';
}
if (obj.conj.baseCod == 'R'){
this.conjunto[0].baseCod = 'R';
this.conjunto[0].cod = 'R';
this.conjunto[0].sets.fcod = 'R';
}
}
this.conjunto.push(obj.conj);
this.funciones.push({
id: this.funciones.length + this.id,
sampler: 'builtIn',
fn: function(scope) {
return fun(scope.x)
},
graphType: tipoGraf,
color: color
});
}
}else{
this.conjunto = [];
this.conjunto.push(obj.conj);
this.id = 0;
this.funciones = [];
this.funciones.push({
id: this.funciones.length,
sampler: 'builtIn',
fn: function(scope) {
return fun(scope.x)
},
graphType: tipoGraf,
color: color
});
var tipoGraf;
if (obj.conj.baseDom != "R") {
tipoGraf = "scatter";
} else {
tipoGraf = "polyline";
}
if (
this.animation.boton &&
obj.conj.cod != "Numer" &&
obj.conj.dom != "Numer"
) {
if (
this.conjunto.length == 1 &&
(this.conjunto[0].cod == "Numer" ||
this.conjunto[0].dom == "Numer")
) {
this.conjunto = [];
this.conjunto.push(obj.conj);
this.id = 0;
this.funciones = [];
if (obj.conj.baseDom == "R") {
this.valores = [];
var funcionGenerada2 = this.generarFuncionDisc(jsonCanvas);
var funcionesVer2019 = this.createListFunction(jsonCanvas);
var listValores = [];
for (var k of this.valores) {
listValores.push(parseInt(k));
}
for (var i of this.valores) {
for (var t of this.valores) {
var aux = parseInt(t);
var aux2 = parseInt(i);
var mul = aux * aux2;
listValores.push(mul);
}
}
for (i = -999; i < 1000; i++) {
listValores.push(i);
}
let sinRepetidos = listValores.filter(
(valor, indiceActual, arreglo) =>
arreglo.indexOf(valor) === indiceActual
);
for (var fun2 of funcionesVer2019) {
let fun3 = eval(fun2);
var insertar = false;
var punto1 = [];
if (sinRepetidos.length) {
for (var p of sinRepetidos) {
var pn = parseInt(p) - 0.001;
var pp = parseInt(p) + 0.001;
insertar =
fun3(pp) != undefined ||
fun3(pn) != undefined ||
insertar;
if (fun3(pp) != undefined) {
punto1.push(pp);
} else if (fun3(pn) != undefined) {
punto1.push(p);
}
let bounding = this.getBounding();
this.instance = functionPlot({
target: '#graph2D-container',
width: bounding.width,
height: bounding.height,
tip: {
color: 'green'
},
xAxis: {
scale: 'linear',
domain: { initial: [-4, 4],
type: 'discrete' },
yAxis: { domain: [-4, 4] }
},
conj:this.conjunto,
data: this.funciones,
zoom:this.animation.zoo,
plugins: [
functionPlot.plugins.zoomBox()
]
})
break;
}
} else {
insertar = true;
}
case 'canvas': {
var shapesData = JSON.parse(canvas.resultado);
var shapesDataNormalized = this.normalizeShapesData(shapesData);
let bounding = this.getBounding();
this.cleanPlot();
this.instance = functionPlot({
target: '#graph2D-container',
width: bounding.width,
height: bounding.height,
grid: true,
xAxis: {
scale: 'linear',
domain: {
initial: [-10, 10],
type: 'discrete'
}
},
data: shapesDataNormalized,
plugins: [
functionPlot.plugins.zoomBox()
]
})
break;
if (insertar) {
console.log("A");
this.funciones.push({
id: 0,
sampler: "builtIn",
fn: function (scope) {
return fun3(scope.x);
},
graphType: tipoGraf,
point: punto1[0],
color: color,
});
}
}
} else {
console.log("B");
this.funciones.push({
id: this.funciones.length,
sampler: "builtIn",
fn: function (scope) {
return fun(scope.x);
},
graphType: tipoGraf,
color: color,
});
}
} else {
if (this.conjunto.length == 1) {
this.id = 1;
this.conjunto.unshift({
radio: 2,
dom: this.conjunto[0].baseDom,
cod: this.conjunto[0].baseCod,
baseCod: this.conjunto[0].baseCod,
baseDom: this.conjunto[0].baseDom,
sets: {
fdom: this.conjunto[0].baseDom,
fcod: this.conjunto[0].baseCod,
},
});
this.funciones[0].id = this.id;
}
if (this.conjunto.length != 0) {
if (obj.conj.baseDom == "R") {
this.conjunto[0].baseDom = "R";
this.conjunto[0].dom = "R";
this.conjunto[0].sets.fdom = "R";
}
if (obj.conj.baseCod == "R") {
this.conjunto[0].baseCod = "R";
this.conjunto[0].cod = "R";
this.conjunto[0].sets.fcod = "R";
}
}
this.conjunto.push(obj.conj);
var identificador = 0;
if (this.conjunto.length > 1) {
identificador = this.conjunto.length - 2 + this.id;
}
if (obj.conj.baseDom == "R") {
this.valores = [];
var funcionGenerada2 = this.generarFuncionDisc(jsonCanvas);
var funcionesVer2019 = this.createListFunction(jsonCanvas);
var listValores = [];
for (var k of this.valores) {
listValores.push(parseInt(k));
}
for (var i of this.valores) {
for (var t of this.valores) {
var aux = parseInt(t);
var aux2 = parseInt(i);
var mul = aux * aux2;
listValores.push(mul);
}
case 'animacion': {
this.cleanPlot();
var animationData = canvas.resultado.map(res => JSON.parse(res));
for (var frame of animationData) {
this.animation.data.push(this.normalizeShapesData(frame));
}
for (i = -999; i < 1000; i++) {
listValores.push(i);
}
let sinRepetidos = listValores.filter(
(valor, indiceActual, arreglo) =>
arreglo.indexOf(valor) === indiceActual
);
for (var fun2 of funcionesVer2019) {
let fun3 = eval(fun2);
var insertar = false;
var punto1 = [];
if (sinRepetidos.length) {
for (var p of sinRepetidos) {
var pn = parseInt(p) - 0.001;
var pp = parseInt(p) + 0.001;
insertar =
fun3(pp) != undefined ||
fun3(pn) != undefined ||
insertar;
if (fun3(pp) != undefined) {
punto1.push(pp);
} else if (fun3(pn) != undefined) {
punto1.push(p);
}
this.runAnimation();
this.animation.init = true;
break;
}
} else {
insertar = true;
}
if (insertar) {
console.log(fun3);
this.funciones.push({
id: identificador,
sampler: "builtIn",
fn: function (scope) {
return fun3(scope.x);
},
graphType: tipoGraf,
point: punto1[0],
color: color,
});
}
}
} else {
console.log("D");
this.funciones.push({
id: identificador,
sampler: "builtIn",
fn: function (scope) {
return fun(scope.x);
},
graphType: tipoGraf,
color: color,
});
}
}
} else {
this.conjunto = [];
this.conjunto.push(obj.conj);
this.id = 0;
this.funciones = [];
if (obj.conj.baseDom == "R") {
this.valores = [];
var funcionGenerada2 = this.generarFuncionDisc(jsonCanvas);
var funcionesVer2019 = this.createListFunction(jsonCanvas);
var listValores = [];
for (var k of this.valores) {
listValores.push(parseInt(k));
}
for (var i of this.valores) {
for (var t of this.valores) {
var aux = parseInt(t);
var aux2 = parseInt(i);
var mul = aux * aux2;
listValores.push(mul);
}
}
for (i = -999; i < 1000; i++) {
listValores.push(i);
}
},
error => {
let sinRepetidos = listValores.filter(
(valor, indiceActual, arreglo) =>
arreglo.indexOf(valor) === indiceActual
);
for (var fun2 of funcionesVer2019) {
let fun3 = eval(fun2);
var insertar = false;
var punto1 = [];
if (sinRepetidos.length) {
for (var p of sinRepetidos) {
var pn = parseInt(p) - 0.001;
var pp = parseInt(p) + 0.001;
insertar =
fun3(pp) != undefined ||
fun3(pn) != undefined ||
insertar;
if (fun3(pp) != undefined) {
punto1.push(pp);
} else if (fun3(pn) != undefined) {
punto1.push(p);
}
}
} else {
insertar = true;
}
if (insertar) {
this.funciones.push({
id: 0,
sampler: "builtIn",
fn: function (scope) {
return fun3(scope.x);
},
graphType: tipoGraf,
point: punto1[0],
color: color,
});
}
}
} else {
this.funciones.push({
id: this.funciones.length,
sampler: "builtIn",
fn: function (scope) {
return fun(scope.x);
},
graphType: tipoGraf,
color: color,
});
}
}
)
}
/**
* Angular lifecycle hook.
* called after Angular has fully initialized a component's view.
*/
ngAfterViewInit() {
if (!this.instance) {
let bounding = this.getBounding();
this.instance = functionPlot({
target: '#graph2D-container',
width: bounding.width,
height: bounding.height,
grid: true,
xAxis: {
scale: 'linear',
domain: {
initial: [-10, 10],
type: 'discrete'
}
target: "#graph2D-container",
grid: this.settings.grid,
axis: this.settings.axis,
width: bounding.width,
height: bounding.height,
tip: {
color: "green",
},
xAxis: {
scale: "linear",
domain: { initial: [-4, 4], type: "discrete" },
yAxis: { domain: [-4, 4] },
},
conj: this.conjunto,
data: this.funciones,
zoom: this.animation.zoo,
plugins: [functionPlot.plugins.zoomBox()],
});
break;
}
case "canvas": {
var shapesData = JSON.parse(canvas.resultado);
var shapesDataNormalized = this.normalizeShapesData(shapesData);
let bounding = this.getBounding();
this.cleanPlot();
this.instance = functionPlot({
target: "#graph2D-container",
width: bounding.width,
height: bounding.height,
grid: this.settings.grid,
axis: this.settings.axis,
xAxis: {
scale: "linear",
domain: {
initial: [-10, 10],
type: "discrete",
},
data: []
})
},
data: shapesDataNormalized,
plugins: [functionPlot.plugins.zoomBox()],
});
break;
}
case "animacion": {
this.cleanPlot();
var animationData = canvas.resultado.map((res) => JSON.parse(res));
for (var frame of animationData) {
this.animation.data.push(this.normalizeShapesData(frame));
}
this.runAnimation();
this.animation.init = true;
break;
}
}
},
(error) => {}
);
}
/**
* Angular lifecycle hook.
* called after Angular has fully initialized a component's view.
*/
ngAfterViewInit() {
if (!this.instance) {
let bounding = this.getBounding();
this.instance = functionPlot({
target: "#graph2D-container",
width: bounding.width,
height: bounding.height,
grid: this.settings.grid,
axis: this.settings.axis,
xAxis: {
scale: "linear",
domain: {
initial: [-10, 10],
type: "discrete",
},
},
data: [],
});
}
/**
* Angular lifecycle hook.
* called when a directive, pipe, or service is destroyed.
*/
ngOnDestroy() {
if (this.ghciServiceSub) {
this.ghciServiceSub.unsubscribe();
}
}
/**
* Angular lifecycle hook.
* called when a directive, pipe, or service is destroyed.
*/
ngOnDestroy() {
if (this.ghciServiceSub) {
this.ghciServiceSub.unsubscribe();
}
/**
* On Resize Event.
*/
onResize(event){
let instance = this.instance;
let bounding = this.getBounding();
if (bounding.width > 0) {
instance.options.width = bounding.width;
instance.options.height = bounding.height;
instance.build();
}
}
/**
* On Resize Event.
*/
onResize(_event) {
let instance = this.instance;
let bounding = this.getBounding();
if (bounding.width > 0) {
instance.options.width = bounding.width;
instance.options.height = bounding.height;
instance.build();
}
/**
* @name getBounding
* @desc get the measures of the container of the graph
*/
private getBounding = function() {
var {width, height} = this.graph2DRef.nativeElement.getBoundingClientRect();
if (width === 0) {
width = document.getElementById('graph2D-container').querySelector('svg').width.baseVal.value;
height = document.getElementById('graph2D-container').querySelector('svg').height.baseVal.value;
}
return {width, height}
}
/**
* @name getBounding
* @desc get the measures of the container of the graph
*/
private getBounding = function () {
var { width, height } =
this.graph2DRef.nativeElement.getBoundingClientRect();
if (width === 0) {
const graph2DSVG = document.getElementById("graph2D-container")
.firstElementChild as SVGSVGElement;
if (!graph2DSVG) {
return { width: 0, height: 0 };
}
width = graph2DSVG.width.baseVal.value;
height = graph2DSVG.height.baseVal.value;
}
/**
* @name updateFrame
* @desc update data for Function Plot and redraw the graph
*/
public updateFrame = function() {
var $this = this;
var $data = $this.animation.data[$this.animation.currentFrame];
if ($this.instance) {
$this.instance.options.data = $data;
$this.instance.draw();
} else {
let bounding = $this.getBounding();
$this.instance = functionPlot({
target: '#graph2D-container',
width: bounding.width,
height: bounding.height,
xAxis: {
label: 'x - axis',
scale: 'linear',
domain: {
initial: [-10, 10],
type: 'discrete'
}
},
data: $data
})
}
// Update Frame
$this.animation.timeout = setTimeout(function() {
$this.animation.currentFrame = ($this.animation.currentFrame + 1) % $this.animation.data.length;
$this.animation.animationFrame = requestAnimationFrame($this.updateFrame.bind($this));
}, 1000/ this.easeInOutCubic($this.animation.fps));
return { width, height };
};
/**
* @name updateFrame
* @desc update data for Function Plot and redraw the graph
*/
public updateFrame = function () {
var $this = this;
var $data = $this.animation.data[$this.animation.currentFrame];
if ($this.instance) {
$this.instance.options.data = $data;
$this.instance.draw();
} else {
let bounding = $this.getBounding();
$this.instance = functionPlot({
target: "#graph2D-container",
grid: this.settings.grid,
axis: this.settings.axis,
width: bounding.width,
height: bounding.height,
xAxis: {
label: "x - axis",
scale: "linear",
domain: {
initial: [-10, 10],
type: "discrete",
},
},
data: $data,
});
}
/**
* @name runAnimation
* @desc Run Shapes Animation
*/
public runAnimation = function() {
if (this.animation.playing) return;
var $this = this;
$this.animation.playing = true;
$this.updateFrame();
// Update Frame
$this.animation.timeout = setTimeout(function () {
$this.animation.currentFrame =
($this.animation.currentFrame + 1) % $this.animation.data.length;
$this.animation.animationFrame = requestAnimationFrame(
$this.updateFrame.bind($this)
);
}, 1000 / this.easeInOutCubic($this.animation.fps));
};
/**
* @name runAnimation
* @desc Run Shapes Animation
*/
public runAnimation = function () {
if (this.animation.playing) return;
var $this = this;
$this.animation.playing = true;
$this.updateFrame();
};
/**
* @name pauseAnimation
* @desc Pause Shapes Animation
*/
public pauseAnimation = function () {
var $this = this;
cancelAnimationFrame($this.animation.animationFrame);
clearTimeout($this.animation.timeout);
$this.animation.timeout = null;
$this.animation.playing = false;
};
/**
* @name stopAnimation
* @desc Stop Shapes Animation
*/
public stopAnimation = function () {
var $this = this;
$this.pauseAnimation();
$this.animation.data = [];
$this.animation.currentFrame = 0;
$this.animation.init = false;
this.instance.removeAllGraphs();
};
/**
* @name decreaseSpeed
* @desc Decrease Speed Animation
*/
public decreaseSpeed = function () {
var decrease = false;
if (this.animation.fps > 6) {
decrease = true;
}
/**
* @name pauseAnimation
* @desc Pause Shapes Animation
*/
public pauseAnimation = function() {
var $this = this;
cancelAnimationFrame($this.animation.animationFrame);
clearTimeout($this.animation.timeout);
$this.animation.timeout = null;
$this.animation.playing = false;
if (decrease) {
if (this.animation.fps > 10) {
this.animation.fps -= 1;
this.animation.speedX = this.animation.fps / 10;
} else {
this.animation.fps -= 1;
this.animation.speedX = this.animation.fps / 10;
}
this.pauseAnimation();
this.runAnimation();
}
/**
* @name stopAnimation
* @desc Stop Shapes Animation
*/
public stopAnimation = function() {
var $this = this;
$this.pauseAnimation();
$this.animation.data = [];
$this.animation.currentFrame = 0;
$this.animation.init = false;
this.instance.removeAllGraphs();
};
/**
* @name restoreSpeed
* @desc Increase Speed Animation
*/
public restoreSpeed = function () {
this.animation.fps = 10;
this.animation.speedX = 1;
this.pauseAnimation();
this.runAnimation();
};
/**
* @name increaseSpeed
* @desc Increase Speed Animation
*/
public increaseSpeed = function () {
var increase = false;
if (this.animation.fps < 60) {
increase = true;
}
/**
* @name decreaseSpeed
* @desc Decrease Speed Animation
*/
public decreaseSpeed = function() {
var decrease = false;
if (this.animation.fps > 6) {
decrease = true;
}
if (decrease) {
if (this.animation.fps > 10) {
this.animation.fps -= 1;
this.animation.speedX = this.animation.fps / 10;
} else {
this.animation.fps -= 1;
this.animation.speedX = this.animation.fps / 10;
}
this.pauseAnimation();
this.runAnimation();
}
if (increase) {
if (this.animation.fps >= 10) {
this.animation.fps += 1;
this.animation.speedX = this.animation.fps / 10;
} else {
this.animation.fps += 1;
this.animation.speedX = this.animation.fps / 10;
}
this.pauseAnimation();
this.runAnimation();
}
/**
* @name restoreSpeed
* @desc Increase Speed Animation
*/
public restoreSpeed = function() {
this.animation.fps = 10;
this.animation.speedX = 1;
this.pauseAnimation();
this.runAnimation();
};
/**
* @name toggleGrid
* @desc Show and Hide Grid
*/
public toggleGrid = function () {
this.instance.toggleGrid();
this.settings.grid = !this.settings.grid;
};
/**
* @name toggleAxis
* @desc Show and Hide Axis
*/
public toggleAxis = function () {
this.instance.toggleAxis();
this.settings.axis = !this.settings.axis;
};
/**
* @name toggleTip
* @desc Show and Hide Tip
*/
public toggleTip = function () {
this.instance.toggleTip();
this.settings.tip = !this.settings.tip;
};
/**
* @name zoomOut
* @desc Zoom Out Button Control
*/
public zoomOut = function () {
this.instance.zoomOut();
};
/**
* @name zoomIn
* @desc Zoom In Button Control
*/
public zoomIn = function () {
this.instance.zoomIn();
};
/**
* @name recenterPlot
* @desc center the plot and it returns to the initial state.
*/
public recenterPlot = function () {
this.instance.recenter();
};
/**
* @name cleanPlot
* @desc remove all the graph from the instance.
*/
public cleanPlot = function () {
if (this.animation.playing) {
this.stopAnimation();
} else {
this.funciones = [];
this.conjunto = [];
this.id = 0;
this.instance.removeAllGraphs();
}
/**
* @name increaseSpeed
* @desc Increase Speed Animation
*/
public increaseSpeed = function() {
var increase = false;
if (this.animation.fps < 60) {
increase = true;
};
/**
* @name exportPlot
* @desc Download Plot as an SVG image.
*/
public exportPlot = function () {
// Objects
var svg = document.querySelector("svg");
var canvas = document.createElement("canvas");
// Set dimensions of the image
var svgSize = svg.getBoundingClientRect();
canvas.width = svgSize.width;
canvas.height = svgSize.height;
// Convert SVG DOM structure to xml
var ctx = canvas.getContext("2d");
var data = new XMLSerializer().serializeToString(svg);
// URL Object used to parse, construct, normalise, and encode URLs.
var DOMURL = window.URL || (<any>window).webkitURL || window;
var img = new Image();
var svgBlob = new Blob([data], { type: "image/svg+xml;charset=utf-8" });
var url = DOMURL.createObjectURL(svgBlob);
img.onload = function () {
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
var imgURI = canvas
.toDataURL("image/png")
.replace("image/png", "image/octet-stream");
triggerDownload(imgURI);
};
img.src = url;
};
/**
* @name normalizeRectData
* @desc Normalize Rectangle data for Function Plot Library
* @param {Object} rectData Data of Rectangle to be normalized
* @returns {Object}
*/
public normalizeRectData = function ($rectData) {
var $rectNormalized: any = {};
var $shape: any = {};
$shape.w = $rectData.w;
$shape.h = $rectData.h;
$shape.x = $rectData.x;
$shape.y = $rectData.y;
$rectData.color && ($shape.fill = $rectData.color);
$rectData.rot !== "undefined" && ($shape.rotation = $rectData.rot);
$rectNormalized.shape = $shape;
$rectNormalized.graphType = "shape";
$rectNormalized.shapeType = "rect";
return $rectNormalized;
};
/**
* @name normalizeCircleData
* @desc Normalize Circle data for Function Plot Library
* @param {Object} circleData Data of Circle to be normalized
* @returns {Object}
*/
public normalizeCircleData = function ($circleData) {
var $circleNormalized: any = {};
var $shape: any = {};
$shape.r = $circleData.r;
$shape.x = $circleData.x;
$shape.y = $circleData.y;
$circleData.color && ($shape.fill = $circleData.color);
$circleData.rot !== "undefined" && ($shape.rotation = $circleData.rot);
$circleNormalized.shape = $shape;
$circleNormalized.graphType = "shape";
$circleNormalized.shapeType = "circle";
return $circleNormalized;
};
/**
* @name normalizeTextData
* @desc Normalize Text data for Function Plot Library
* @param {Object} textData Data of Text to be normalized
* @returns {Object}
*/
public normalizeTextData = function ($textData) {
var $textNormalized: any = {};
var $shape: any = {};
$shape.text = $textData.text;
$shape.size = $textData.size;
$shape.x = $textData.x;
$shape.y = $textData.y;
$textData.color && ($shape.fill = $textData.color);
$textData.rot !== "undefined" && ($shape.rotation = $textData.rot);
$textNormalized.shape = $shape;
$textNormalized.graphType = "shape";
$textNormalized.shapeType = "text";
return $textNormalized;
};
/**
* @name normalizeLineData
* @desc Normalize Line data for Function Plot Library
* @param {Object} lineData Data of Line to be normalized
* @returns {Object}
*/
public normalizeLineData = function ($lineData) {
var $lineNormalized: any = {};
var $points = [];
for (var p of $lineData.pts) {
$points.push([p[0], p[1]]);
}
$lineNormalized.points = $points;
$lineNormalized.stroke = $lineData.color;
$lineNormalized.rotation = $lineData.rot;
$lineNormalized.fnType = "points";
$lineNormalized.polylineType = "line";
$lineNormalized.graphType = "polyline";
return $lineNormalized;
};
/**
* @name normalizePolygonData
* @desc Normalize Polygon data for Function Plot Library
* @param {Object} textData Data of Polygon to be normalized
* @returns {Object}
*/
public normalizePolygonData = function ($polygonData) {
var $polygonNormalized: any = {};
var $points = [];
for (var p of $polygonData.pts) {
$points.push([p[0], p[1]]);
}
$polygonNormalized.points = $points;
$polygonNormalized.fill = $polygonData.color;
$polygonNormalized.rotation = $polygonData.rot;
$polygonNormalized.fnType = "points";
$polygonNormalized.polylineType = "polygon";
$polygonNormalized.graphType = "polyline";
return $polygonNormalized;
};
/**
* @name normalizeShapesData
* @desc Normalize Shapes data for Function Plot Library
* @param {Array} shapesData Data of Shapes to be normalized
* @returns {Array}
*/
public normalizeShapesData = function (shapesData) {
var normalized: Array<Object> = [];
for (var shape of shapesData) {
switch (shape.kind) {
case "rect": {
normalized.push(this.normalizeRectData(shape));
break;
}
if (increase) {
if (this.animation.fps >= 10) {
this.animation.fps += 1;
this.animation.speedX = this.animation.fps / 10;
} else {
this.animation.fps += 1;
this.animation.speedX = this.animation.fps / 10;
}
this.pauseAnimation();
this.runAnimation();
case "circle": {
normalized.push(this.normalizeCircleData(shape));
break;
}
case "text": {
normalized.push(this.normalizeTextData(shape));
break;
}
case "line": {
normalized.push(this.normalizeLineData(shape));
break;
}
case "poly": {
normalized.push(this.normalizePolygonData(shape));
break;
}
}
}
/**
* @name toggleGrid
* @desc Show and Hide Grid
*/
public toggleGrid = function () {
this.instance.toggleGrid();
this.settings.grid = !this.settings.grid;
return normalized;
};
getRandomArbitrary = function (min, max) {
return Math.round(Math.random() * (max - min) + min);
};
generarFuncion = function (graph) {
var funcionString = "";
var grafica;
for (var fun of graph.funs) {
funcionString =
"var " +
fun.fun +
" = function(" +
fun.args.join() +
"){\n return " +
this.generarExpresion(fun.bdy) +
"}\n" +
funcionString;
if (fun.fun == graph.graph) {
funcionString += "return " + fun.fun + "(" + fun.args.join() + ");\n";
grafica = fun;
}
}
/**
* @name toggleAxis
* @desc Show and Hide Axis
*/
public toggleAxis = function () {
this.instance.toggleAxis();
this.settings.axis = !this.settings.axis;
funcionString = "(" + grafica.args.join() + ")=>{\n" + funcionString + "}";
return funcionString;
};
generarExpresion = function (exp) {
var expresion = "";
if (exp.kind == "cnd") {
expresion =
" (" +
this.generarExpresion(exp.cond) +
"?" +
this.generarExpresion(exp.exp1) +
":" +
this.generarExpresion(exp.exp2) +
") ";
} else if (exp.kind == "bop") {
if (exp.op == "==") {
expresion =
" Math.abs((" +
this.generarExpresion(exp.exp1) +
") - (" +
this.generarExpresion(exp.exp2) +
")) == 0 ";
} else if (exp.op == "/=") {
expresion =
" Math.abs((" +
this.generarExpresion(exp.exp1) +
") - (" +
this.generarExpresion(exp.exp2) +
")) != 0";
} else if (exp.op == "^") {
expresion =
" Math.pow(" +
this.generarExpresion(exp.exp1) +
"," +
this.generarExpresion(exp.exp2) +
") ";
} else {
expresion =
" (" +
this.generarExpresion(exp.exp1) +
")" +
exp.op +
"(" +
this.generarExpresion(exp.exp2) +
") ";
}
} else if (exp.kind == "uop") {
expresion = " " + exp.op + " " + this.generarExpresion(exp.exp) + " ";
} else if (exp.kind == "app") {
var mul = "";
if (exp.fun == "Math.tan" || exp.fun == "tan") {
exp.fun = "Math.tan";
mul = "*Math.PI/180";
} else if (exp.fun == "Math.cos" || exp.fun == "cos") {
exp.fun = "Math.cos";
mul = "*Math.PI/180";
} else if (exp.fun == "Math.sin" || exp.fun == "sin") {
exp.fun = "Math.sin";
mul = "*Math.PI/180";
} else if (exp.fun == "red") {
exp.fun = "Math.round";
} else if (exp.fun == "sqrt") {
exp.fun = "Math.sqrt";
}
expresion =
" " +
exp.fun +
"((" +
exp.args.map((e) => this.generarExpresion(e)).join() +
")" +
mul +
") ";
} else if (exp.kind == "tup") {
expresion =
" (" + exp.exps.map((e) => this.generarExpresion(e)).join() + ") ";
} else if (exp.kind == "lit") {
expresion = " " + exp.val + " ";
} else if (exp.kind == "var") {
expresion = " " + exp.var + " ";
} else {
expresion = " undefined ";
}
/**
* @name toggleTip
* @desc Show and Hide Tip
*/
public toggleTip = function () {
this.instance.toggleTip();
this.settings.tip = !this.settings.tip;
return expresion;
};
// nueva
createListFunction = function (graph) {
var funcionString = "";
var grafica;
var funciones = [];
var j = 0;
while (graph.funs[j].fun != graph.graph) {
j += 1;
}
/**
* @name zoomOut
* @desc Zoom Out Button Control
*/
public zoomOut = function () {
this.instance.zoomOut();
}
/**
* @name zoomIn
* @desc Zoom In Button Control
*/
public zoomIn = function () {
this.instance.zoomIn();
var fun1 = graph.funs[j];
var arrayFunction = [];
var nameFun = [];
nameFun.push(fun1.fun);
funciones = this.armarFuncion(fun1.bdy, graph, nameFun);
for (var funs of funciones) {
for (var fun of graph.funs) {
if (fun.fun != fun1.fun) {
funcionString =
"var " +
fun.fun +
" = function(" +
fun.args.join() +
"){\n return " +
this.generarExpresion(fun.bdy) +
"}\n" +
funcionString;
}
}
funcionString =
"var " +
fun1.fun +
" = function(" +
fun1.args.join() +
"){\n return " +
funs +
"}\n" +
funcionString;
funcionString += ";return " + fun1.fun + "(" + fun1.args.join() + ");\n";
grafica = fun1;
funcionString =
"(" + grafica.args.join() + ")=>{\n" + funcionString + "}";
arrayFunction.push(funcionString);
var funcionString = "";
}
/**
* @name recenterPlot
* @desc center the plot and it returns to the initial state.
*/
public recenterPlot = function () {
this.instance.recenter();
return arrayFunction;
};
armarFuncion = function (exp, graph, nameFun) {
var lisArm = this.generateFunctionAndExp(exp, graph, nameFun);
var lisFun = [];
for (var lis of lisArm) {
var aux = "";
if (lis[0] == "N") {
aux = lis[1];
} else {
aux = "(" + lis[0] + " ? " + lis[1] + " : undefined )";
}
lisFun.push(aux);
}
/**
* @name cleanPlot
* @desc remove all the graph from the instance.
*/
public cleanPlot = function () {
if (this.animation.playing) {
this.stopAnimation();
return lisFun;
};
generateFunctionAndExp = function (exp, graph, namefun6) {
var myList = [];
// devuelvo lista con tupla (cond,funcion)
if (exp.kind == "cnd") {
var lisA = this.generateFunctionAndExp(exp.exp1, graph, namefun6);
var lisB = this.generateFunctionAndExp(exp.exp2, graph, namefun6);
var cond = this.createListExp(exp.cond);
var g = this.createListExp(exp.cond);
var cond2 = g.splice(1);
var union = g[0];
for (var a of cond2) {
union = "(" + union + " && " + a + ")";
}
for (var fun1 of lisA) {
var aux121 = [];
if (fun1[0] == "N") {
if (cond.length == 0) {
aux121[0] = "N";
} else {
aux121[0] = union;
}
} else {
this.funciones = [];
this.conjunto = [];
this.id = 0;
this.instance.removeAllGraphs();
aux121[0] = "(" + fun1[0] + " && " + union + ")";
}
aux121[1] = fun1[1];
myList.push(aux121);
}
for (var fun2 of lisB) {
if (cond.length != 0) {
for (var condi of cond) {
var aux123 = [];
aux123[1] = fun2[1];
if (fun2[0] == "N") {
aux123[0] = "!(" + condi + ")";
} else {
aux123[0] = "(" + fun2[0] + " && !(" + condi + "))";
}
myList.push(aux123);
}
} else {
myList.push(fun2);
}
}
} else if (exp.kind == "bop") {
if (exp.op == "^") {
var lisA1 = this.generateFunctionAndExp(exp.exp1, graph, namefun6);
var lisB1 = this.generateFunctionAndExp(exp.exp2, graph, namefun6);
var aux1 = [];
for (var f1 of lisA1) {
for (var f2 of lisB1) {
var aux11 = "Math.pow(" + f1[1] + " , " + f2[1] + ")";
var aux21;
if (f2[0] == "N" && f1[0] == "N") {
aux21 = "N";
} else if (f2[0] == "N") {
aux21 = f1[0];
} else if (f1[0] == "N") {
aux21 = f2[0];
} else {
aux21 = "(" + f1[0] + " && " + f2[0] + ")";
}
aux1[0] = aux21;
aux1[1] = aux11;
myList.push(aux1);
}
}
} else {
var lisA2 = this.generateFunctionAndExp(exp.exp1, graph, namefun6);
var lisB2 = this.generateFunctionAndExp(exp.exp2, graph, namefun6);
var aux2 = [];
for (var f1 of lisA2) {
for (var f2 of lisB2) {
var aux12 = "((" + f1[1] + ")" + exp.op + "(" + f2[1] + "))";
var aux22;
if (f2[0] == "N" && f1[0] == "N") {
aux22 = "N";
} else if (f2[0] == "N") {
aux22 = f1[0];
} else if (f1[0] == "N") {
aux22 = f2[0];
} else {
aux22 = "(" + f1[0] + " && " + f2[0] + ")";
}
aux2[0] = aux22;
aux2[1] = aux12;
myList.push(aux2);
}
}
}
} else if (exp.kind == "uop") {
var lisA3 = this.generateFunctionAndExp(exp.exp, graph, namefun6);
var aux3 = [];
for (var f1 of lisA3) {
var aux13 = " " + exp.op + " " + f1[1] + " ";
aux3[0] = f1[0];
aux3[1] = aux13;
myList.push(aux3);
}
} else if (exp.kind == "app") {
if (exp.fun == "Math.cos" || exp.fun == "cos") {
var aux4 = [];
var aux14 =
"Math.cos((" +
exp.args.map((e) => this.generarExpresion(e)).join() +
")*Math.PI/180)";
var aux24 = "N";
aux4[0] = aux24;
aux4[1] = aux14;
myList.push(aux4);
} else if (exp.fun == "Math.sin" || exp.fun == "sin") {
var aux5 = [];
var aux15 =
"Math.sin((" +
exp.args.map((e) => this.generarExpresion(e)).join() +
")*Math.PI/180)";
var aux25 = "N";
aux5[0] = aux25;
aux5[1] = aux15;
myList.push(aux5);
} else if (exp.fun == "Math.tan" || exp.fun == "tan") {
var aux5 = [];
var aux15 =
"Math.tan((" +
exp.args.map((e) => this.generarExpresion(e)).join() +
")*Math.PI/180)";
var aux25 = "N";
aux5[0] = aux25;
aux5[1] = aux15;
myList.push(aux5);
} else if (exp.fun == "Math.PI" || exp.fun == "pi") {
var aux5 = [];
var aux15 = "Math.PI";
var aux25 = "N";
aux5[0] = aux25;
aux5[1] = aux15;
myList.push(aux5);
} else if (exp.fun == "Math.round" || exp.fun == "red") {
var aux6 = [];
var aux16 =
"Math.round(" +
exp.args.map((e) => this.generarExpresion(e)).join() +
")";
var aux26 = "N";
aux6[0] = aux26;
aux6[1] = aux16;
myList.push(aux6);
} else if (exp.fun == "Math.sqrt" || exp.fun == "sqrt") {
var aux7 = [];
var aux17 =
"Math.sqrt(" +
exp.args.map((e) => this.generarExpresion(e)).join() +
")";
var aux27 = "N";
aux7[0] = aux27;
aux7[1] = aux17;
myList.push(aux7);
// }else if (exp.args[0].kind == 'app'){
// var aux101 = [];
// var aux1101 = exp.fun+'('+ exp.args.map(e => this.generarExpresion(e)).join() +')';
// var aux2101 = 'N'
// aux101[0]= aux2101;
// aux101[1] = aux1101;
// myList.push(aux101);
// }else if(((exp.args[0].kind == 'cnd' || exp.args[0].kind == 'bop') && (exp.args[0].exp1.kind == 'app' || exp.args[0].exp2.kind == 'app' )) || (exp.args[0].kind == 'uop' && exp.args[0].exp.kind == 'app') ){
// var aux102 = [];
// var aux1102 = exp.fun+'('+ exp.args.map(e => this.generarExpresion(e)).join() +')';
// var aux2102 = 'N'
// aux102[0]= aux2102;
// aux102[1] = aux1102;
// myList.push(aux102);
} else if (JSON.stringify(exp.args[0]).indexOf("app") != -1) {
exp.args[0] = this.recorrerArgumentos(exp.args[0]);
var aux102 = [];
var aux1102 =
exp.fun +
"(" +
exp.args.map((e) => this.generarExpresion(e)).join() +
")";
var aux2102 = "N";
aux102[0] = aux2102;
aux102[1] = aux1102;
myList.push(aux102);
} else {
var nomFun =
exp.fun + exp.args.map((e) => this.generarExpresion(e)).join();
if (!namefun6.includes(nomFun)) {
var ListnameFNew = namefun6;
ListnameFNew.push(nomFun);
for (var fun5 of graph.funs) {
if (fun5.fun == exp.fun) {
myList = this.generateFunctionAndExp(
fun5.bdy,
graph,
ListnameFNew
);
for (var iter of myList) {
iter[1] = iter[1].replace(
/x/g,
exp.args.map((e) => this.generarExpresion(e)).join()
);
}
}
}
} else {
var aux76 = [];
aux76[0] = "N";
aux76[1] =
exp.fun +
"(" +
exp.args.map((e) => this.generarExpresion(e)).join() +
")";
myList.push(aux76);
}
}
} else if (exp.kind == "tup") {
var lisA7 = this.generateFunctionAndExp(exp.exps, graph, namefun6);
for (var f of lisA7) {
var aux65 = [];
aux65[1] = "(" + f[1] + ")";
aux65[0] = f[0];
myList.push(aux65);
}
//Es esto o las combinaciones
// expresion = ' (' + exp.exps.map(e => this.generarExpresion(e)).join() + ') ';
} else if (exp.kind == "lit") {
var aux8 = [];
aux8[0] = "N";
aux8[1] = " " + exp.val + " ";
myList.push(aux8);
} else if (exp.kind == "var") {
var aux9 = [];
aux9[0] = "N";
aux9[1] = " " + exp.var + " ";
myList.push(aux9);
} else {
var aux54 = [];
aux54[0] = "N";
aux54[1] = "undefined";
myList.push(aux54);
}
/**
* @name exportPlot
* @desc Download Plot as an SVG image.
*/
public exportPlot = function() {
// Objects
var svg = document.querySelector('svg');
var canvas = document.createElement("canvas");
// Set dimensions of the image
var svgSize = svg.getBoundingClientRect();
canvas.width = svgSize.width;
canvas.height = svgSize.height;
// Convert SVG DOM structure to xml
var ctx = canvas.getContext('2d');
var data = new XMLSerializer().serializeToString(svg);
// URL Object used to parse, construct, normalise, and encode URLs.
var DOMURL = window.URL || (<any>window).webkitURL || window;
var img = new Image();
var svgBlob = new Blob([data], { type: 'image/svg+xml;charset=utf-8' });
var url = DOMURL.createObjectURL(svgBlob);
img.onload = function () {
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
var imgURI = canvas
.toDataURL('image/png')
.replace('image/png', 'image/octet-stream');
triggerDownload(imgURI);
};
img.src = url;
}
/**
* @name normalizeRectData
* @desc Normalize Rectangle data for Function Plot Library
* @param {Object} rectData Data of Rectangle to be normalized
* @returns {Object}
*/
public normalizeRectData = function ($rectData) {
var $rectNormalized:any = {};
var $shape:any = {};
$shape.w = $rectData.w;
$shape.h = $rectData.h;
$shape.x = $rectData.x;
$shape.y = $rectData.y;
$rectData.color && ($shape.fill = $rectData.color);
$rectData.rot !== 'undefined' && ($shape.rotation = $rectData.rot);
$rectNormalized.shape = $shape;
$rectNormalized.graphType = 'shape';
$rectNormalized.shapeType = 'rect';
return $rectNormalized;
return myList;
};
recorrerArgumentos = function (argumento) {
if (argumento.kind == "app") {
if (argumento.fun == "Math.cos" || argumento.fun == "cos") {
argumento.fun = "Math.cos";
} else if (argumento.fun == "Math.sin" || argumento.fun == "sin") {
argumento.fun = "Math.sin";
} else if (argumento.fun == "Math.tan" || argumento.fun == "tan") {
argumento.fun = "Math.tan";
} else if (argumento.fun == "Math.round" || argumento.fun == "red") {
argumento.fun = "Math.round";
} else if (argumento.fun == "Math.sqrt" || argumento.fun == "sqrt") {
argumento.fun = "Math.sqrt";
}
} else if (argumento.kind == "cnd") {
this.recorrerArgumentos(argumento.exp1);
this.recorrerArgumentos(argumento.exp2);
} else if (argumento.kind == "bop") {
this.recorrerArgumentos(argumento.exp1);
this.recorrerArgumentos(argumento.exp2);
} else if (argumento.kind == "uop") {
this.recorrerArgumentos(argumento.exp1);
}
/**
* @name normalizeCircleData
* @desc Normalize Circle data for Function Plot Library
* @param {Object} circleData Data of Circle to be normalized
* @returns {Object}
*/
public normalizeCircleData = function ($circleData) {
var $circleNormalized:any = {};
var $shape:any = {};
$shape.r = $circleData.r;
$shape.x = $circleData.x;
$shape.y = $circleData.y;
$circleData.color && ($shape.fill = $circleData.color);
$circleData.rot !== 'undefined' && ($shape.rotation = $circleData.rot);
$circleNormalized.shape = $shape;
$circleNormalized.graphType = 'shape';
$circleNormalized.shapeType = 'circle';
return $circleNormalized;
}
/**
* @name normalizeTextData
* @desc Normalize Text data for Function Plot Library
* @param {Object} textData Data of Text to be normalized
* @returns {Object}
*/
public normalizeTextData = function ($textData) {
var $textNormalized:any = {};
var $shape:any = {};
$shape.text = $textData.text;
$shape.size = $textData.size;
$shape.x = $textData.x;
$shape.y = $textData.y;
$textData.color && ($shape.fill = $textData.color);
$textData.rot !== 'undefined' && ($shape.rotation = $textData.rot);
$textNormalized.shape = $shape;
$textNormalized.graphType = 'shape';
$textNormalized.shapeType = 'text';
return $textNormalized;
}
/**
* @name normalizeLineData
* @desc Normalize Line data for Function Plot Library
* @param {Object} lineData Data of Line to be normalized
* @returns {Object}
*/
public normalizeLineData = function ($lineData) {
var $lineNormalized:any = {};
var $points = []
for (var p of $lineData.pts) {
$points.push([p[0],p[1]]);
return argumento;
};
/////////////////////
createListExp = function (exp) {
var expresion = "";
var funcione = [];
if (exp.kind == "cnd") {
funcione = this.createListExp(exp.cond);
} else if (exp.kind == "bop") {
if (exp.op == "==") {
expresion =
" Math.abs((" +
this.createListExp(exp.exp1)[0] +
") - (" +
this.createListExp(exp.exp2)[0] +
")) == 0 ";
if (exp.exp1.kind == "lit") {
this.valores.push(exp.exp1.val);
}
$lineNormalized.points = $points;
$lineNormalized.stroke = $lineData.color;
$lineNormalized.rotation = $lineData.rot;
$lineNormalized.fnType = 'points';
$lineNormalized.polylineType = 'line';
$lineNormalized.graphType = 'polyline';
return $lineNormalized;
}
/**
* @name normalizePolygonData
* @desc Normalize Polygon data for Function Plot Library
* @param {Object} textData Data of Polygon to be normalized
* @returns {Object}
*/
public normalizePolygonData = function ($polygonData) {
var $polygonNormalized:any = {};
var $points = []
for (var p of $polygonData.pts) {
$points.push([p[0],p[1]]);
if (exp.exp2.kind == "lit") {
this.valores.push(exp.exp2.val);
}
$polygonNormalized.points = $points;
$polygonNormalized.fill = $polygonData.color;
$polygonNormalized.rotation = $polygonData.rot;
$polygonNormalized.fnType = 'points';
$polygonNormalized.polylineType = 'polygon';
$polygonNormalized.graphType = 'polyline';
return $polygonNormalized;
}
/**
* @name normalizeShapesData
* @desc Normalize Shapes data for Function Plot Library
* @param {Array} shapesData Data of Shapes to be normalized
* @returns {Array}
*/
public normalizeShapesData = function (shapesData) {
var normalized:Array<Object> = [];
for (var shape of shapesData) {
switch(shape.kind) {
case 'rect': {
normalized.push(this.normalizeRectData(shape));
break;
}
case 'circle': {
normalized.push(this.normalizeCircleData(shape));
break;
}
case 'text': {
normalized.push(this.normalizeTextData(shape));
break;
}
case 'line': {
normalized.push(this.normalizeLineData(shape));
break;
}
case 'poly': {
normalized.push(this.normalizePolygonData(shape));
break;
}
}
funcione.push(expresion);
} else if (exp.op == "/=") {
expresion =
" Math.abs((" +
this.createListExp(exp.exp1) +
") - (" +
this.createListExp(exp.exp2) +
")) != 0";
funcione.push(expresion);
} else if (exp.op == "^") {
expresion =
" Math.pow(" +
this.createListExp(exp.exp1) +
"," +
this.createListExp(exp.exp2) +
") ";
funcione.push(expresion);
} else if (exp.op == "&&") {
for (var atr of this.createListExp(exp.exp1)) {
funcione.push(atr);
}
for (var atr2 of this.createListExp(exp.exp2)) {
funcione.push(atr2);
}
return normalized;
} else if (exp.op == "or") {
funcione.push("!" + this.createListExp(exp.exp1));
funcione.push("!" + this.createListExp(exp.exp2));
} else {
var lis1 = this.createListExp(exp.exp1);
var lis2 = this.createListExp(exp.exp2);
for (var expes1 of lis1) {
for (var expes2 of lis2) {
expresion = " ((" + expes1 + ")" + exp.op + "(" + expes2 + ") )";
funcione.push(expresion);
}
}
}
} else if (exp.kind == "uop") {
expresion = " " + exp.op + " " + this.createListExp(exp.exp) + " ";
funcione.push(expresion);
} else if (exp.kind == "app") {
if (exp.fun == "Math.cos") {
exp.fun = "Math.cos";
expresion =
" " +
exp.fun +
"((" +
exp.args.map((e) => this.generarExpresion(e)).join() +
")*Math.PI/180) ";
funcione.push(expresion);
} else if (exp.fun == "Math.sin") {
exp.fun = "Math.sin";
expresion =
" " +
exp.fun +
"((" +
exp.args.map((e) => this.generarExpresion(e)).join() +
")*Math.PI/180) ";
funcione.push(expresion);
} else if (exp.fun == "Math.tan") {
exp.fun = "Math.tan";
expresion =
" " +
exp.fun +
"((" +
exp.args.map((e) => this.generarExpresion(e)).join() +
")*Math.PI/180) ";
funcione.push(expresion);
} else if (exp.fun == "Math.PI" || exp.fun == "pi") {
exp.fun = "Math.PI";
funcione.push(exp.fun);
} else if (exp.fun == "Math.round") {
exp.fun = "Math.round";
expresion =
" " +
exp.fun +
"(" +
exp.args.map((e) => this.generarExpresion(e)).join() +
") ";
funcione.push(expresion);
} else if (exp.fun == "Math.sqrt") {
exp.fun = "Math.sqrt";
expresion =
" " +
exp.fun +
"(" +
exp.args.map((e) => this.generarExpresion(e)).join() +
") ";
funcione.push(expresion);
} else {
expresion =
" " +
exp.fun +
"(" +
exp.args.map((e) => this.generarExpresion(e)).join() +
") ";
funcione.push(expresion);
}
} else if (exp.kind == "tup") {
expresion =
" (" + exp.exps.map((e) => this.generarExpresion(e)).join() + ") ";
funcione.push(expresion);
} else if (exp.kind == "lit") {
expresion = " " + exp.val + " ";
this.valores.push(exp.val);
funcione.push(expresion);
} else if (exp.kind == "var") {
expresion = " " + exp.var + " ";
funcione.push(expresion);
} else {
expresion = "undefined ";
funcione.push(expresion);
}
getRandomArbitrary = function (min, max) {
return Math.round(Math.random() * (max - min) + min);
return funcione;
};
///////////////////// fin de nuevo
// Prueba 2019
generarFuncionDisc = function (graph) {
var funcionString = "";
var grafica;
var arrayFunction = [];
var fun = graph.funs[0];
var ListnameF = [];
ListnameF.push(fun.fun);
var funciones = this.generarExpresionDisc(fun.bdy, graph, ListnameF);
for (var funs of funciones) {
funcionString =
"var " +
fun.fun +
" = function(" +
fun.args.join() +
"){\n return " +
funs +
"}\n" +
funcionString;
if (fun.fun == graph.graph) {
funcionString += ";return " + fun.fun + "(" + fun.args.join() + ");\n";
grafica = fun;
}
funcionString =
"(" + grafica.args.join() + ")=>{\n" + funcionString + "}";
arrayFunction.push(funcionString);
var funcionString = "";
}
generarFuncion = function (graph) {
var funcionString = '';
var grafica;
for (var fun of graph.funs) {
funcionString = 'var ' + fun.fun + ' = function(' + fun.args.join() + '){\n return ' + this.generarExpresion(fun.bdy) + '}\n' + funcionString;
if (fun.fun == graph.graph) {
funcionString += 'return ' + fun.fun + '(' + fun.args.join() + ');\n'
grafica = fun;
}
}
funcionString = '(' + grafica.args.join() + ')=>{\n' + funcionString + '}';
var arrayFunction1 = [arrayFunction[0]];
return arrayFunction;
};
return funcionString;
}
generarExpresionDisc = function (exp, grap, ListnameF) {
var expresion = "";
var funcione = [];
if (exp.kind == "cnd") {
var con1 = this.generarExpresionDisc(exp.cond, grap, ListnameF);
var con11 = "";
generarExpresion = function (exp) {
var expresion = '';
if (exp.kind == 'cnd') {
expresion = ' (' + this.generarExpresion(exp.cond) + '?' + this.generarExpresion(exp.exp1) + ':' + this.generarExpresion(exp.exp2) + ') ';
} else if (exp.kind == 'bop') {
if (exp.op == '==') {
expresion = ' Math.abs((' + this.generarExpresion(exp.exp1) + ') - (' + this.generarExpresion(exp.exp2) + ')) == 0 ';
} else if (exp.op == '/=') {
expresion = ' Math.abs((' + this.generarExpresion(exp.exp1) + ') - (' + this.generarExpresion(exp.exp2) + ')) == 0 || Math.abs((' + this.generarExpresion(exp.exp1) + ') - (' + this.generarExpresion(exp.exp2) + ')) == 0 ';
} else if (exp.op == '^') {
expresion = ' Math.pow(' + this.generarExpresion(exp.exp1) + ',' + this.generarExpresion(exp.exp2) + ') ';
} else {
expresion = ' (' + this.generarExpresion(exp.exp1) + ')' + exp.op + '(' + this.generarExpresion(exp.exp2) + ') ';
for (var condi of con1) {
if (con11 == "") {
con11 = condi;
} else {
con11 = "(" + con11 + " && " + condi + ")";
}
}
for (var funs of this.generarExpresionDisc(exp.exp1, grap, ListnameF)) {
funcione.push("(" + con11 + " ? " + funs + " : undefined)");
}
for (var funs2 of this.generarExpresionDisc(exp.exp2, grap, ListnameF)) {
for (var condi2 of con1) {
funcione.push("(!(" + condi2 + ") ? " + funs2 + " : undefined)");
}
}
} else if (exp.kind == "bop") {
if (exp.op == "==") {
expresion =
" Math.abs((" +
this.generarExpresionDisc(exp.exp1, grap, ListnameF) +
") - (" +
this.generarExpresionDisc(exp.exp2, grap, ListnameF) +
")) == 0 ";
if (exp.exp1.kind == "lit") {
this.valores.push(exp.exp1.val);
}
if (exp.exp2.kind == "lit") {
this.valores.push(exp.exp2.val);
}
funcione.push(expresion);
} else if (exp.op == "/=") {
expresion =
" Math.abs((" +
this.generarExpresionDisc(exp.exp1, grap, ListnameF) +
") - (" +
this.generarExpresionDisc(exp.exp2, grap, ListnameF) +
")) != 0";
funcione.push(expresion);
} else if (exp.op == "^") {
expresion =
" Math.pow(" +
this.generarExpresionDisc(exp.exp1, grap, ListnameF) +
"," +
this.generarExpresionDisc(exp.exp2, grap, ListnameF) +
") ";
funcione.push(expresion);
} else if (exp.op == "&&") {
for (var atr of this.generarExpresionDisc(exp.exp1, grap, ListnameF)) {
funcione.push(atr);
}
for (var atr2 of this.generarExpresionDisc(exp.exp2, grap, ListnameF)) {
funcione.push(atr2);
}
} else if (exp.op == "or") {
funcione.push(
"!" + this.generarExpresionDisc(exp.exp1, grap, ListnameF)
);
funcione.push(
"!" + this.generarExpresionDisc(exp.exp2, grap, ListnameF)
);
} else {
var lis1 = this.generarExpresionDisc(exp.exp1, grap, ListnameF);
var lis2 = this.generarExpresionDisc(exp.exp2, grap, ListnameF);
for (var expes1 of lis1) {
for (var expes2 of lis2) {
expresion = " ((" + expes1 + ")" + exp.op + "(" + expes2 + ") )";
funcione.push(expresion);
}
}
}
} else if (exp.kind == "uop") {
expresion =
" " +
exp.op +
" " +
this.generarExpresionDisc(exp.exp, grap, ListnameF) +
" ";
funcione.push(expresion);
} else if (exp.kind == "app") {
if (exp.fun == "Math.cos") {
exp.fun = "Math.cos";
expresion =
" " +
exp.fun +
"(" +
exp.args
.map((e) => this.generarExpresionDisc(e, grap, ListnameF))
.join() +
") ";
funcione.push(expresion);
} else if (exp.fun == "Math.sin") {
exp.fun = "Math.sin";
expresion =
" " +
exp.fun +
"(" +
exp.args
.map((e) => this.generarExpresionDisc(e, grap, ListnameF))
.join() +
") ";
funcione.push(expresion);
} else if (exp.fun == "Math.round") {
exp.fun = "Math.round";
expresion =
" " +
exp.fun +
"(" +
exp.args
.map((e) => this.generarExpresionDisc(e, grap, ListnameF))
.join() +
") ";
funcione.push(expresion);
} else if (exp.fun == "Math.sqrt") {
exp.fun = "Math.sqrt";
expresion =
" " +
exp.fun +
"(" +
exp.args
.map((e) => this.generarExpresionDisc(e, grap, ListnameF))
.join() +
") ";
funcione.push(expresion);
} else {
if (!ListnameF.includes(exp.fun)) {
var ListnameFNew = ListnameF;
ListnameFNew.push(exp.fun);
for (var fun5 of grap.funs) {
if (fun5.fun == exp.fun) {
var funresul = this.generarExpresionDisc(
fun5.bdy,
grap,
ListnameFNew
);
for (var subfunciones of funresul) {
funcione.push(subfunciones);
}
}
} else if (exp.kind == 'uop') {
expresion = ' ' + exp.op + ' ' + this.generarExpresion(exp.exp) + ' ';
} else if (exp.kind == 'app') {
if (exp.fun == 'cos') {
exp.fun = 'Math.cos'
} else if (exp.fun == 'sin') {
exp.fun = 'Math.sin'
} else if (exp.fun == 'round') {
exp.fun = 'Math.round'
}
expresion = ' ' + exp.fun + '(' + exp.args.map(e => this.generarExpresion(e)).join() + ') ';
} else if (exp.kind == 'tup') {
expresion = ' (' + exp.exps.map(e => this.generarExpresion(e)).join() + ') ';
} else if (exp.kind == 'lit') {
expresion = ' ' + exp.val + ' ';
} else if (exp.kind == 'var') {
expresion = ' ' + exp.var + ' ';
}
} else {
expresion = ' undefined ';
funcione.push(exp.fun);
}
return expresion;
}
} else if (exp.kind == "tup") {
expresion =
" (" +
exp.exps
.map((e) => this.generarExpresionDisc(e, grap, ListnameF))
.join() +
") ";
funcione.push(expresion);
} else if (exp.kind == "lit") {
expresion = " " + exp.val + " ";
this.valores.push(exp.val);
funcione.push(expresion);
} else if (exp.kind == "var") {
expresion = " " + exp.var + " ";
funcione.push(expresion);
} else {
expresion = " undefined ";
funcione.push(expresion);
}
//Nuevo 20-07-2018
obtenerConjunto = function (grf) {
var setf = '\"sets\": {';
var dominio = '{\"conj\": {';
if (grf.dom == 'R') {
dominio += "\"radio\": 0.3, \"baseDom\": \"R\", \"dom\": \"R\"";
setf += "\"fdom\": \"R\",";
} else if (grf.dom == 'Z') {
dominio += "\"radio\": 2, \"baseDom\": \"Z\", \"dom\": \"Z\"";
setf += "\"fdom\": \"Z\",";
}/* else if (grf.dom == 'N') {
return funcione;
};
//Prueba 2019 fin
//Nuevo 20-07-2018
obtenerConjunto = function (grf) {
var setf = '"sets": {';
var dominio = '{"conj": {';
if (grf.dom == "R") {
dominio += '"radio": 0.3, "baseDom": "R", "dom": "R"';
setf += '"fdom": "R",';
} else if (grf.dom == "Z") {
dominio += '"radio": 2, "baseDom": "Z", "dom": "Z"';
setf += '"fdom": "Z",';
} /* else if (grf.dom == 'N') {
dominio += "\"radio\":2, \"baseDom\": \"N\", \"dom\": \"N\"";
setf += "\"fdom\": \"N\",";
}*/ else {
var nom = grf.dom;
if (Array.isArray(grf.sets[0][nom])) {
var arreglo = grf.sets[0][nom];
var arreglo2 = [];
for (var item of arreglo) {
arreglo2.push("\"" + item + "\"");
}
dominio += "\"radio\":2, \"baseDom\": \"N\", \"dom\": \"Numer\"";
setf += "\"fdom\": [" + arreglo2 + "], ";
} else {
dominio += this.recursivoDom(grf.sets, nom);
setf += "\"fdom\":\"function(x)\",";
}
var nom = grf.dom;
if (Array.isArray(grf.sets[0][nom])) {
var arreglo = grf.sets[0][nom];
var arreglo2 = [];
for (var item of arreglo) {
arreglo2.push('"' + item + '"');
}
dominio += ", ";
if (grf.cod == 'R') {
dominio += "\"baseCod\": \"R\", \"cod\": \"R\" ,";
setf += "\"fcod\": \"R\"";
} else if (grf.cod == 'Z') {
dominio += "\"baseCod\": \"Z\", \"cod\": \"Z\" ,";
setf += "\"fcod\": \"Z\"";
} else if (grf.cod == 'N') {
dominio += '"radio":2, "baseDom": "N", "dom": "Numer"';
setf += '"fdom": [' + arreglo2 + "], ";
} else {
dominio += this.recursivoDom(grf.sets, nom);
setf += '"fdom":"function(x)",';
}
}
dominio += ", ";
if (grf.cod == "R") {
dominio += '"baseCod": "R", "cod": "R" ,';
setf += '"fcod": "R"';
} else if (grf.cod == "Z") {
dominio += '"baseCod": "Z", "cod": "Z" ,';
setf += '"fcod": "Z"';
} /*else if (grf.cod == 'N') {
dominio += "\"baseCod\": \"N\", \"cod\": \"N\" ,";
setf += "\"fcod\": \"N\"";
} else {
var nom = grf.cod;
if (Array.isArray(grf.sets[0][nom])) {
var arreglo = grf.sets[0][nom];
var arreglo2 = [];
for (var item of arreglo) {
arreglo2.push("\"" + item + "\"");
}
dominio += "\"baseCod\": \"N\", \"cod\": \"Numer\" ,";
setf += '\"fcod\":[' + arreglo2 + ']';
} else {
dominio += this.recursivoCod(grf.sets, nom);
setf += "\"fcod\": \"function(x)\"";
}
} */ else {
var nom1 = grf.cod;
if (Array.isArray(grf.sets[0][nom1])) {
var arreglo3 = grf.sets[0][nom1];
var arreglo4 = [];
for (var item of arreglo3) {
arreglo4.push('"' + item + '"');
}
return dominio + setf + "}}";
dominio += '"baseCod": "N", "cod": "Numer" ,';
setf += '"fcod":[' + arreglo4 + "]";
} else {
dominio += this.recursivoCod(grf.sets, nom1);
setf += '"fcod": "function(x)"';
}
}
recursionfuncion = function (func, nombre) {
var fun = func[0][nombre].set;
var resul = "";
if (fun == 'R' || fun == 'Z' || fun == 'N') {
resul += this.generarF(func[0][nombre].cond);
} else {
resul += this.generarF(func[0][nombre].cond) + " && " + this.recursionfuncion(func, fun);
}
return resul;
return dominio + setf + "}}";
};
recursionfuncion = function (func, nombre) {
var fun = func[0][nombre].set;
var resul = ""; // "var z = 2;"; // PRUEBA
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);
}
recursivoDom = function (sets, nom) {
var domin = "";
if (sets[0][nom].set == 'R') {
domin += "\"radio\": 0.3, \"baseDom\": \"R\", \"dom\": \"Func\"";
} else if (sets[0][nom].set == 'Z') {
domin += "\"radio\": 2, \"baseDom\": \"Z\", \"dom\": \"Func\"";
} else if (sets[0][nom].set == 'N') {
domin += "\"radio\": 2, \"baseDom\": \"N\", \"dom\": \"Func\"";
} else {
var nombre = sets[0][nom].set;
domin = this.recursivoDom(sets, nombre);
}
return domin;
return resul;
};
recursionfuncionCod = function (func, nombre) {
//ACA CAMBIE
var fun = func[0][nombre].set;
var resul = "";
if (fun == "R" || fun == "Z" || fun == "N") {
//ACA TAMBIEN
resul += this.generarF(func[0][nombre].cond);
} else {
//ACA TAMBIEN
resul +=
this.generarF(func[0][nombre].cond) +
" && " +
this.recursionfuncionCod(func, fun);
}
recursivoCod = function (sets, nom) {
var coodo = "";
if (sets[0][nom].set == 'R') {
coodo += "\"baseCod\": \"R\", \"cod\": \"Func\",";
} else if (sets[0][nom].set == 'Z') {
coodo += "\"baseCod\": \"Z\", \"cod\": \"Func\",";
} else if (sets[0][nom].set == 'N') {
coodo += "\"baseCod\": \"N\", \"cod\": \"Func\",";
} else {
var nombre = sets[0][nom].set;
coodo += this.recursivoDom(sets, nombre);
}
return coodo;
return resul;
};
recursivoDom = function (sets, nom) {
var domin = "";
if (sets[0][nom] == undefined) {
domin += '"baseDom": "Error"';
} else if (sets[0][nom].set == "R") {
domin += '"radio": 0.3, "baseDom": "R", "dom": "Func"';
} else if (sets[0][nom].set == "Z") {
domin += '"radio": 2, "baseDom": "Z", "dom": "Func"';
} else if (sets[0][nom].set == "N") {
domin += '"radio": 2, "baseDom": "N", "dom": "Func"';
} else {
var nombre = sets[0][nom].set;
domin = this.recursivoDom(sets, nombre);
}
generarF = function (exp) {
var expresion = '';
if (exp.kind == 'cond') {
expresion = ' (' + this.generarF(exp.cond) + '?' + this.generarF(exp.exp1) + ':' + this.generarF(exp.exp2) + ') ';
} else if (exp.kind == 'bop') {
if (exp.op == '==') {
expresion = ' Math.abs((' + this.generarF(exp.exp1) + ') - (' + this.generarF(exp.exp2) + ')) == 0 ';
} else if (exp.op == '/=') {
expresion = ' Math.abs((' + this.generarF(exp.exp1) + ') - (' + this.generarF(exp.exp2) + ')) == 0 || Math.abs((' + this.generarF(exp.exp1) + ') - (' + this.generarF(exp.exp2) + ')) == 0 ';
} else if (exp.op == '^') {
expresion = ' Math.pow(' + this.generarF(exp.exp1) + ',' + this.generarF(exp.exp2) + ') ';
} else {
expresion = ' (' + this.generarF(exp.exp1) + ')' + exp.op + '(' + this.generarF(exp.exp2) + ') ';
}
} else if (exp.kind == 'uop') {
expresion = ' ' + exp.op + ' ' + this.generarF(exp.exp) + ' ';
} else if (exp.kind == 'app') {
if (exp.fun == 'cos') {
exp.fun = 'Math.cos'
} else if (exp.fun == 'sin') {
exp.fun = 'Math.sin'
} else if (exp.fun == 'round') {
exp.fun = 'Math.round'
}
expresion = ' ' + exp.fun + '(' + exp.args.map(e => this.generarF(e)).join() + ') ';
} else if (exp.kind == 'tup') {
expresion = ' (' + exp.exps.map(e => this.generarF(e)).join() + ') ';
} else if (exp.kind == 'lit') {
expresion = ' ' + exp.val + ' ';
} else if (exp.kind == 'var') {
expresion = ' ' + exp.var + ' ';
} else {
expresion = ' undefined ';
}
return expresion;
return domin;
};
recursivoCod = function (sets, nom) {
var coodo = "";
if (sets[0][nom] == undefined) {
coodo += '"baseCod": "Error"';
} else if (sets[0][nom].set == "R") {
coodo += '"baseCod": "R", "cod": "Func",';
} else if (sets[0][nom].set == "Z") {
coodo += '"baseCod": "Z", "cod": "Func",';
} else if (sets[0][nom].set == "N") {
coodo += '"baseCod": "N", "cod": "Func",';
} else {
var nombre = sets[0][nom].set;
coodo += this.recursivoDom(sets, nombre);
}
generarFun = function (graph) {
var funcionString = '';
var grafica;
for (var fun of graph.funs) {
funcionString = 'var ' + fun.fun + ' = function(' + fun.args.join() + '){\n return ' + this.generarF(fun.bdy) + '}\n' + funcionString;
if (fun.fun == graph.graph) {
funcionString += 'return ' + fun.fun + '(' + fun.args.join() + ');\n'
grafica = fun;
}
}
funcionString = '(' + grafica.args.join() + ')=>{\n' + funcionString + '}';
return funcionString;
return coodo;
};
generarF = function (exp) {
var expresion = "";
if (exp.kind == "cond") {
expresion =
" (" +
this.generarF(exp.cond) +
"?" +
this.generarF(exp.exp1) +
":" +
this.generarF(exp.exp2) +
") ";
} else if (exp.kind == "bop") {
if (exp.op == "==") {
expresion =
" Math.abs((" +
this.generarF(exp.exp1) +
") - (" +
this.generarF(exp.exp2) +
")) == 0 ";
} else if (exp.op == "/=") {
expresion =
" Math.abs((" +
this.generarF(exp.exp1) +
") - (" +
this.generarF(exp.exp2) +
")) != 0 ";
} else if (exp.op == "^") {
expresion =
" Math.pow(" +
this.generarF(exp.exp1) +
"," +
this.generarF(exp.exp2) +
") ";
} else {
expresion =
" (" +
this.generarF(exp.exp1) +
")" +
exp.op +
"(" +
this.generarF(exp.exp2) +
") ";
}
} else if (exp.kind == "uop") {
expresion = " " + exp.op + " " + this.generarF(exp.exp) + " ";
} else if (exp.kind == "app") {
if (exp.fun == "cos") {
exp.fun = "Math.cos";
} else if (exp.fun == "sin") {
exp.fun = "Math.sin";
} else if (exp.fun == "round") {
exp.fun = "Math.round";
} else if (exp.fun == "sqrt") {
exp.fun = "Math.sqrt";
}
expresion =
" " +
exp.fun +
"(" +
exp.args.map((e) => this.generarF(e)).join() +
") ";
} else if (exp.kind == "tup") {
expresion = " (" + exp.exps.map((e) => this.generarF(e)).join() + ") ";
} else if (exp.kind == "lit") {
expresion = " " + exp.val + " ";
} else if (exp.kind == "var") {
expresion = " " + exp.var + " ";
} else {
expresion = " undefined ";
}
return expresion;
};
generarFun = function (graph) {
var funcionString = "";
var grafica;
for (var fun of graph.funs) {
funcionString =
"var " +
fun.fun +
" = function(" +
fun.args.join() +
"){\n return " +
this.generarF(fun.bdy) +
"}\n" +
funcionString;
if (fun.fun == graph.graph) {
funcionString += "return " + fun.fun + "(" + fun.args.join() + ");\n";
grafica = fun;
}
}
funcionString = "(" + grafica.args.join() + ")=>{\n" + funcionString + "}";
return funcionString;
};
}
export interface Animation {
data?: any,
init: boolean,
currentFrame: number,
fps: number,
playing: boolean,
timeout?: any,
animationFrame?: any,
speedX: number,
boton: boolean,
zoo: number,
data?: any;
init: boolean;
currentFrame: number;
fps: number;
playing: boolean;
timeout?: any;
animationFrame?: any;
speedX: number;
boton: boolean;
zoo: number;
}
export interface Setting {
axis: boolean,
grid: boolean,
tip: boolean
axis: boolean;
grid: boolean;
tip: boolean;
}
export function toJSON(data: string) : string {
console.log('data',data);
const regexPts = /(?:\"pts\"\:\[(?:\((x),(y)\))+,?\])/g;
var dataJSON = data.replace(regexPts, (match, x, y) => {
return `"points": [[${x},${y}]]`
})
console.log('dataJSON', dataJSON);
return dataJSON;
export function toJSON(data: string): string {
console.log("data", data);
const regexPts = /(?:\"pts\"\:\[(?:\((x),(y)\))+,?\])/g;
var dataJSON = data.replace(regexPts, (match, x, y) => {
return `"points": [[${x},${y}]]`;
});
console.log("dataJSON", dataJSON);
return dataJSON;
}
/**************para borrar***************** */
// export function JSONRepair(data: string): string {
// const regex = /\"sets\"\ : \[(\"+.*)\]\, \"bdy\"/g;
// return data.replace(regex, (match, content) => {
// return `"sets": [{ ${content} }], "bdy"`
// })
// }
/**************fin para borrar***************** */
export function triggerDownload(imgURI: string) {
var evt = new MouseEvent('click', {
view: window,
bubbles: false,
cancelable: true
});
var evt = new MouseEvent("click", {
view: window,
bubbles: false,
cancelable: true,
});
var a = document.createElement('a');
a.setAttribute('download', 'Matefun_2D_plot.png');
a.setAttribute('href', imgURI);
a.setAttribute('target', '_blank');
var a = document.createElement("a");
a.setAttribute("download", "Matefun_2D_plot.png");
a.setAttribute("href", imgURI);
a.setAttribute("target", "_blank");
a.dispatchEvent(evt);
}
\ No newline at end of file
a.dispatchEvent(evt);
}
import { NgModule} from '@angular/core';
import { CommonModule } from '@angular/common'
import { RouterModule } from '@angular/router';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { FormsModule } from '@angular/forms';
import { Graph2DComponent } from './graph2D.component';
import { DirectivesModule } from '../../../shared/directives/directives.module';
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { RouterModule } from "@angular/router";
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
import { FormsModule } from "@angular/forms";
import { Graph2DComponent } from "./graph2D.component";
import { DirectivesModule } from "../../../shared/directives/directives.module";
import { I18nModule } from "../../../shared/modules/translate/i18n.module";
import { TitleCaseModule } from "../../../shared/modules/titlecase.module";
@NgModule({
imports: [FormsModule, RouterModule, CommonModule, NgbModule, DirectivesModule],
declarations: [Graph2DComponent],
exports: [Graph2DComponent],
imports: [
FormsModule,
RouterModule,
CommonModule,
NgbModule,
DirectivesModule,
I18nModule,
TitleCaseModule,
],
declarations: [Graph2DComponent],
exports: [Graph2DComponent],
})
export class Graph2DModule { }
\ No newline at end of file
export class Graph2DModule {}
import { Route } from '@angular/router';
import { Graph2DComponent } from '.';
import { Route } from "@angular/router";
import { Graph2DComponent } from ".";
export const Graph2DRoutes: Route[] = [
{
path: 'graph2D',
component: Graph2DComponent
}
{
path: "graph2D",
component: Graph2DComponent,
},
];
/**
* This barrel file provides the export for the lazy loaded BlankpageComponent.
*/
export * from './graph2D.component';
export * from "./graph2D.component";
export * from './graph2D.routes';
export * from "./graph2D.routes";
<div class="card">
<div class="controls">
<div class="btn-group ddown">
<button
type="button"
class="btn btn-secondary"
style="min-width: 70px;"
(click)=changeZoomType()
>
{{getZoom3DTypeName(graphProps.zoomType)}}
</button>
<div class="btn-group" ngbDropdown role="group" aria-label="Button group with nested dropdown">
<button class="btn btn-secondary dropdown-toggle-split" ngbDropdownToggle></button>
<div class="dropdown-menu" ngbDropdownMenu>
<button
*ngFor="let type of [1,2,3,4]"
class="dropdown-item"
[disabled]="type === graphProps.zoomType"
(click)=changeZoomType(type)
>
{{getZoom3DTypeName(type)}}
</button>
</div>
</div>
</div>
<button
ngbPopover="Zoom +"
triggers="mouseenter:mouseleave"
data-placement="bottom"
class="btn btn-sm btn-secondary"
(click)=zoomIn()
>
<i class="fa fa-plus"></i>
</button>
<button
ngbPopover="Zoom -"
triggers="mouseenter:mouseleave"
data-placement="bottom"
class="btn btn-sm btn-secondary"
(click)=zoomOut()
>
<i class="fa fa-minus"></i>
</button>
<button
ngbPopover="Centrar"
triggers="mouseenter:mouseleave"
data-placement="bottom"
class="btn btn-sm btn-secondary"
(click)=center()
>
<i class="fa fa-arrows"></i>
</button>
<button
closePopoverDirective
class="btn btn-sm btn-secondary"
placement="bottom"
[ngbPopover]=popoverAxesSize
popoverTitle="Rango de ejes"
#popover="ngbPopover"
tiggers="click"
>
<i class="fa fa-arrows-h"></i>
</button>
<ng-template #popoverAxesSize>
<div class="axes-size">
<div class="axe">
<input
type="number"
class="form-control form-control-sm"
[(ngModel)]="graphProps.range.xMin"
[max]="graphProps.range.xMax-1"
[min]="-99"
(change)="onChangeAxesSize('xMin', $event)"
/>
<div class="less-than">
<span>&#8804;</span>x<span>&#8804;</span>
</div>
<input
type="number"
class="form-control form-control-sm"
[(ngModel)]="graphProps.range.xMax"
[max]="99"
[min]="graphProps.range.xMin+1"
(change)="onChangeAxesSize('xMax', $event)"
/>
</div>
<div class="axe">
<input
type="number"
class="form-control form-control-sm"
[(ngModel)]="graphProps.range.yMin"
[max]="graphProps.range.yMax-1"
[min]="-99"
(change)="onChangeAxesSize('yMin', $event)"
/>
<div class="less-than">
<span>&#8804;</span>y<span>&#8804;</span>
</div>
<input
type="number"
class="form-control form-control-sm"
[(ngModel)]="graphProps.range.yMax"
[max]="99"
[min]="graphProps.range.yMin+1"
(change)="onChangeAxesSize('yMax', $event)"
/>
</div>
<div class="axe">
<input
type="number"
class="form-control form-control-sm"
[(ngModel)]="graphProps.range.zMin"
[max]="graphProps.range.zMax-1"
[min]="-99"
(change)="onChangeAxesSize('zMin', $event)"
/>
<div class="less-than">
<span>&#8804;</span>z<span>&#8804;</span>
</div>
<input
type="number"
class="form-control form-control-sm"
[(ngModel)]="graphProps.range.zMax"
[max]="99"
[min]="graphProps.range.zMin+1"
(change)="onChangeAxesSize('zMax', $event)"
/>
</div>
</div>
</ng-template>
<button
ngbPopover="Borrar"
triggers="mouseenter:mouseleave"
data-placement="bottom"
class="btn btn-sm btn-secondary"
(click)=clear()
>
<i class="fa fa-trash"></i>
</button>
<button
[ngbPopover]=popoverConfig
closePopoverDirective
placement="bottom"
tiggers="click"
class="btn btn-sm btn-secondary"
popoverTitle="Configuración"
>
<i class="fa fa-gear"></i>
</button>
<ng-template #popoverConfig>
<div style="width: 140px;">
<label class="d-block">
<input type="checkbox"[checked]=graphProps.showAxes (click)="changeAxesVisibility()">
Mostrar grilla
</label>
<div style="display: flex;">
<span style="margin-right: 8px; align-self: center;">
Quality:
</span>
<input
type="number"
class="form-control form-control-sm"
[(ngModel)]="graphProps.quality"
[max]="99"
[min]="2"
(change)="onChangeQuality()"
style="width: 55px;"
/>
</div>
</div>
</ng-template>
</div>
<div class="card-block contenedor-canvas" >
<animation-control
[minSpeed]="60"
[value]="animationProps.value"
[speed]="animationProps.speed"
[visible]="animationProps.visible"
[playing]="animationProps.playing"
[onChangeSpeed]="onAnimationChangeSpeed"
[onTogglePlay]="onAnimationTogglePlay"
>
</animation-control>
<div #graph3DElement style="width: 100%; height: 100%;">
</div>
</div>
<div class="controls">
<div class="btn-group ddown">
<button
type="button"
class="btn btn-secondary"
style="min-width: 70px"
(click)="changeZoomType()"
>
{{ translationTypes[graphProps.zoomType] | translate | titleCase
}}{{ translationTypesSuffix[graphProps.zoomType] }}
</button>
<div
class="btn-group"
ngbDropdown
role="group"
aria-label="Button group with nested dropdown"
>
<button
class="btn btn-secondary dropdown-toggle-split"
ngbDropdownToggle
></button>
<div class="dropdown-menu" ngbDropdownMenu>
<button
*ngFor="let type of [1, 2, 3, 4]"
class="dropdown-item"
[disabled]="type === graphProps.zoomType"
(click)="changeZoomType(type)"
>
{{ translationTypes[type] | translate | titleCase
}}{{ translationTypesSuffix[type] }}
</button>
</div>
</div>
</div>
<button
ngbPopover="{{ 'i18n.action.zoom' | translate | titleCase }} +"
triggers="mouseenter:mouseleave"
placement="bottom"
class="btn btn-sm btn-secondary"
(click)="zoomIn()"
>
<i class="fa fa-plus"></i>
</button>
<button
ngbPopover="{{ 'i18n.action.zoom' | translate | titleCase }} -"
triggers="mouseenter:mouseleave"
placement="bottom"
class="btn btn-sm btn-secondary"
(click)="zoomOut()"
>
<i class="fa fa-minus"></i>
</button>
<button
ngbPopover="{{ 'i18n.action.center' | translate | titleCase }}"
triggers="mouseenter:mouseleave"
placement="bottom"
class="btn btn-sm btn-secondary"
(click)="center()"
>
<i class="fa fa-arrows"></i>
</button>
<button
closePopoverDirective
class="btn btn-sm btn-secondary"
placement="bottom"
[autoClose]="'outside'"
[ngbPopover]="popoverAxesSize"
popoverTitle="Rango de ejes"
#popover="ngbPopover"
tiggers="click"
>
<i class="fa fa-arrows-h"></i>
</button>
<ng-template #popoverAxesSize>
<div class="axes-size">
<div class="axe">
<input
type="number"
class="form-control form-control-sm"
[(ngModel)]="graphProps.range.xMin"
[max]="graphProps.range.xMax - 1"
[min]="-99"
(change)="onChangeAxesSize('xMin', $event)"
/>
<div class="less-than"><span>&#8804;</span>x<span>&#8804;</span></div>
<input
type="number"
class="form-control form-control-sm"
[(ngModel)]="graphProps.range.xMax"
[max]="99"
[min]="graphProps.range.xMin + 1"
(change)="onChangeAxesSize('xMax', $event)"
/>
</div>
<div class="axe">
<input
type="number"
class="form-control form-control-sm"
[(ngModel)]="graphProps.range.yMin"
[max]="graphProps.range.yMax - 1"
[min]="-99"
(change)="onChangeAxesSize('yMin', $event)"
/>
<div class="less-than"><span>&#8804;</span>y<span>&#8804;</span></div>
<input
type="number"
class="form-control form-control-sm"
[(ngModel)]="graphProps.range.yMax"
[max]="99"
[min]="graphProps.range.yMin + 1"
(change)="onChangeAxesSize('yMax', $event)"
/>
</div>
<div class="axe">
<input
type="number"
class="form-control form-control-sm"
[(ngModel)]="graphProps.range.zMin"
[max]="graphProps.range.zMax - 1"
[min]="-99"
(change)="onChangeAxesSize('zMin', $event)"
/>
<div class="less-than"><span>&#8804;</span>z<span>&#8804;</span></div>
<input
type="number"
class="form-control form-control-sm"
[(ngModel)]="graphProps.range.zMax"
[max]="99"
[min]="graphProps.range.zMin + 1"
(change)="onChangeAxesSize('zMax', $event)"
/>
</div>
</div>
</ng-template>
<button
ngbPopover="{{ 'i18n.action.delete' | translate | titleCase }}"
triggers="mouseenter:mouseleave"
placement="bottom"
class="btn btn-sm btn-secondary"
(click)="clear()"
>
<i class="fa fa-trash"></i>
</button>
<button
[autoClose]="'outside'"
[ngbPopover]="popoverConfig"
closePopoverDirective
placement="bottom"
tiggers="click"
class="btn btn-sm btn-secondary"
popoverTitle="{{ 'i18n.object.settings' | translate | titleCase }}"
>
<i class="fa fa-gear"></i>
</button>
<ng-template #popoverConfig>
<div style="width: 140px">
<label class="d-block">
<input
type="checkbox"
[checked]="graphProps.showEdges"
(click)="changeEdgesVisibility()"
/>
{{ "i18n.object.edges" | translate | titleCase }}
</label>
<label class="d-block">
<input
type="checkbox"
[checked]="graphProps.showAxes"
(click)="changeAxesVisibility()"
/>
{{ "i18n.object.grid" | translate | titleCase }}
</label>
<label class="d-block">
<input
type="checkbox"
[checked]="graphProps.showVertices"
(click)="changeVerticesVisibility()"
/>
{{ "i18n.object.vertices" | translate | titleCase }}
</label>
<div style="display: flex">
<span style="margin-right: 8px; align-self: center">
{{ "i18n.object.quality" | translate | titleCase }}:
</span>
<input
type="number"
class="form-control form-control-sm"
[(ngModel)]="graphProps.quality"
[max]="99"
[min]="2"
(change)="onChangeQuality()"
style="width: 55px"
/>
</div>
<hr style="margin-block: 0.75rem 0.5rem" />
<label class="d-block">
<input
type="checkbox"
[checked]="graphProps.showMetaData"
(click)="changeMetaDataVisibility()"
/>
{{ "i18n.object.metaData" | translate | titleCase }}
</label>
</div>
</ng-template>
</div>
<div class="card-block contenedor-canvas">
<animation-control
[minSpeed]="60"
[value]="animationProps.value"
[speed]="animationProps.speed"
[visible]="animationProps.visible"
[playing]="animationProps.playing"
[onChangeSpeed]="onAnimationChangeSpeed"
[onTogglePlay]="onAnimationTogglePlay"
>
</animation-control>
<div #graph3DElement style="width: 100%; height: 100%"></div>
</div>
</div>
.controls {
margin-top: -40px;
height: 35px;
padding: 4px;
align-self: flex-end;
.button {
float:right;
margin-right: 165px;
margin-top: -55px
}
.ddown {
vertical-align: bottom;
button {
padding: 2.5px 8px 2.5px 3px;
}
}
.axes-size {
width: 165px;
.axe {
display: flex;
&:not(:last-child) {
margin-bottom: 6px;
}
.less-than {
padding: 0 2.5px 0 5px;
font-size: 17px;
letter-spacing: 4px;
}
}
}
display: flex;
justify-content: flex-end;
align-self: flex-end;
width: fit-content;
margin: -35px -1px 7px 0;
.button {
float: right;
margin-right: 165px;
margin-top: -55px;
}
.ddown {
vertical-align: bottom;
button {
padding: 2.5px 8px 2.5px 3px;
}
}
.axes-size {
width: 165px;
.axe {
display: flex;
&:not(:last-child) {
margin-bottom: 6px;
}
.less-than {
padding: 0 2.5px 0 5px;
font-size: 17px;
letter-spacing: 4px;
}
}
}
}
.dropdown-item:disabled{
background-color: #f7f7f7;
color: #9e9e9e;
.dropdown-item:disabled {
background-color: #f7f7f7;
color: #9e9e9e;
}
.d-block{
display: block;
}
\ No newline at end of file
.d-block {
display: block;
}
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing";
import { Graph3DComponent } from './graph3D.component';
import { Graph3DComponent } from "./graph3D.component";
describe('Graph3DComponent', () => {
describe("Graph3DComponent", () => {
let component: Graph3DComponent;
let fixture: ComponentFixture<Graph3DComponent>;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ Graph3DComponent ]
})
.compileComponents();
declarations: [Graph3DComponent],
}).compileComponents();
}));
beforeEach(() => {
......@@ -19,7 +18,7 @@ describe('Graph3DComponent', () => {
fixture.detectChanges();
});
it('should be created', () => {
it("should be created", () => {
expect(component).toBeTruthy();
});
});
import { Component, OnInit, ViewChild, ElementRef, NgZone, AfterViewInit } from '@angular/core';
import * as graph3DLib from 'graph3D';
import { GHCIService } from '../../../shared/services/ghci.service';
import { formatJSON, AnimationProps, Zoom3DType, GraphProps, Default_GraphProps, debounce } from './graph3D.helper';
import {
Component,
OnInit,
ViewChild,
ElementRef,
NgZone,
AfterViewInit,
} from "@angular/core";
import * as graph3DLib from "graph3D";
import { GHCIService } from "../../../shared/services/ghci.service";
import {
formatJSON,
AnimationProps,
Zoom3DType,
GraphProps,
Default_GraphProps,
debounce,
} from "./graph3D.helper";
import { TranslateService } from "@ngx-translate/core";
import { TitleCasePipe } from "../../../shared/pipes/titlecase.pipe";
@Component({
selector: 'graph3d-component',
templateUrl: './graph3D.component.html',
styleUrls: ['./graph3D.component.scss'],
selector: "graph3d-component",
templateUrl: "./graph3D.component.html",
styleUrls: ["./graph3D.component.scss"],
host: {
'(window:resize)': 'onResize($event)'
}
"(window:resize)": "onResize($event)",
},
})
export class Graph3DComponent implements AfterViewInit {
private ghciServiceSub: any;
@ViewChild('graph3DElement')
translateService: any;
titlecasePipe: any;
/**
* Diccionario de traducciones para los tipos de Zoom.
*/
translationTypes = {
[Zoom3DType.Normal]: "i18n.object.normal",
[Zoom3DType.XAxis]: "i18n.object.axis",
[Zoom3DType.YAxis]: "i18n.object.axis",
[Zoom3DType.ZAxis]: "i18n.object.axis",
};
/**
* Diccionario para complementar las traducciones de los tipos de Zoom.
*/
translationTypesSuffix = {
[Zoom3DType.Normal]: "",
[Zoom3DType.XAxis]: " X",
[Zoom3DType.YAxis]: " Y",
[Zoom3DType.ZAxis]: " Z",
};
@ViewChild("graph3DElement", { static: true })
private graph3DRef: ElementRef;
graphProps : GraphProps = Default_GraphProps;
animationProps : AnimationProps = {
graphProps: GraphProps = Default_GraphProps;
animationProps: AnimationProps = {
visible: false,
playing: false,
value: 0,
speed: 1000
speed: 1000,
};
constructor(ghciService: GHCIService, private zone: NgZone) {
constructor(
ghciService: GHCIService,
private zone: NgZone,
public translate: TranslateService
) {
const self = this;
this.ghciServiceSub = ghciService.messages.subscribe(
message => {
if (message.tipo == "canvas3D") {
const figures = JSON.parse(formatJSON(message.resultado));
self.clear();
graph3DLib.drawFigures(figures);
}
else if (message.tipo == "animacion3D") {
const frames = message.resultado.map((frame) => JSON.parse(formatJSON(frame)));
// i18n
this.translateService = translate;
this.titlecasePipe = new TitleCasePipe();
this.ghciServiceSub = ghciService.messages.subscribe((message) => {
if (message.tipo == "canvas3D") {
const figures = JSON.parse(formatJSON(message.resultado));
self.clear();
graph3DLib.drawFigures(figures);
} else if (message.tipo == "animacion3D") {
const frames = message.resultado.map((frame) =>
JSON.parse(formatJSON(frame))
);
self.clear();
self.clear();
this.animationProps.visible = true;
this.animationProps.playing = true;
this.animationProps.value = 0;
this.animationProps.visible = true;
this.animationProps.playing = true;
this.animationProps.value = 0;
graph3DLib.initializeAnimation(frames,
(value) => this.animationProps.value = value
);
graph3DLib.initializeAnimation(
frames,
(value) => (this.animationProps.value = value)
);
graph3DLib.playAnimation();
}
graph3DLib.playAnimation();
}
)
});
}
ngAfterViewInit() {
//this.zone.runOutsideAngular(() => {
graph3DLib.initialize(this.graph3DRef.nativeElement);
graph3DLib.initialize(this.graph3DRef.nativeElement);
//})
}
......@@ -71,54 +117,67 @@ export class Graph3DComponent implements AfterViewInit {
onActivate() {
setTimeout(() => {
this.onResize(null);
})
});
}
onResize(event){
const {width, height} = this.graph3DRef.nativeElement.getBoundingClientRect();
if (width > 0 && height > 0)
graph3DLib.changeSize({width, height});
onResize(_event) {
const { width, height } =
this.graph3DRef.nativeElement.getBoundingClientRect();
if (width > 0 && height > 0) {
graph3DLib.changeSize({ width, height });
}
}
onAnimationChangeSpeed = (value) => {
this.animationProps.speed = parseInt(value);
graph3DLib.changeSpeedAnimation(parseInt(value));
}
};
onAnimationTogglePlay = () => {
if (this.animationProps.playing) {
graph3DLib.pauseAnimation();
}
else {
} else {
graph3DLib.playAnimation();
}
this.animationProps.playing = !this.animationProps.playing;
}
};
public changeZoomType = (type: Zoom3DType = null) => {
if (type != null) {
this.graphProps.zoomType = type;
}
else {
} else {
this.graphProps.zoomType = (this.graphProps.zoomType % 4) + 1;
}
graph3DLib.changeZoomType(this.graphProps.zoomType);
}
};
public changeEdgesVisibility = () => {
this.graphProps.showEdges = !this.graphProps.showEdges;
graph3DLib.showEdges(this.graphProps.showEdges);
};
public changeAxesVisibility = () => {
this.graphProps.showAxes = !this.graphProps.showAxes;
graph3DLib.showAxes(this.graphProps.showAxes);
}
};
public changeVerticesVisibility = () => {
this.graphProps.showVertices = !this.graphProps.showVertices;
graph3DLib.showVertices(this.graphProps.showVertices);
};
public changeMetaDataVisibility = () => {
this.graphProps.showMetaData = !this.graphProps.showMetaData;
graph3DLib.showMetaData(this.graphProps.showMetaData);
};
handleAxesRangeDebounced = debounce(function () {
setTimeout(() =>
graph3DLib.changeAxesSize(this.graphProps.range)
);
setTimeout(() => graph3DLib.changeAxesSize(this.graphProps.range));
}, 500);
public onChangeAxesSize = (v, event) => {
let value = this.graphProps.range[v];
......@@ -126,64 +185,50 @@ export class Graph3DComponent implements AfterViewInit {
const max = parseInt(event.target.max);
if (value == null) {
value = v.search('Min') ? min : max;
value = v.search("Min") ? min : max;
this.graphProps.range[v] = value;
}
if (value < min) {
this.graphProps.range[v] = min;
}
}
if (value > max) {
this.graphProps.range[v] = max;
}
this.handleAxesRangeDebounced();
//graph3DLib.changeAxesSize(this.graphProps.range)
}
};
public onChangeQuality = () => {
const value = this.graphProps.quality;
if (value == null || value <= 1) {
this.graphProps.quality = 30;
}
else {
} else {
this.graphProps.quality = value;
}
graph3DLib.changeOptions({quality: value});
}
graph3DLib.changeOptions({ quality: value });
};
public zoomIn = () => {
graph3DLib.changeZoom(true);
}
};
public zoomOut = () => {
graph3DLib.changeZoom(false);
}
};
public clear = () => {
this.animationProps.visible = false;
graph3DLib.clear();
}
graph3DLib.clearSceneObjects();
};
public center = () => {
this.graphProps = Default_GraphProps;
graph3DLib.reset();
}
public getZoom3DTypeName = (type: Zoom3DType) => {
switch (type) {
case Zoom3DType.Normal:
return 'Normal';
case Zoom3DType.XAxis:
return 'Eje x';
case Zoom3DType.YAxis:
return 'Eje y';
case Zoom3DType.ZAxis:
return 'Eje z';
}
}
};
}
export function formatJSON(jsonString: string) : string {
const regexRot = /\"rot\"\:\((\d*.\d*),(\d*.\d*),(\d*.\d*)\)/g;
const regexPts = /\"pts\"\:\[\((\-?\d*.\d*),(\-?\d*.\d*),(\-?\d*.\d*)\),\((\-?\d*.\d*),(\-?\d*.\d*),(\-?\d*.\d*)\)\]/g;
export function formatJSON(jsonString: string): string {
const regexRot = /\"rot\"\:\((\-?\d*.\d*),(\-?\d*.\d*),(\-?\d*.\d*)\)/g;
const regexPts =
/\"pts\"\:\[\((\-?\d*.\d*),(\-?\d*.\d*),(\-?\d*.\d*)\),\((\-?\d*.\d*),(\-?\d*.\d*),(\-?\d*.\d*)\)\]/g;
return jsonString
.replace(
regexRot, (match, x, y, z) => {
return `"rot": { "x": ${x}, "y": ${y}, "z": ${z} }`
}
)
.replace(
regexPts, (match, x1, y1, z1, x2, y2, z2) => {
return `"pts": [{ "x": ${x1}, "y": ${y1}, "z": ${z1} },{ "x": ${x2}, "y": ${y2}, "z": ${z2} }]`
}
)
return jsonString
.replace(regexRot, (match, x, y, z) => {
return `"rot": { "x": ${x}, "y": ${y}, "z": ${z} }`;
})
.replace(regexPts, (match, x1, y1, z1, x2, y2, z2) => {
return `"pts": [{ "x": ${x1}, "y": ${y1}, "z": ${z1} },{ "x": ${x2}, "y": ${y2}, "z": ${z2} }]`;
});
}
export interface AnimationProps {
visible?: boolean,
playing?: boolean,
value?: number,
speed?: number
visible?: boolean;
playing?: boolean;
value?: number;
speed?: number;
}
export enum Zoom3DType {
Normal = 1,
XAxis,
YAxis,
ZAxis,
Normal = 1,
XAxis,
YAxis,
ZAxis,
}
export interface GraphProps {
zoomType?: Zoom3DType,
showAxes?: boolean,
quality?: number,
range: {
xMin?: number,
xMax?: number,
yMin?: number,
yMax?: number,
zMin?: number,
zMax?: number
}
zoomType?: Zoom3DType;
showAxes?: boolean;
showEdges?: boolean;
showMetaData?: boolean;
showVertices?: boolean;
quality?: number;
range: {
xMin?: number;
xMax?: number;
yMin?: number;
yMax?: number;
zMin?: number;
zMax?: number;
};
}
export const Default_GraphProps : GraphProps = {
zoomType: Zoom3DType.Normal,
showAxes: true,
quality: 30,
range: {
xMin: -10,
xMax: 10,
yMin: -10,
yMax: 10,
zMin: -10,
zMax: 10
}
}
export const Default_GraphProps: GraphProps = {
zoomType: Zoom3DType.Normal,
showAxes: true,
showEdges: false,
showMetaData: false,
showVertices: false,
quality: 30,
range: {
xMin: -10,
xMax: 10,
yMin: -10,
yMax: 10,
zMin: -10,
zMax: 10,
},
};
export function debounce(fn, delay) {
var timer = null;
return function () {
var context = this, args = arguments;
var context = this,
args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
}
import { NgModule} from '@angular/core';
import { CommonModule } from '@angular/common'
import { RouterModule } from '@angular/router';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { FormsModule } from '@angular/forms';
import { Graph3DComponent } from './graph3D.component';
import { AnimationControlComponent } from '../animation-control/animation-control.component';
import { DirectivesModule } from '../../../shared/directives/directives.module';
import { NgModule } from "@angular/core";
import { CommonModule } from "@angular/common";
import { RouterModule } from "@angular/router";
import { NgbModule } from "@ng-bootstrap/ng-bootstrap";
import { FormsModule } from "@angular/forms";
import { Graph3DComponent } from "./graph3D.component";
import { AnimationControlComponent } from "../animation-control/animation-control.component";
import { DirectivesModule } from "../../../shared/directives/directives.module";
import { I18nModule } from "../../../shared/modules/translate/i18n.module";
import { TitleCaseModule } from "../../../shared/modules/titlecase.module";
@NgModule({
imports: [FormsModule, RouterModule, CommonModule, NgbModule, DirectivesModule],
declarations: [
AnimationControlComponent,
Graph3DComponent
],
entryComponents: [
AnimationControlComponent
],
exports: [Graph3DComponent]
imports: [
FormsModule,
RouterModule,
CommonModule,
NgbModule,
DirectivesModule,
I18nModule,
TitleCaseModule,
],
declarations: [AnimationControlComponent, Graph3DComponent],
exports: [Graph3DComponent],
})
export class Graph3DModule { }
export class Graph3DModule {}
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { LoginComponent } from './login.component';
import { NgModule } from "@angular/core";
import { Routes, RouterModule } from "@angular/router";
import { LoginComponent } from "./login.component";
const routes: Routes = [
{ path: '', component: LoginComponent }
];
const routes: Routes = [{ path: "", component: LoginComponent }];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
exports: [RouterModule],
})
export class LoginRoutingModule { }
export class LoginRoutingModule {}
<div class="login-page" style="background: #004869;">
<div class="row">
<div class="col-md-4 push-md-4" style="padding: 55px 35px;background: rgba(255,255,255,0.15);border-radius: 8px;">
<h1>MateFun</h1>
<form role="form">
<div class="form-content">
<div class="form-group">
<input type="text" [(ngModel)]=model.cedula name="cedula" class="form-control input-underline input-lg" placeholder="Usuario">
</div>
<div class="login-page" style="background: #004869">
<div class="row">
<div
class="col-md-4 push-md-4"
style="
padding: 55px 35px;
background: rgba(255, 255, 255, 0.15);
border-radius: 8px;
"
>
<h1>MateFun</h1>
<form role="form">
<div class="form-content">
<div class="form-group">
<input
type="text"
[(ngModel)]="model.cedula"
name="cedula"
class="form-control input-underline input-lg"
placeholder="{{ 'i18n.object.user' | translate | titleCase }}"
/>
</div>
<div class="form-group">
<input type="password" [(ngModel)]=model.password (keyup.enter)=login() name="password" class="form-control input-underline input-lg" placeholder="Contraseña">
</div>
<div class="form-group" style="margin-bottom: 0px;">
<div ngbDropdown class="d-inline-block">
<button class="btn btn-outline-secondary" id="input-lang" ngbDropdownToggle>{{model.language.name}}</button>
<div class="form-group">
<input
type="password"
[(ngModel)]="model.password"
(keyup.enter)="login()"
name="password"
class="form-control input-underline input-lg"
placeholder="{{ 'i18n.object.password' | translate | titleCase }}"
/>
</div>
<!-- <div class="form-group" style="margin-bottom: 0px; text-align: left;">
<div ngbDropdown class="d-inline-block language-switcher">
<button class="btn btn-outline-secondary" id="input-lang" ngbDropdownToggle>
<span class="flag-icon flag-icon-{{model.language.flagCode}}"></span>
{{model.language.name}}
</button>
<div class="dropdown-menu" aria-labelledby="input-lang">
<button class="dropdown-item" *ngFor="let lang of languages" (click)="model.language = lang" >{{lang.name}}</button>
<div class="dropdown-menu-front">
<div class="dropdown-menu-content">
<button class="dropdown-item" *ngFor="let lang of languages" (click)="onChangeLanguage(lang)" >
<span class="flag-icon flag-icon-{{lang.flagCode}}"></span>
{{lang.name}}
</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div> -->
</div>
<a class="btn rounded-btn" style="background: transparent;color: white;cursor: pointer;width: 159px;margin-right: 3px;" (click)=login()> Iniciar Sesión </a>
<a class="btn rounded-btn" style="background: transparent;color: white;cursor: pointer;width: 159px;margin-left: 3px;" (click)=invitado()> Invitado </a>
&nbsp;
<div class="loading" *ngIf="loading">
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
</div>
<div class="login-error" *ngIf="error && !loading">
<ngb-alert [dismissible]="false" [type]="'danger'">
<strong>Error!</strong> {{errorText}}.
</ngb-alert>
</div>
</form>
<a
class="btn rounded-btn"
style="
background: transparent;
color: white;
cursor: pointer;
width: 159px;
margin-right: 3px;
"
(click)="login()"
>
{{ "i18n.action.login" | translate | titleCase }}
</a>
<a
class="btn rounded-btn"
style="
background: transparent;
color: white;
cursor: pointer;
width: 159px;
margin-left: 3px;
"
(click)="invitado()"
>
{{ "i18n.object.guest" | translate | titleCase }}
</a>
&nbsp;
<div class="loading" *ngIf="loading">
<div class="loading-bar"></div>
<div class="loading-bar"></div>
<div class="loading-bar"></div>
</div>
<div class="login-error" *ngIf="error && !loading">
<ngb-alert [dismissible]="false" [type]="'danger'">
<strong>¡Error!</strong>{{ errorText }}
</ngb-alert>
</div>
</form>
</div>
</div>
</div>
......@@ -103,3 +103,35 @@ $topnav-background-color: #222;
position: relative;
top: 20px;
}
.language-switcher {
button {
color: #ccc;
border: 0px;
background-color: transparent;
&:hover, &:active {
background-color: rgba(255,255,255,0.15);
}
&:focus {
box-shadow: none;
}
}
.flag-icon {
margin-right: 10px;
}
.dropdown-menu {
padding: 0px;
margin: 0.5rem 0;
background-color: #004869;
&-front {
background-color: rgba(255,255,255,0.15);
}
&-content {
padding: 0.5rem 0;
}
}
.dropdown-item {
padding-left: 15px;
}
}
\ No newline at end of file
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { ComponentFixture, TestBed, waitForAsync } from "@angular/core/testing";
import { LoginComponent } from './login.component';
import { LoginComponent } from "./login.component";
describe('LoginComponent', () => {
describe("LoginComponent", () => {
let component: LoginComponent;
let fixture: ComponentFixture<LoginComponent>;
beforeEach(async(() => {
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ LoginComponent ]
})
.compileComponents();
declarations: [LoginComponent],
}).compileComponents();
}));
beforeEach(() => {
......@@ -19,7 +18,7 @@ describe('LoginComponent', () => {
fixture.detectChanges();
});
it('should create', () => {
it("should create", () => {
expect(component).toBeTruthy();
});
});