From 57e5de121fb69781f55235f3fa8ff554bbc66693 Mon Sep 17 00:00:00 2001 From: "jose.ignacio.fagian" <nachofagian@gmail.com> Date: Mon, 11 Jun 2018 20:40:44 -0300 Subject: [PATCH] =?UTF-8?q?Se=20comienza=20con=20la=20integracion=20del=20?= =?UTF-8?q?componente=203D=20al=20proyecto=20y=20se=20a=C3=B1ade=20la=20re?= =?UTF-8?q?ferencia=20a=20la=20libreria=20graph3D=20en=20github?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Frontend Angular 4/package.json | 3 +- .../app/layout/matefun/matefun.component.html | 5 ++ .../app/layout/matefun/matefun.component.ts | 2 + .../src/app/layout/matefun/matefun.module.ts | 3 + .../animation-control.component.html | 44 ++++++++++ .../animation-control.component.scss | 0 .../animation-control.component.spec.ts | 25 ++++++ .../animation-control.component.ts | 26 ++++++ .../plotter/graph3D/graph3D.component.html | 84 ++++++++++++++++++ .../plotter/graph3D/graph3D.component.scss | 20 +++++ .../plotter/graph3D/graph3D.component.spec.ts | 25 ++++++ .../plotter/graph3D/graph3D.component.ts | 87 +++++++++++++++++++ .../layout/plotter/graph3D/graph3D.helper.ts | 17 ++++ .../layout/plotter/graph3D/graph3D.module.ts | 21 +++++ .../src/app/shared/services/ghci.service.ts | 8 +- 15 files changed, 368 insertions(+), 2 deletions(-) create mode 100644 Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.html create mode 100644 Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.scss create mode 100644 Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.spec.ts create mode 100644 Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.ts create mode 100644 Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.html create mode 100644 Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.scss create mode 100644 Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.spec.ts create mode 100644 Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.ts create mode 100644 Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.helper.ts create mode 100644 Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.module.ts diff --git a/Frontend Angular 4/package.json b/Frontend Angular 4/package.json index 6e4eb10..95d1e85 100644 --- a/Frontend Angular 4/package.json +++ b/Frontend Angular 4/package.json @@ -31,7 +31,8 @@ "ng2-slider-component": "^1.0.9", "rxjs": "^5.1.0", "tippy.js": "^1.2.0", - "zone.js": "^0.8.4" + "zone.js": "^0.8.4", + "graph3D": "git://github.com/ifagian/graph3D#master" }, "devDependencies": { "@angular/cli": "1.2.6", diff --git a/Frontend Angular 4/src/app/layout/matefun/matefun.component.html b/Frontend Angular 4/src/app/layout/matefun/matefun.component.html index 0e2031a..07a5f6a 100644 --- a/Frontend Angular 4/src/app/layout/matefun/matefun.component.html +++ b/Frontend Angular 4/src/app/layout/matefun/matefun.component.html @@ -78,6 +78,11 @@ <ng-template ngbTabContent> <canvas-component (canvasComp)=canvasC></canvas-component> </ng-template> + </ngb-tab> + <ngb-tab id="FigurasBtn2" title="Figuras 3D"> + <ng-template ngbTabContent> + <graph3d-component (graph3DComp)=graph3DComp></graph3d-component> + </ng-template> </ngb-tab> </ngb-tabset> diff --git a/Frontend Angular 4/src/app/layout/matefun/matefun.component.ts b/Frontend Angular 4/src/app/layout/matefun/matefun.component.ts index eef61f1..7a45f4c 100644 --- a/Frontend Angular 4/src/app/layout/matefun/matefun.component.ts +++ b/Frontend Angular 4/src/app/layout/matefun/matefun.component.ts @@ -19,6 +19,7 @@ import { CodemirrorComponent } from 'ng2-codemirror'; import { NgbPopoverConfig, NgbPopover} from '@ng-bootstrap/ng-bootstrap'; import { NgbPopoverWindow } from '@ng-bootstrap/ng-bootstrap/popover/popover'; import { NotificacionService } from '../../shared/services/notificacion.service'; +import { Graph3DComponent } from '../plotter/graph3D/graph3D.component'; import 'rxjs/add/operator/catch'; import 'rxjs/add/operator/map'; @@ -351,6 +352,7 @@ export class MateFunComponent { } @ViewChild(CanvasComponent) canvasC: CanvasComponent; + @ViewChild(Graph3DComponent) graph3DComp: Graph3DComponent; funcionSTR: string = 'Math.sin(x)*x*x-20'; consola: string = ''; 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 850c3c3..bad4eed 100644 --- a/Frontend Angular 4/src/app/layout/matefun/matefun.module.ts +++ b/Frontend Angular 4/src/app/layout/matefun/matefun.module.ts @@ -10,11 +10,14 @@ import { MateFunRoutingModule } from './matefun-routing.module'; import { CodemirrorModule } from 'ng2-codemirror'; import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; import { NotificacionModule } from '../../notificacion/notificacion.module'; +import { Graph3DModule } from '../plotter/graph3D/graph3D.module'; + @NgModule({ imports: [ CommonModule, FormsModule, CanvasModule, + Graph3DModule, NotificacionModule, MateFunRoutingModule, CodemirrorModule, diff --git a/Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.html b/Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.html new file mode 100644 index 0000000..fe8fec8 --- /dev/null +++ b/Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.html @@ -0,0 +1,44 @@ +<div *ngIf="visible"> + <button + class="btn btn-sm btn-secondary" + data-placement="bottom" + *ngIf="!playing" + style=" float:left; margin-top: -5px; margin-right: 5px" + (click)="onTogglePlay()" + > + <i class="fa fa-play"></i> + </button> + + <button + class="btn btn-sm btn-secondary" + data-placement="bottom" + *ngIf="playing" + style=" float:left; margin-top: -5px; margin-right: 5px" + (click)="onTogglePlay()" + > + <i class="fa fa-pause"></i> + </button> + + <ngb-progressbar + style="float: left; width: 45%" + type="info" + [value]="value" + > + </ngb-progressbar> + + <span + style="float: right; margin-left: 10px" + > + {{speed}}ms + </span> + + <input + style="float: right; width: 20%" + type="range" + [min]="minSpeed" + max="1500" + [value]="speed" + (input)="onChangeSpeed($event.target.value)" + /> + +</div> \ No newline at end of file diff --git a/Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.scss b/Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.scss new file mode 100644 index 0000000..e69de29 diff --git a/Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.spec.ts b/Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.spec.ts new file mode 100644 index 0000000..15a503f --- /dev/null +++ b/Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.spec.ts @@ -0,0 +1,25 @@ +// import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +// import { AnimationControlComponent } from './animation-control.component'; + +// describe('AnimationControlComponent', () => { +// let component: AnimationControlComponent; +// let fixture: ComponentFixture<AnimationControlComponent>; + +// beforeEach(async(() => { +// TestBed.configureTestingModule({ +// declarations: [ AnimationControlComponent ] +// }) +// .compileComponents(); +// })); + +// beforeEach(() => { +// fixture = TestBed.createComponent(AnimationControlComponent); +// component = fixture.componentInstance; +// fixture.detectChanges(); +// }); + +// it('should be created', () => { +// expect(component).toBeTruthy(); +// }); +// }); diff --git a/Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.ts b/Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.ts new file mode 100644 index 0000000..085382c --- /dev/null +++ b/Frontend Angular 4/src/app/layout/plotter/animation-control/animation-control.component.ts @@ -0,0 +1,26 @@ +import { Component, OnInit, Input } from '@angular/core'; + +@Component({ + selector: 'animation-control', + templateUrl: './animation-control.component.html', + styleUrls: ['./animation-control.component.scss'] +}) +export class AnimationControlComponent implements OnInit { + + @Input() visible: boolean; + @Input() playing: boolean; + + @Input() value: number; + + @Input() minSpeed: number; + @Input() speed: number; + + @Input() onTogglePlay: Function; + @Input() onChangeSpeed: Function; + + constructor() { } + + ngOnInit() { + } + +} diff --git a/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.html b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.html new file mode 100644 index 0000000..d5e2616 --- /dev/null +++ b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.html @@ -0,0 +1,84 @@ +<div class="card"> + <div class="controls"> + <div class="btn-group ddown" style=""> + <button type="button" class="btn btn-secondary">Normal</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 class="dropdown-item">Eje x</button> + <button class="dropdown-item">Eje y</button> + <button class="dropdown-item">Eje z</button> + </div> + </div> + </div> + + <button + ngbPopover="Zoom +" + triggers="mouseenter:mouseleave" + data-placement="bottom" + class="btn btn-sm btn-secondary" + (click)=zoomMas() + > + <i class="fa fa-plus"></i> + </button> + + <button + ngbPopover="Zoom -" + triggers="mouseenter:mouseleave" + data-placement="bottom" + class="btn btn-sm btn-secondary" + (click)=zoomMas() + > + <i class="fa fa-minus"></i> + </button> + + <button + ngbPopover="Centrar" + triggers="mouseenter:mouseleave" + data-placement="bottom" + class="btn btn-sm btn-secondary" + (click)=zoomMas() + > + <i class="fa fa-arrows"></i> + </button> + + <button + ngbPopover="Borrar" + triggers="mouseenter:mouseleave" + data-placement="bottom" + class="btn btn-sm btn-secondary" + (click)=zoomMas() + > + <i class="fa fa-trash"></i> + </button> + + <button + ngbPopover="Configuración" + triggers="mouseenter:mouseleave" + data-placement="bottom" + class="btn btn-sm btn-secondary" + (click)=zoomMas() + > + <i class="fa fa-gear"></i> + </button> + + </div> + + <div class="card-block contenedor-canvas" > + <animation-control + [minSpeed]="60" + [value]="animation.value" + [speed]="animation.speed" + [visible]="animation.visible" + [playing]="animation.playing" + [onChangeSpeed]="onAnimationChangeSpeed" + [onTogglePlay]="onAnimationTogglePlay" + > + </animation-control> + + + <div #graph3DElement style="width: 100%; height: 100%;"> + </div> + </div> + +</div> diff --git a/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.scss b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.scss new file mode 100644 index 0000000..43a8fe9 --- /dev/null +++ b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.scss @@ -0,0 +1,20 @@ +.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 5px; + } + } +} \ No newline at end of file diff --git a/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.spec.ts b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.spec.ts new file mode 100644 index 0000000..513c245 --- /dev/null +++ b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { Graph3DComponent } from './graph3D.component'; + +describe('Graph3DComponent', () => { + let component: Graph3DComponent; + let fixture: ComponentFixture<Graph3DComponent>; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ Graph3DComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(Graph3DComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should be created', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.ts b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.ts new file mode 100644 index 0000000..7acf104 --- /dev/null +++ b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.component.ts @@ -0,0 +1,87 @@ +import { Component, OnInit, ViewChild, ElementRef, NgZone } from '@angular/core'; +import * as graph3DLib from 'graph3d'; +import { GHCIService } from '../../../shared/services/ghci.service'; +import { formatJSON, AnimationProps } from './graph3D.helper'; + +@Component({ + selector: 'graph3d-component', + templateUrl: './graph3D.component.html', + styleUrls: ['./graph3D.component.scss'], + host: { + '(window:resize)': 'onResize($event)' + } +}) +export class Graph3DComponent implements OnInit { + + private ghciServiceSub: any; + + @ViewChild('graph3DElement') + private graph3DRef: ElementRef; + + private animation : AnimationProps = { + visible: false, + playing: false, + value: 0, + t:1, + speed: 1000 + }; + + constructor(private ghciService: GHCIService, private zone: NgZone) { + this.ghciServiceSub = ghciService.messages.subscribe( + message => { + if (message.tipo == "canvas3D") { + const figures = JSON.parse(formatJSON(message.resultado)); + + graph3DLib.drawFigures(figures); + } + else if (message.tipo == "animacion3D") { + const frames = message.resultado.map((frame) => JSON.parse(formatJSON(frame))); + + this.animation.visible = true; + this.animation.playing = true; + this.animation.value = 0; + + graph3DLib.initializeAnimation(frames, + (value) => this.animation.value = value + ); + + graph3DLib.playAnimation(); + } + } + ) + } + + ngOnInit() { + this.zone.runOutsideAngular(() => { + graph3DLib.initialize(this.graph3DRef.nativeElement); + }) + } + + ngOnDestroy() { + if (this.ghciServiceSub) { + this.ghciServiceSub.unsubscribe(); + } + } + + onResize(event){ + const {width, height} = this.graph3DRef.nativeElement.getBoundingClientRect(); + + graph3DLib.changeSize({width, height}); + } + + onAnimationChangeSpeed = (value) => { + this.animation.speed = parseInt(value); + graph3DLib.changeSpeedAnimation(parseInt(value)); + } + + onAnimationTogglePlay = () => { + if (this.animation.playing) { + graph3DLib.pauseAnimation(); + } + else { + graph3DLib.playAnimation(); + } + + this.animation.playing = !this.animation.playing; + } +} diff --git a/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.helper.ts b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.helper.ts new file mode 100644 index 0000000..d143e78 --- /dev/null +++ b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.helper.ts @@ -0,0 +1,17 @@ +export function formatJSON(jsonString: string) : string { + const regexRot = /\"rot\"\:\((\d*.\d*),(\d*.\d*),(\d*.\d*)\)/g; + + return jsonString.replace( + regexRot, (match, x, y, z) => { + return `"rot": { "x": ${x}, "y": ${y}, "z": ${z} }` + } + ) +} + +export interface AnimationProps { + visible?: boolean, + playing?: boolean, + value?: number, + speed?: number, + t: any +} \ 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 new file mode 100644 index 0000000..0497860 --- /dev/null +++ b/Frontend Angular 4/src/app/layout/plotter/graph3D/graph3D.module.ts @@ -0,0 +1,21 @@ +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'; + +@NgModule({ + imports: [FormsModule, RouterModule, CommonModule, NgbModule], + declarations: [ + AnimationControlComponent, + Graph3DComponent + ], + entryComponents: [ + AnimationControlComponent + ], + exports: [Graph3DComponent] +}) + +export class Graph3DModule { } diff --git a/Frontend Angular 4/src/app/shared/services/ghci.service.ts b/Frontend Angular 4/src/app/shared/services/ghci.service.ts index 8a24162..475461f 100644 --- a/Frontend Angular 4/src/app/shared/services/ghci.service.ts +++ b/Frontend Angular 4/src/app/shared/services/ghci.service.ts @@ -294,10 +294,16 @@ export class GHCIService { this.startPrompt.bind(this); this.startPrompt(); // console.log(x); - }else if (json_server_message.tipo == 'canvas' || json_server_message.tipo == 'animacion' || json_server_message.tipo == 'graph'){ + } else if (json_server_message.tipo == 'canvas' || + json_server_message.tipo == 'animacion' || + json_server_message.tipo == 'graph') { document.getElementById("FigurasBtn").click() this.focusConsole(); this.messages.next(json_server_message); + } else if (json_server_message.tipo == 'canvas3D' || + json_server_message.tipo == 'animacion3D') { + this.focusConsole(); + this.messages.next(json_server_message); } } -- GitLab