diff --git a/Frontend Angular 4/src/app/layout/matefun/matefun.module.ts b/Frontend Angular 4/src/app/layout/matefun/matefun.module.ts index 479210f297ed023b2a10a2b55c57e4de48a8f1e7..2850b570783e96e0bc53317cb624cb0b8ed6acd3 100755 --- a/Frontend Angular 4/src/app/layout/matefun/matefun.module.ts +++ b/Frontend Angular 4/src/app/layout/matefun/matefun.module.ts @@ -12,6 +12,8 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { NotificacionModule } from '../../notificacion/notificacion.module'; import { Graph2DModule } from '../plotter/graph2D/graph2D.module'; import { Graph3DModule } from '../plotter/graph3D/graph3D.module'; +import { ClosePopoverOnOutsideClickDirective } from '../../shared/utils/closePopoverDirective'; + @NgModule({ imports: [ @@ -30,7 +32,12 @@ import { Graph3DModule } from '../plotter/graph3D/graph3D.module'; ConfirmComponent, SeleccionarDirectorioComp ], - declarations: [MateFunComponent,ConfirmComponent,SeleccionarDirectorioComp], + declarations: [ + MateFunComponent, + ConfirmComponent, + SeleccionarDirectorioComp, + ClosePopoverOnOutsideClickDirective + ], exports: [MateFunComponent] }) diff --git a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.html b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.html index 845db4ba7d9edfc5d21da6a581360bd2d4fc885f..939fcb1eff9fb19def085ad40dbfc2c5cc958889 100755 --- a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.html +++ b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.html @@ -1,58 +1,144 @@ -<div class="card"> - <div class="card-block contenedor-canvas" > - <button ngbPopover="Zoom +" triggers="mouseenter:mouseleave" data-placement="bottom" class="btn btn-sm btn-secondary" style="float:right; margin-right: 165px; margin-top: -55px" (click)=zoomIn() ><i class="fa fa-plus"></i></button> - <button ngbPopover="Zoom -" triggers="mouseenter:mouseleave" data-placement="bottom" class="btn btn-sm btn-secondary" style="float:right; margin-right: 132px; margin-top: -55px" (click)=zoomOut() ><i class="fa fa-minus"></i></button> - <button ngbPopover="Centrar" triggers="mouseenter:mouseleave" data-placement="bottom" class="btn btn-sm btn-secondary" style=" float:right; margin-right: 99px; margin-top: -55px" (click)="recenterPlot()" ><i class="fa fa-arrows"></i></button> - <button ngbPopover="Borrar" triggers="mouseenter:mouseleave" data-placement="bottom" class="btn btn-sm btn-secondary" style=" float:right; margin-right: 66px; margin-top: -55px" (click)="cleanPlot()" ><i class="fa fa-trash"></i></button> - - <button ngbPopover="Descargar PNG" triggers="mouseenter:mouseleave" data-placement="bottom" class="btn btn-sm btn-secondary" style="float:right; margin-right: 33px; margin-top: -55px" (click)=exportPlot() ><i class="fa fa-download"></i></button> - <a id="download-plot" class="download-plot" href="#" download="Plot.svg" style="display: none">Download Canvas</a> - - <button class="btn btn-sm btn-secondary" data-placement="bottom" *ngIf="!animation.playing && animation.data.length>0" style=" float:left; margin-top: -5px; margin-right: 5px" (click)="runAnimation()" ><i class="fa fa-play"></i></button> - <button class="btn btn-sm btn-secondary" data-placement="bottom" *ngIf="animation.playing && animation.data.length>0" style=" float:left; margin-top: -5px; margin-right: 5px" (click)="pauseAnimation()" ><i class="fa fa-pause"></i></button> - - <ngb-progressbar style="float: left; width: 90%" *ngIf="animation.data.length>0" type="info" [value]="((animation.currentFrame+1)/animation.data.length)*100"></ngb-progressbar> - - <button - [ngbPopover]=popoverConfig +<!-- 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" closePopoverOnOutsideClick - placement="bottom" - style=" float:right; margin-right: 1px; margin-top: -55px" - tiggers="click" - class="btn btn-sm btn-secondary" + [ngbPopover]=popoverCanvas 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]=animation.boton (click)="multiGraf(value)" > - Multi gráficas: - </label> + #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 style="display: flex;"> - <span style="margin-right: 8px; align-self: center;"> - Zoom: - </span> - - <input - type="number" - class="form-control form-control-sm" - [max]="10000" - [min]="2" - [(ngModel)]=animation.zoo - (change)="setZoom()" - style="width: 70px;" - /> + <!-- Settings Popover Content --> + <ng-template #popoverCanvas> + <div class="form-group settings-popover-content"> + <div class="chart-controls setting-section"> + <label> + <input + type="checkbox" + name="settings.grid" + class="form-control form-control-sm" + [checked]=settings.grid + (click)="toggleGrid()"> + Grilla + </label> + <label> + <input + type="checkbox" + name="settings.axis" + class="form-control form-control-sm" + [checked]=settings.axis + (click)="toggleAxis()"> + Ejes + </label> + <label> + <input + type="checkbox" + name="settings.tip" + class="form-control form-control-sm" + [checked]=settings.tip + (click)="toggleTip()"> + Tip + </label> + </div> + <div class="animation-controls setting-section" + [class.disabled]="animation.data.length === 0"> + <label>Velocidad de animación:</label> + <label> + <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()'> + <i class="fa fa-undo"></i> + </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"> + 1x + </span> + </label> </div> </div> - </ng-template> - <div id="graph2D-container" style="height: 100%; width: 100%;"> + </ng-template> + + <!-- Animation --> + <!-- <div class="animation" *ngIf="animation.data.length>0"> --> + <div class="animation"> + <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> + + <ngb-progressbar + class="progressbar" + type="info" + [value]="((animation.currentFrame+1)/animation.data.length)*100"> + </ngb-progressbar> + </div> + + <!-- Graph Container --> + <div #graph2DContainer id="graph2D-container"> + </div> - </div> </div> \ No newline at end of file diff --git a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.scss b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..2586cd3f2f709619f5be3dcd74626e2f074d280f --- /dev/null +++ b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.scss @@ -0,0 +1,71 @@ +// 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; + } +} + +// Settings Popover +.settings-popover-content { + width: 12em; + label { + display: 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; + } + &.disabled { + color: #ccc; + i.fa { + color: #ccc; + } + } + } +} + +// Animation +.animation { + .btn-play, .btn-pause { + float:left; + margin-top: -5px; + margin-right: 5px; + } + .progressbar { + float: left; + width: 90%; + } +} + +#graph2D-container { + height: 100%; + width: 100%; +} + + diff --git a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.ts b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.ts index cbe0568b13d681c2a598e89630ee0f9d4d4220fb..457088f8475e9347f2558f9c75e44ff17ee1b146 100755 --- a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.ts +++ b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.component.ts @@ -1,21 +1,35 @@ -import { Component } from '@angular/core'; +import { Component, ViewChild, ElementRef } from '@angular/core'; import { GHCIService } from '../../../shared/services/ghci.service'; import functionPlot from 'function-plot'; -import { Animation, toJSON, triggerDownload } from './graph2D.helper'; +import { Animation, Setting, toJSON, triggerDownload } from './graph2D.helper'; @Component({ moduleId: module.id, selector: 'graph2D-component', templateUrl: './graph2D.component.html', + styleUrls: ['./graph2D.component.scss'], host: { - + '(window:resize)': 'onResize($event)' } }) export class Graph2DComponent { + // Ghci Service private ghciServiceSub: any; - private instance: null; + // Chart Container - DOM Element + @ViewChild('graph2DContainer') + private graph2DRef: ElementRef; + + // Chart Instance + private instance: any; + + // Settings + settings: Setting = { + axis: true, + grid: true, + tip: true + } private funciones= []; @@ -23,6 +37,7 @@ export class Graph2DComponent { private conjunto= []; + // Animation state animation: Animation = { data: [], timer: null, @@ -146,11 +161,11 @@ export class Graph2DComponent { color: color }); } + let bounding = this.getBounding(); this.instance = functionPlot({ target: '#graph2D-container', - width: 620, - height: 450, - + width: bounding.width, + height: bounding.height, tip: { color: 'green' }, xAxis: { label: 'x - axis', scale: 'linear', @@ -170,11 +185,13 @@ export class Graph2DComponent { case 'canvas': { var shapesData = JSON.parse(canvas.resultado); var shapesDataNormalized = this.normalizeShapesData(shapesData); - this.instance = null; + let bounding = this.getBounding(); + this.cleanPlot(); this.instance = functionPlot({ target: '#graph2D-container', - width: 800, - height: 700, + width: bounding.width, + height: bounding.height, + grid: true, xAxis: { label: 'x - axis', scale: 'linear', @@ -190,7 +207,8 @@ export class Graph2DComponent { }) break; } - case 'animacion': { + 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)); @@ -212,10 +230,12 @@ export class Graph2DComponent { */ ngAfterViewInit() { if (!this.instance) { + let bounding = this.getBounding(); this.instance = functionPlot({ target: '#graph2D-container', - width: 800, - height: 700, + width: bounding.width, + height: bounding.height, + grid: true, xAxis: { label: 'x - axis', scale: 'linear', @@ -239,6 +259,33 @@ export class Graph2DComponent { } } + /** + * On Resize Event. + */ + onResize(event){ + let instance = this.instance; + let bounding = this.getBounding(); + //if (bounding.width > 0) { + console.log('yes'); + instance.options.width = bounding.width; + instance.options.height = bounding.height; + instance.build(); + //} + } + + onClickMe(event) { + console.log('click'); + } + + /** + * @name getBounding + * @desc get the measures of the container of the graph + */ + private getBounding = function() { + const {width, height} = this.graph2DRef.nativeElement.getBoundingClientRect(); + return {width, height} + } + /** * @name updateFrame * @desc update data for Function Plot and redraw the graph @@ -248,10 +295,11 @@ export class Graph2DComponent { this.instance.options.data = d; this.instance.draw(); } else { + let bounding = this.getBounding(); this.instance = functionPlot({ target: '#graph2D-container', - width: 800, - height: 700, + width: bounding.width, + height: bounding.height, xAxis: { label: 'x - axis', scale: 'linear', @@ -260,10 +308,7 @@ export class Graph2DComponent { type: 'discrete' } }, - data: d, - plugins: [ - functionPlot.plugins.zoomBox() - ] + data: d }) } // Update Frame @@ -308,6 +353,40 @@ export class Graph2DComponent { this.instance.removeAllGraphs(); } + /** + * @name increaseSpeed + * @desc Increase Speed Animation + */ + public increaseSpeed = function() { + this.animation.speed *= 1.5; + console.log(this.animation.speed); + } + + + /** + * @name toggleGrid + * @desc Show and Hide Grid + */ + public toggleGrid = function () { + //this.instance.toggleGrid(); + } + + /** + * @name toggleAxis + * @desc Show and Hide Axis + */ + public toggleAxis = function () { + //this.instance.toggleAxis(); + } + + /** + * @name toggleTip + * @desc Show and Hide Tip + */ + public toggleTip = function () { + //this.instance.toggleTip(); + } + /** * @name zoomOut * @desc Zoom Out Button Control diff --git a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.helper.ts b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.helper.ts index b5a275181b51231f0aee145ea2b454092c9dc8ea..2016d2f3d2e40c97d816374ef49695178bcd0885 100644 --- a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.helper.ts +++ b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.helper.ts @@ -9,6 +9,12 @@ export interface Animation { zoo: number, } +export interface Setting { + axis: boolean, + grid: boolean, + tip: boolean +} + export function toJSON(data: string) : string { console.log('data',data); const regexPts = /(?:\"pts\"\:\[(?:\((x),(y)\))+,?\])/g; diff --git a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.module.ts b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.module.ts index 0083535d10b24663644361ec9b43cd594ecca823..ca89efba92142575ea86c8bcee10cfd6ea586e2a 100755 --- a/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.module.ts +++ b/Frontend Angular 4/src/app/layout/plotter/graph2D/graph2D.module.ts @@ -8,7 +8,7 @@ import { Graph2DComponent } from './graph2D.component'; @NgModule({ imports: [FormsModule, RouterModule, CommonModule, NgbModule], declarations: [Graph2DComponent], - exports: [Graph2DComponent] + exports: [Graph2DComponent], }) export class Graph2DModule { } \ No newline at end of file diff --git a/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.module.ts b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.module.ts index 1df9cb3ac17e699be6577bd704445c58701a6023..03009354df81f306e4fa8f63bdf70c1731ab5606 100644 --- a/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.module.ts +++ b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.module.ts @@ -5,15 +5,13 @@ 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 { ClosePopoverOnOutsideClickDirective } from '../../../shared/utils/closePopoverDirective'; @NgModule({ imports: [FormsModule, RouterModule, CommonModule, NgbModule], declarations: [ AnimationControlComponent, - Graph3DComponent, - ClosePopoverOnOutsideClickDirective + Graph3DComponent ], entryComponents: [ AnimationControlComponent