edit plots
This commit is contained in:
2
pdb-js/.vscode/settings.json
vendored
Normal file
2
pdb-js/.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
{
|
||||||
|
}
|
||||||
@@ -1,14 +1,8 @@
|
|||||||
<style>
|
<style>
|
||||||
:host {
|
:host {
|
||||||
/*
|
|
||||||
height: calc(100% - 29px);
|
|
||||||
*/
|
|
||||||
width: 100%;
|
|
||||||
position: absolute;
|
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.center {
|
.center {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
|
|||||||
@@ -14,9 +14,9 @@
|
|||||||
max-height: unset;
|
max-height: unset;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<h1 mat-dialog-title>Add Plot</h1>
|
<h1 mat-dialog-title>{{data.title}}</h1>
|
||||||
|
|
||||||
<pdb-visualization-page mat-dialog-content #plot></pdb-visualization-page>
|
<pdb-visualization-page mat-dialog-content #plot [defaultConfig]="data.config" [galleryEnabled]="false"></pdb-visualization-page>
|
||||||
|
|
||||||
<div mat-dialog-actions align="end">
|
<div mat-dialog-actions align="end">
|
||||||
<button mat-button mat-dialog-close >Cancel</button>
|
<button mat-button mat-dialog-close >Cancel</button>
|
||||||
|
|||||||
@@ -1,17 +1,22 @@
|
|||||||
import { Component, ElementRef, ViewChild } from '@angular/core';
|
import { AfterViewInit, Component, ElementRef, Inject, ViewChild } from '@angular/core';
|
||||||
import { MatDialogRef } from '@angular/material/dialog';
|
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
|
||||||
|
import { PlotConfig } from 'src/app/plot.service';
|
||||||
import { VisualizationPageComponent } from 'src/app/visualization-page/visualization-page.component';
|
import { VisualizationPageComponent } from 'src/app/visualization-page/visualization-page.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-add-plot-dialog',
|
selector: 'app-add-plot-dialog',
|
||||||
templateUrl: './add-plot-dialog.component.html',
|
templateUrl: './add-plot-dialog.component.html'
|
||||||
styleUrls: ['./add-plot-dialog.component.scss']
|
|
||||||
})
|
})
|
||||||
export class AddPlotDialogComponent {
|
export class AddPlotDialogComponent {
|
||||||
|
|
||||||
@ViewChild("plot") plotElement! :VisualizationPageComponent;
|
@ViewChild("plot") plotElement! :VisualizationPageComponent;
|
||||||
|
|
||||||
constructor(public dialogRef: MatDialogRef<string>){
|
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public dialogRef: MatDialogRef<PlotConfig | undefined>,
|
||||||
|
@Inject(MAT_DIALOG_DATA) public data: {config: PlotConfig, title: string}
|
||||||
|
){
|
||||||
}
|
}
|
||||||
|
|
||||||
onSaveClick(): void {
|
onSaveClick(): void {
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export class DashboardComponent implements OnInit {
|
|||||||
|
|
||||||
if (index < plotWidgetQueue.length){
|
if (index < plotWidgetQueue.length){
|
||||||
const plot = plotWidgetQueue[index];
|
const plot = plotWidgetQueue[index];
|
||||||
const request = this.createPlotRequest(plot.widget)
|
const request = PlotWidget.createPlotRequest(plot.widget);
|
||||||
this.plotService.sendPlotRequest(request).subscribe({
|
this.plotService.sendPlotRequest(request).subscribe({
|
||||||
next: (response: PlotResponse)=> {
|
next: (response: PlotResponse)=> {
|
||||||
plot.plotResponse= response;
|
plot.plotResponse= response;
|
||||||
@@ -71,7 +71,7 @@ export class DashboardComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
createPlotRequest(plotWidget: PlotWidget): PlotRequest {
|
createPlotRequest(plotWidget: PlotWidget): PlotRequest {
|
||||||
|
|
||||||
const height = this.height(plotWidget.size);
|
const height = this.height(plotWidget.size);
|
||||||
@@ -111,6 +111,7 @@ export class DashboardComponent implements OnInit {
|
|||||||
return 900;
|
return 900;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
private repairArrangement(){
|
private repairArrangement(){
|
||||||
const arrangement = this.dashboard!.arrangement || [];
|
const arrangement = this.dashboard!.arrangement || [];
|
||||||
@@ -153,6 +154,7 @@ export class DashboardComponent implements OnInit {
|
|||||||
|
|
||||||
addPlot() {
|
addPlot() {
|
||||||
this.dialog.open(AddPlotDialogComponent,{
|
this.dialog.open(AddPlotDialogComponent,{
|
||||||
|
data: {title: "Add Plot"},
|
||||||
width: 'calc(100% - 1em)',
|
width: 'calc(100% - 1em)',
|
||||||
height: 'calc(100% - 1em)'
|
height: 'calc(100% - 1em)'
|
||||||
}).afterClosed().subscribe((config: PlotConfig | "") => {
|
}).afterClosed().subscribe((config: PlotConfig | "") => {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
.dashboard-card {
|
.dashboard-card {
|
||||||
border: solid 1px red;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -19,8 +19,23 @@
|
|||||||
img {
|
img {
|
||||||
cursor: zoom-in;
|
cursor: zoom-in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
.editable-hovered {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dashboard-card .editable-hovered {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.dashboard-card:hover .editable-hovered {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="dashboard-card" [ngClass]="{'size-medium' : true}">
|
<div class="dashboard-card" [ngClass]="{'size-medium' : true}">
|
||||||
|
<button mat-icon-button (click)="edit()" class="editable-hovered"><img src="/assets/img/edit-outline.svg"/></button>
|
||||||
<mat-spinner *ngIf="!hasRender('main') && !isError"></mat-spinner>
|
<mat-spinner *ngIf="!hasRender('main') && !isError"></mat-spinner>
|
||||||
<img *ngIf="hasRender('main')" [src]="getImageUrl('main')" (click)="showFullScreenImage()" />
|
<img *ngIf="hasRender('main')" [src]="getImageUrl('main')" (click)="showFullScreenImage()" />
|
||||||
<div *ngIf="isError">
|
<div *ngIf="isError">
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core';
|
import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { PlotWidget, PlotWidgetRenderData } from 'src/app/dashboard.service';
|
import { PlotSize, PlotWidget, PlotWidgetRenderData } from 'src/app/dashboard.service';
|
||||||
import { PlotViewComponent } from 'src/app/plot-view/plot-view.component';
|
import { PlotViewComponent } from 'src/app/plot-view/plot-view.component';
|
||||||
import { PlotRequest, PlotResponse, PlotService, RenderOptions } from 'src/app/plot.service';
|
import { PlotConfig, PlotRequest, PlotResponse, PlotService, RenderOptions } from 'src/app/plot.service';
|
||||||
|
import { AddPlotDialogComponent } from '../add-plot-dialog/add-plot-dialog.component';
|
||||||
import { FullScreenPlotDialogComponent } from '../full-screen-plot-dialog/full-screen-plot-dialog.component';
|
import { FullScreenPlotDialogComponent } from '../full-screen-plot-dialog/full-screen-plot-dialog.component';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -19,7 +20,7 @@ export class PlotWidgetComponent implements AfterViewInit {
|
|||||||
|
|
||||||
@ViewChild("plotView") plotView!: PlotViewComponent;
|
@ViewChild("plotView") plotView!: PlotViewComponent;
|
||||||
|
|
||||||
constructor(private dialog: MatDialog, ){}
|
constructor(private dialog: MatDialog, private service: PlotService){}
|
||||||
|
|
||||||
ngAfterViewInit(): void {
|
ngAfterViewInit(): void {
|
||||||
|
|
||||||
@@ -44,4 +45,31 @@ export class PlotWidgetComponent implements AfterViewInit {
|
|||||||
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
edit() {
|
||||||
|
this.dialog.open(AddPlotDialogComponent, {
|
||||||
|
data: {config: this.data.widget.config, title:"Edit Plot"},
|
||||||
|
width: 'calc(100% - 15px)',
|
||||||
|
height: 'calc(100% - 15px)',
|
||||||
|
}).afterClosed().subscribe((config?: PlotConfig) => {
|
||||||
|
if (config !== undefined && config.query.length > 0) {
|
||||||
|
this.data.widget.config = config;
|
||||||
|
|
||||||
|
this.isError = false;
|
||||||
|
this.data.plotResponse = undefined;
|
||||||
|
|
||||||
|
const request = PlotWidget.createPlotRequest(this.data.widget);
|
||||||
|
this.service.sendPlotRequest(request).subscribe({
|
||||||
|
next: (response: PlotResponse)=> {
|
||||||
|
this.data.plotResponse = response;
|
||||||
|
},
|
||||||
|
error: (error:any)=> {
|
||||||
|
this.isError = true;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,8 @@
|
|||||||
|
<style>
|
||||||
|
div[mat-dialog-content] {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
<h1 mat-dialog-title>Create a new dashboard</h1>
|
<h1 mat-dialog-title>Create a new dashboard</h1>
|
||||||
<div mat-dialog-content>
|
<div mat-dialog-content>
|
||||||
<mat-form-field class="pdb-form-full-width">
|
<mat-form-field class="pdb-form-full-width">
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
|
|
||||||
div[mat-dialog-content] {
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
import { Component, ElementRef, Inject, OnInit, ViewChild } from '@angular/core';
|
import { Component, ElementRef, Inject, OnInit, ViewChild } from '@angular/core';
|
||||||
import {MatDialog, MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog';
|
import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog';
|
||||||
import { DashboardCreationData } from 'src/app/dashboard.service';
|
import { DashboardCreationData } from 'src/app/dashboard.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-new-dashboard',
|
selector: 'app-new-dashboard',
|
||||||
templateUrl: './new-dashboard.component.html',
|
templateUrl: './new-dashboard.component.html'
|
||||||
styleUrls: ['./new-dashboard.component.scss']
|
|
||||||
})
|
})
|
||||||
export class NewDashboardComponent implements OnInit {
|
export class NewDashboardComponent implements OnInit {
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { Observable } from 'rxjs';
|
import { Observable } from 'rxjs';
|
||||||
import { PlotConfig, PlotResponse } from './plot.service';
|
import { PlotConfig, PlotRequest, PlotResponse, RenderOptions } from './plot.service';
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root'
|
providedIn: 'root'
|
||||||
@@ -67,6 +67,47 @@ export class PlotWidget extends BaseWidget {
|
|||||||
constructor(override id: string, override size: 'SMALL'|'MEDIUM'|'LARGE', public config: PlotConfig) {
|
constructor(override id: string, override size: 'SMALL'|'MEDIUM'|'LARGE', public config: PlotConfig) {
|
||||||
super(id, 'PLOT', size);
|
super(id, 'PLOT', size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static createPlotRequest(widget: PlotWidget): PlotRequest {
|
||||||
|
|
||||||
|
const height = this.height(widget.size);
|
||||||
|
const width = this.width(widget.size);
|
||||||
|
|
||||||
|
const fullWidth = window.innerWidth-30;
|
||||||
|
const fullHeight = window.innerHeight-30;
|
||||||
|
|
||||||
|
const request = new PlotRequest(
|
||||||
|
(<any>window).submitterId+crypto.randomUUID(),
|
||||||
|
widget.config,
|
||||||
|
{
|
||||||
|
'main': new RenderOptions(height,width, false, true),
|
||||||
|
'fullScreen': new RenderOptions(fullHeight,fullWidth, false, true)
|
||||||
|
}
|
||||||
|
);
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static height(size: PlotSize): number{
|
||||||
|
switch (size) {
|
||||||
|
case 'SMALL':
|
||||||
|
return 300;
|
||||||
|
case 'MEDIUM':
|
||||||
|
return 400;
|
||||||
|
case 'LARGE':
|
||||||
|
return 600;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static width(size: PlotSize): number{
|
||||||
|
switch (size) {
|
||||||
|
case 'SMALL':
|
||||||
|
return 400;
|
||||||
|
case 'MEDIUM':
|
||||||
|
return 600;
|
||||||
|
case 'LARGE':
|
||||||
|
return 900;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PlotSize = 'SMALL'|'MEDIUM'|'LARGE';
|
export type PlotSize = 'SMALL'|'MEDIUM'|'LARGE';
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
<mat-form-field class="pdb-form-number"
|
<mat-form-field class="pdb-form-number"
|
||||||
*ngIf="limitBy !== 'NO_LIMIT'">
|
*ngIf="limitBy !== 'NO_LIMIT'">
|
||||||
|
<mat-label><!--empty label needed for layout reasons--></mat-label>
|
||||||
<input
|
<input
|
||||||
matInput
|
matInput
|
||||||
type="number"
|
type="number"
|
||||||
|
|||||||
@@ -93,20 +93,15 @@ export class PlotService {
|
|||||||
|
|
||||||
|
|
||||||
export class PlotType {
|
export class PlotType {
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
icon: string
|
|
||||||
active: boolean;
|
|
||||||
xAxis: DataType;
|
|
||||||
yAxis: DataType;
|
|
||||||
|
|
||||||
constructor(id: string, name: string, icon: string, active: boolean, xAxis: DataType, yAxis: DataType) {
|
constructor(
|
||||||
this.id = id;
|
public id: string,
|
||||||
this.name = name;
|
public name: string,
|
||||||
this.icon = icon;
|
public icon: string,
|
||||||
this.active = active;
|
public active: boolean,
|
||||||
this.xAxis = xAxis;
|
public xAxis: DataType,
|
||||||
this.yAxis = yAxis;
|
public yAxis: DataType) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compatible(others: Array<PlotType>) : boolean {
|
compatible(others: Array<PlotType>) : boolean {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Component, OnInit, Input, ViewChild } from '@angular/core';
|
import { Component, OnInit, Input, ViewChild, AfterViewInit } from '@angular/core';
|
||||||
import {UntypedFormControl} from '@angular/forms';
|
import {FormControl, UntypedFormControl} from '@angular/forms';
|
||||||
import {Observable} from 'rxjs';
|
import {Observable} from 'rxjs';
|
||||||
import {startWith, map} from 'rxjs/operators';
|
import {startWith, map} from 'rxjs/operators';
|
||||||
import {MatAutocompleteTrigger } from '@angular/material/autocomplete';
|
import {MatAutocompleteTrigger } from '@angular/material/autocomplete';
|
||||||
@@ -12,7 +12,7 @@ import { PlotService, PlotType, AutocompleteResult, Suggestion, ResultMode } fro
|
|||||||
})
|
})
|
||||||
export class QueryAutocompleteComponent implements OnInit {
|
export class QueryAutocompleteComponent implements OnInit {
|
||||||
|
|
||||||
queryField = new UntypedFormControl('');
|
queryField = new FormControl<Suggestion>(new Suggestion("","",0));
|
||||||
|
|
||||||
suggestions = new UntypedFormControl();
|
suggestions = new UntypedFormControl();
|
||||||
|
|
||||||
@@ -20,26 +20,33 @@ export class QueryAutocompleteComponent implements OnInit {
|
|||||||
|
|
||||||
query : string = "";
|
query : string = "";
|
||||||
|
|
||||||
|
suggestionFetcherEnabled = true;
|
||||||
|
|
||||||
@ViewChild(MatAutocompleteTrigger)
|
@ViewChild(MatAutocompleteTrigger)
|
||||||
autocomplete!: MatAutocompleteTrigger;
|
autocomplete!: MatAutocompleteTrigger;
|
||||||
|
|
||||||
|
|
||||||
constructor(private plotService: PlotService) {}
|
constructor(private plotService: PlotService) {
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
const that = this;
|
|
||||||
this.query = "";
|
this.query = "";
|
||||||
this.queryField.valueChanges.subscribe(function(value){
|
this.queryField.valueChanges.subscribe((value) =>{
|
||||||
|
if (value != null) {
|
||||||
if (typeof value == "string") {
|
if (typeof value == "string") {
|
||||||
that.query = value;
|
this.query = value;
|
||||||
}else{
|
}else{
|
||||||
that.query = value.newQuery;
|
this.query = value.newQuery;
|
||||||
|
|
||||||
var el : HTMLInputElement = <HTMLInputElement>document.getElementById('query-autocomplete-input');
|
const el : HTMLInputElement = <HTMLInputElement>document.getElementById('query-autocomplete-input');
|
||||||
el.selectionStart=value.newCaretPosition;
|
el.selectionStart=value.newCaretPosition;
|
||||||
el.selectionEnd=value.newCaretPosition;
|
el.selectionEnd=value.newCaretPosition;
|
||||||
|
}
|
||||||
|
|
||||||
that.fetchSuggestions(value.newCaretPosition);
|
|
||||||
|
if (this.suggestionFetcherEnabled) {
|
||||||
|
this.fetchSuggestions(value.newCaretPosition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.filteredSuggestions = this.suggestions.valueChanges.pipe(
|
this.filteredSuggestions = this.suggestions.valueChanges.pipe(
|
||||||
@@ -61,23 +68,21 @@ export class QueryAutocompleteComponent implements OnInit {
|
|||||||
const that = this;
|
const that = this;
|
||||||
const query = typeof this.queryField.value == "string"
|
const query = typeof this.queryField.value == "string"
|
||||||
? this.queryField.value
|
? this.queryField.value
|
||||||
: this.queryField.value.newQuery;
|
: this.queryField.value!.newQuery;
|
||||||
|
|
||||||
this.plotService
|
this.plotService
|
||||||
.autocomplete(query, caretIndex, ResultMode.CUT_AT_DOT)
|
.autocomplete(query, caretIndex, ResultMode.CUT_AT_DOT)
|
||||||
.subscribe(
|
.subscribe({
|
||||||
(data: AutocompleteResult) => {// success path
|
next: (data: AutocompleteResult) => {
|
||||||
//console.log(JSON.stringify(data.proposals));
|
|
||||||
that.suggestions.setValue(data.proposals);
|
that.suggestions.setValue(data.proposals);
|
||||||
|
|
||||||
that.autocomplete.openPanel();
|
that.autocomplete.openPanel();
|
||||||
},
|
},
|
||||||
(error:any) => console.log(error)
|
error: (error:any) => console.log(error)
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
displaySuggestion(suggestion?: Suggestion): string {
|
displaySuggestion(suggestion?: Suggestion): string {
|
||||||
//console.log("suggestion: "+JSON.stringify(suggestion));
|
|
||||||
return suggestion ? suggestion.newQuery : '';
|
return suggestion ? suggestion.newQuery : '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@
|
|||||||
<pdb-y-axis-definition #y1AxisDefinitionComponent yIndex="1"></pdb-y-axis-definition>
|
<pdb-y-axis-definition #y1AxisDefinitionComponent yIndex="1"></pdb-y-axis-definition>
|
||||||
<pdb-y-axis-definition #y2AxisDefinitionComponent yIndex="2" [hidden]="!y2AxisAvailable"></pdb-y-axis-definition>
|
<pdb-y-axis-definition #y2AxisDefinitionComponent yIndex="2" [hidden]="!y2AxisAvailable"></pdb-y-axis-definition>
|
||||||
|
|
||||||
<mat-checkbox [(ngModel)]="enableGallery">Gallery</mat-checkbox>
|
<mat-checkbox *ngIf="galleryEnabled" [(ngModel)]="enableGallery">Gallery</mat-checkbox>
|
||||||
|
|
||||||
<mat-form-field *ngIf="enableGallery" class="pdb-form-full-width">
|
<mat-form-field *ngIf="enableGallery" class="pdb-form-full-width">
|
||||||
<mat-label>Split By:</mat-label>
|
<mat-label>Split By:</mat-label>
|
||||||
|
|||||||
@@ -15,11 +15,11 @@
|
|||||||
grid:
|
grid:
|
||||||
"query-box query-box date-box" auto
|
"query-box query-box date-box" auto
|
||||||
"filters results results" 1fr
|
"filters results results" 1fr
|
||||||
/ 25.5em 3fr 24em;
|
/ 25.5em 3fr 23.5em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 1000px) {
|
@media screen and (max-width: 900px) {
|
||||||
#visualization {
|
#visualization {
|
||||||
display: grid;
|
display: grid;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
grid:
|
grid:
|
||||||
"query-box" auto
|
"query-box" auto
|
||||||
"date-box" auto
|
"date-box" auto
|
||||||
"filters" auto
|
"filters" min-content
|
||||||
"results" 1fr
|
"results" 1fr
|
||||||
/ 1fr;
|
/ 1fr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import { Component, OnInit, ViewChild } from '@angular/core';
|
import { AfterViewInit, Component, Input, OnInit, ViewChild } from '@angular/core';
|
||||||
import { PlotService, PlotType, PlotRequest, PlotResponse, TagField, FilterDefaults, DataType, YAxisDefinition, AxesTypes, PlotConfig, RenderOptions, RenderOptionsMap } from '../plot.service';
|
import { PlotService, PlotType, PlotRequest, TagField, FilterDefaults, DataType, AxesTypes, PlotConfig, RenderOptions, RenderOptionsMap, Suggestion } from '../plot.service';
|
||||||
import { UntypedFormControl, Validators } from '@angular/forms';
|
import { UntypedFormControl, } from '@angular/forms';
|
||||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||||
import { LimitByComponent } from '../limit-by/limit-by.component';
|
import { LimitByComponent } from '../limit-by/limit-by.component';
|
||||||
import { YAxisDefinitionComponent } from '../y-axis-definition/y-axis-definition.component';
|
import { YAxisDefinitionComponent } from '../y-axis-definition/y-axis-definition.component';
|
||||||
import { QueryAutocompleteComponent } from '../query-autocomplete/query-autocomplete.component';
|
import { QueryAutocompleteComponent } from '../query-autocomplete/query-autocomplete.component';
|
||||||
import { PlotViewComponent, SelectionRange, DateAnchor, LoadingEvent } from '../plot-view/plot-view.component';
|
import { PlotViewComponent, LoadingEvent } from '../plot-view/plot-view.component';
|
||||||
import { GalleryViewComponent } from '../gallery-view/gallery-view.component';
|
import { GalleryViewComponent } from '../gallery-view/gallery-view.component';
|
||||||
import * as moment from 'moment';
|
|
||||||
import { WidgetDimensions } from '../dashboard.service';
|
import { WidgetDimensions } from '../dashboard.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
@@ -15,14 +14,20 @@ import { WidgetDimensions } from '../dashboard.service';
|
|||||||
templateUrl: './visualization-page.component.html',
|
templateUrl: './visualization-page.component.html',
|
||||||
styleUrls: ['./visualization-page.component.scss']
|
styleUrls: ['./visualization-page.component.scss']
|
||||||
})
|
})
|
||||||
export class VisualizationPageComponent implements OnInit {
|
export class VisualizationPageComponent implements OnInit, AfterViewInit {
|
||||||
|
|
||||||
readonly DATE_PATTERN = "YYYY-MM-DD HH:mm:ss"; // for moment-JS
|
readonly DATE_PATTERN = "YYYY-MM-DD HH:mm:ss"; // for moment-JS
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
defaultConfig?: PlotConfig;
|
||||||
|
|
||||||
|
@Input()
|
||||||
|
galleryEnabled = true;
|
||||||
|
|
||||||
dateRange = new UntypedFormControl('2019-10-05 00:00:00 - 2019-10-11 23:59:59');
|
dateRange = new UntypedFormControl('2019-10-05 00:00:00 - 2019-10-11 23:59:59');
|
||||||
|
|
||||||
selectedPlotType = new Array<PlotType>();
|
selectedPlotType = new Array<PlotType>();
|
||||||
plotTypes: Array<any> = [];
|
plotTypes: PlotType[] = [];
|
||||||
|
|
||||||
tagFields: Array<TagField> = new Array<TagField>();
|
tagFields: Array<TagField> = new Array<TagField>();
|
||||||
|
|
||||||
@@ -68,34 +73,69 @@ export class VisualizationPageComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
const that = this;
|
|
||||||
|
|
||||||
(<any>window).initDatePicker();
|
(<any>window).initDatePicker();
|
||||||
|
|
||||||
this.plotTypes = this.plotService.getPlotTypes();
|
this.plotTypes = this.plotService.getPlotTypes();
|
||||||
this.selectedPlotType.push(this.plotTypes[0]);
|
this.selectedPlotType.push(this.plotTypes[0]);
|
||||||
|
|
||||||
that.plotService.getFilterDefaults().subscribe(function(filterDefaults: FilterDefaults) {
|
this.plotService.getFilterDefaults().subscribe((filterDefaults: FilterDefaults) => {
|
||||||
|
|
||||||
filterDefaults.fields.forEach(function(name:string) {
|
filterDefaults.fields.forEach((name:string) => {
|
||||||
that.tagFields.push(new TagField(name));
|
this.tagFields.push(new TagField(name));
|
||||||
},
|
},
|
||||||
(error: any) => {
|
(error: any) => {
|
||||||
that.showError(error.error.message);
|
this.showError(error.error.message);
|
||||||
});
|
});
|
||||||
|
|
||||||
that.groupBy = that.tagFields.filter(val => filterDefaults.groupBy.includes(val.name));
|
const groupByDefaults = this.defaultConfig ? this.defaultConfig.groupBy : filterDefaults.groupBy;
|
||||||
that.splitBy = that.tagFields.find(val => filterDefaults.splitBy == val.name);
|
this.groupBy = this.tagFields.filter(val => groupByDefaults.includes(val.name));
|
||||||
});
|
this.splitBy = this.tagFields.find(val => filterDefaults.splitBy == val.name);
|
||||||
|
|
||||||
|
if (this.defaultConfig) {
|
||||||
|
this.plot();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ngAfterViewInit(): void {
|
||||||
|
if (this.defaultConfig) {
|
||||||
|
const c = this.defaultConfig;
|
||||||
|
this.query.suggestionFetcherEnabled = false;
|
||||||
|
this.query.queryField.setValue(new Suggestion(c.query, c.query, c.query.length));
|
||||||
|
this.query.suggestionFetcherEnabled = true;
|
||||||
|
|
||||||
|
this.selectedPlotType = this.plotTypes.filter(pt => c.aggregates.includes(pt.id));
|
||||||
|
this.changePlotType(this.selectedPlotType);
|
||||||
|
this.updateDateRange(c.dateRange, false);
|
||||||
|
this.limitbycomponent.limitBy = c.limitBy;
|
||||||
|
this.limitbycomponent.limit = c.limit;
|
||||||
|
this.y1AxisDefinitionComponent.yAxisScale = c.y1.axisScale;
|
||||||
|
this.y1AxisDefinitionComponent.minYValue = c.y1.rangeMin;
|
||||||
|
this.y1AxisDefinitionComponent.maxYValue = c.y1.rangeMax;
|
||||||
|
this.y1AxisDefinitionComponent.yAxisUnit = c.y1.rangeUnit;
|
||||||
|
|
||||||
|
if (c.y2) {
|
||||||
|
this.y2AxisDefinitionComponent.yAxisScale = c.y2.axisScale;
|
||||||
|
this.y2AxisDefinitionComponent.minYValue = c.y2.rangeMin;
|
||||||
|
this.y2AxisDefinitionComponent.maxYValue = c.y2.rangeMax;
|
||||||
|
this.y2AxisDefinitionComponent.yAxisUnit = c.y2.rangeUnit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loading(event: LoadingEvent) {
|
loading(event: LoadingEvent) {
|
||||||
this.plotJobActive = event.loading;
|
this.plotJobActive = event.loading;
|
||||||
}
|
}
|
||||||
|
|
||||||
updateDateRange(newDateRange: string) {
|
updateDateRange(newDateRange: string, updatePlot=true) {
|
||||||
(<HTMLInputElement>document.getElementById("search-date-range")).value = newDateRange;
|
(<HTMLInputElement>document.getElementById("search-date-range")).value = newDateRange;
|
||||||
|
if (updatePlot){
|
||||||
this.plot();
|
this.plot();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
changePlotType(selectedPlotTypes: Array<PlotType>) {
|
changePlotType(selectedPlotTypes: Array<PlotType>) {
|
||||||
const compatiblePlotTypes = this.plotTypes.filter(pt => pt.compatible(selectedPlotTypes));
|
const compatiblePlotTypes = this.plotTypes.filter(pt => pt.compatible(selectedPlotTypes));
|
||||||
|
|||||||
@@ -48,9 +48,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
$( document ).ready(function() {
|
$( document ).ready(function() {
|
||||||
//initDatePicker();
|
|
||||||
|
|
||||||
|
|
||||||
initInvaders('results');
|
initInvaders('results');
|
||||||
document.addEventListener("invadersPause", function(event) {
|
document.addEventListener("invadersPause", function(event) {
|
||||||
pauseInvaders();
|
pauseInvaders();
|
||||||
|
|||||||
Reference in New Issue
Block a user