Commit 90200d00 authored by Diego Rey's avatar Diego Rey
Browse files

Fixed plotter 2D html, added speed control and fixed resposive grid

parent e842aa8d
...@@ -12,6 +12,8 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap'; ...@@ -12,6 +12,8 @@ import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { NotificacionModule } from '../../notificacion/notificacion.module'; import { NotificacionModule } from '../../notificacion/notificacion.module';
import { Graph2DModule } from '../plotter/graph2D/graph2D.module'; import { Graph2DModule } from '../plotter/graph2D/graph2D.module';
import { Graph3DModule } from '../plotter/graph3D/graph3D.module'; import { Graph3DModule } from '../plotter/graph3D/graph3D.module';
import { ClosePopoverOnOutsideClickDirective } from '../../shared/utils/closePopoverDirective';
@NgModule({ @NgModule({
imports: [ imports: [
...@@ -30,7 +32,12 @@ import { Graph3DModule } from '../plotter/graph3D/graph3D.module'; ...@@ -30,7 +32,12 @@ import { Graph3DModule } from '../plotter/graph3D/graph3D.module';
ConfirmComponent, ConfirmComponent,
SeleccionarDirectorioComp SeleccionarDirectorioComp
], ],
declarations: [MateFunComponent,ConfirmComponent,SeleccionarDirectorioComp], declarations: [
MateFunComponent,
ConfirmComponent,
SeleccionarDirectorioComp,
ClosePopoverOnOutsideClickDirective
],
exports: [MateFunComponent] exports: [MateFunComponent]
}) })
......
<div class="card"> <!-- Buttons Controls -->
<div class="card-block contenedor-canvas" > <div class="buttons-control">
<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 +"
<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> class="btn btn-sm btn-secondary btn-zoom-increase"
<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> data-placement="bottom"
<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> triggers="mouseenter:mouseleave"
(click)=zoomIn() >
<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> <i class="fa fa-plus"></i>
<a id="download-plot" class="download-plot" href="#" download="Plot.svg" style="display: none">Download Canvas</a> </button>
<button ngbPopover="Zoom -"
<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> class="btn btn-sm btn-secondary btn-zoom-decrease"
<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> data-placement="bottom"
triggers="mouseenter:mouseleave"
<ngb-progressbar style="float: left; width: 90%" *ngIf="animation.data.length>0" type="info" [value]="((animation.currentFrame+1)/animation.data.length)*100"></ngb-progressbar> (click)=zoomOut() >
<i class="fa fa-minus"></i>
<button </button>
[ngbPopover]=popoverConfig <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 closePopoverOnOutsideClick
placement="bottom" [ngbPopover]=popoverCanvas
style=" float:right; margin-right: 1px; margin-top: -55px"
tiggers="click"
class="btn btn-sm btn-secondary"
popoverTitle="Configuración" popoverTitle="Configuración"
> #popover="ngbPopover"
<i class="fa fa-gear"></i> tiggers="click">
</button> <i class="fa fa-gear"></i>
</button>
<ng-template #popoverConfig> </div>
<div style="width: 140px;">
<label class="d-block">
<input type="checkbox" [checked]=animation.boton (click)="multiGraf(value)" >
Multi gráficas:
</label>
<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;"> <!-- Settings Popover Content -->
<span style="margin-right: 8px; align-self: center;"> <ng-template #popoverCanvas>
Zoom: <div class="form-group settings-popover-content">
</span> <div class="chart-controls setting-section">
<label>
<input <input
type="number" type="checkbox"
class="form-control form-control-sm" name="settings.grid"
[max]="10000" class="form-control form-control-sm"
[min]="2" [checked]=settings.grid
[(ngModel)]=animation.zoo (click)="toggleGrid()">
(change)="setZoom()" Grilla
style="width: 70px;" </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>
</div> </div>
</ng-template> </ng-template>
<div id="graph2D-container" style="height: 100%; width: 100%;">
<!-- 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> </div>
</div> </div>
\ No newline at end of file
// 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%;
}
import { Component } from '@angular/core'; import { Component, ViewChild, ElementRef } from '@angular/core';
import { GHCIService } from '../../../shared/services/ghci.service'; import { GHCIService } from '../../../shared/services/ghci.service';
import functionPlot from 'function-plot'; import functionPlot from 'function-plot';
import { Animation, toJSON, triggerDownload } from './graph2D.helper'; import { Animation, Setting, toJSON, triggerDownload } from './graph2D.helper';
@Component({ @Component({
moduleId: module.id, moduleId: module.id,
selector: 'graph2D-component', selector: 'graph2D-component',
templateUrl: './graph2D.component.html', templateUrl: './graph2D.component.html',
styleUrls: ['./graph2D.component.scss'],
host: { host: {
'(window:resize)': 'onResize($event)'
} }
}) })
export class Graph2DComponent { export class Graph2DComponent {
// Ghci Service
private ghciServiceSub: any; 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= []; private funciones= [];
...@@ -23,6 +37,7 @@ export class Graph2DComponent { ...@@ -23,6 +37,7 @@ export class Graph2DComponent {
private conjunto= []; private conjunto= [];
// Animation state
animation: Animation = { animation: Animation = {
data: [], data: [],
timer: null, timer: null,
...@@ -146,11 +161,11 @@ export class Graph2DComponent { ...@@ -146,11 +161,11 @@ export class Graph2DComponent {
color: color color: color
}); });
} }
let bounding = this.getBounding();
this.instance = functionPlot({ this.instance = functionPlot({
target: '#graph2D-container', target: '#graph2D-container',
width: 620, width: bounding.width,
height: 450, height: bounding.height,
tip: { color: 'green' }, tip: { color: 'green' },
xAxis: { label: 'x - axis', xAxis: { label: 'x - axis',
scale: 'linear', scale: 'linear',
...@@ -170,11 +185,13 @@ export class Graph2DComponent { ...@@ -170,11 +185,13 @@ export class Graph2DComponent {
case 'canvas': { case 'canvas': {
var shapesData = JSON.parse(canvas.resultado); var shapesData = JSON.parse(canvas.resultado);
var shapesDataNormalized = this.normalizeShapesData(shapesData); var shapesDataNormalized = this.normalizeShapesData(shapesData);
this.instance = null; let bounding = this.getBounding();
this.cleanPlot();
this.instance = functionPlot({ this.instance = functionPlot({
target: '#graph2D-container', target: '#graph2D-container',
width: 800, width: bounding.width,
height: 700, height: bounding.height,
grid: true,
xAxis: { xAxis: {
label: 'x - axis', label: 'x - axis',
scale: 'linear', scale: 'linear',
...@@ -190,7 +207,8 @@ export class Graph2DComponent { ...@@ -190,7 +207,8 @@ export class Graph2DComponent {
}) })
break; break;
} }
case 'animacion': { case 'animacion': {
this.cleanPlot();
var animationData = canvas.resultado.map(res => JSON.parse(res)); var animationData = canvas.resultado.map(res => JSON.parse(res));
for (var frame of animationData) { for (var frame of animationData) {
this.animation.data.push(this.normalizeShapesData(frame)); this.animation.data.push(this.normalizeShapesData(frame));
...@@ -212,10 +230,12 @@ export class Graph2DComponent { ...@@ -212,10 +230,12 @@ export class Graph2DComponent {
*/ */
ngAfterViewInit() { ngAfterViewInit() {
if (!this.instance) { if (!this.instance) {
let bounding = this.getBounding();
this.instance = functionPlot({ this.instance = functionPlot({
target: '#graph2D-container', target: '#graph2D-container',
width: 800, width: bounding.width,
height: 700, height: bounding.height,
grid: true,
xAxis: { xAxis: {
label: 'x - axis', label: 'x - axis',
scale: 'linear', scale: 'linear',
...@@ -239,6 +259,33 @@ export class Graph2DComponent { ...@@ -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 * @name updateFrame
* @desc update data for Function Plot and redraw the graph * @desc update data for Function Plot and redraw the graph
...@@ -248,10 +295,11 @@ export class Graph2DComponent { ...@@ -248,10 +295,11 @@ export class Graph2DComponent {
this.instance.options.data = d; this.instance.options.data = d;
this.instance.draw(); this.instance.draw();
} else { } else {
let bounding = this.getBounding();
this.instance = functionPlot({ this.instance = functionPlot({
target: '#graph2D-container', target: '#graph2D-container',
width: 800, width: bounding.width,
height: 700, height: bounding.height,
xAxis: { xAxis: {
label: 'x - axis', label: 'x - axis',
scale: 'linear', scale: 'linear',
...@@ -260,10 +308,7 @@ export class Graph2DComponent { ...@@ -260,10 +308,7 @@ export class Graph2DComponent {
type: 'discrete' type: 'discrete'
} }
}, },
data: d, data: d
plugins: [
functionPlot.plugins.zoomBox()
]
}) })
} }
// Update Frame // Update Frame
...@@ -308,6 +353,40 @@ export class Graph2DComponent { ...@@ -308,6 +353,40 @@ export class Graph2DComponent {
this.instance.removeAllGraphs(); 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 * @name zoomOut
* @desc Zoom Out Button Control * @desc Zoom Out Button Control
......
...@@ -9,6 +9,12 @@ export interface Animation { ...@@ -9,6 +9,12 @@ export interface Animation {
zoo: number, zoo: number,
} }
export interface Setting {
axis: boolean,
grid: boolean,
tip: boolean
}
export function toJSON(data: string) : string { export function toJSON(data: string) : string {
console.log('data',data); console.log('data',data);
const regexPts = /(?:\"pts\"\:\[(?:\((x),(y)\))+,?\])/g; const regexPts = /(?:\"pts\"\:\[(?:\((x),(y)\))+,?\])/g;
......
...@@ -8,7 +8,7 @@ import { Graph2DComponent } from './graph2D.component'; ...@@ -8,7 +8,7 @@ import { Graph2DComponent } from './graph2D.component';
@NgModule({ @NgModule({
imports: [FormsModule, RouterModule, CommonModule, NgbModule], imports: [FormsModule, RouterModule, CommonModule, NgbModule],
declarations: [Graph2DComponent], declarations: [Graph2DComponent],
exports: [Graph2DComponent] exports: [Graph2DComponent],
}) })