make the drop down for "combine with" dynamic
This commit is contained in:
@@ -2,6 +2,7 @@ import { BrowserModule } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { NgModule, enableProdMode } from '@angular/core';
|
||||
import { HttpClientModule } from '@angular/common/http';
|
||||
import { ReactiveFormsModule } from '@angular/forms';
|
||||
|
||||
import { AppRoutingModule } from './app-routing.module';
|
||||
import { AppComponent } from './app.component';
|
||||
@@ -26,6 +27,7 @@ import { YAxisRangeComponent } from './y-axis-range/y-axis-range.component';
|
||||
imports: [
|
||||
BrowserModule,
|
||||
AppRoutingModule,
|
||||
ReactiveFormsModule,
|
||||
MatSelectModule,MatFormFieldModule, MatInputModule,
|
||||
BrowserAnimationsModule,
|
||||
HttpClientModule
|
||||
|
||||
@@ -13,7 +13,7 @@ This page describes how to use this tool.
|
||||
|
||||
<h2>Why not use one of the existing monitoring tools?</h2>
|
||||
<p>
|
||||
There are many monitoring tools out there.
|
||||
There are many tools out there that do monitoring in one way or the other. Here are a few:
|
||||
<a href="https://newrelic.com" target="_blank" rel="nofollow" class="external-link">New Relic</a>,
|
||||
<a href="https://www.splunk.com" target="_blank" rel="nofollow" class="external-link">Splunk</a>,
|
||||
<a href="https://www.elastic.co/products/kibana" target="_blank" rel="nofollow" class="external-link">Kibana</a> (<a href="https://www.elastic.co/products/elastic-stack" target="_blank" rel="nofollow" class="external-link">ELK</a>),
|
||||
@@ -27,15 +27,17 @@ There are many monitoring tools out there.
|
||||
<a href="https://www.influxdata.com/products/influxdb-overview/" target="_blank" rel="nofollow" class="external-link">InfluxDB</a>
|
||||
+ <a href="https://www.influxdata.com/time-series-platform/chronograf/" target="_blank" rel="nofollow" class="external-link">Chronograf</a>,
|
||||
<a href="http://opentsdb.net/" target="_blank" rel="nofollow" class="external-link">OpenTSDB</a>,
|
||||
<a href="https://www.nagios.org/" target="_blank" rel="nofollow" class="external-link">Nagios</a>/<a href="https://icinga.com/" target="_blank" rel="nofollow" class="external-link">Icinga</a>,
|
||||
Heka,
|
||||
Bosun,
|
||||
Wavefront,
|
||||
Dropwizard,
|
||||
Druid.io,
|
||||
Bleemo,
|
||||
Site24x7,
|
||||
Sitescope,
|
||||
<a href="https://www.nagios.org/" target="_blank" rel="nofollow" class="external-link">Nagios</a>/<a href="https://icinga.com/" target="_blank" rel="nofollow" class="external-link">Icinga</a>,
|
||||
<a href="https://sentry.io/" target="_blank" rel="nofollow" class="external-link">Sentry</a>,
|
||||
<a href="https://github.com/mozilla-services/heka" target="_blank" rel="nofollow" class="external-link">Heka</a>,
|
||||
<a href="https://bosun.org/" target="_blank" rel="nofollow" class="external-link">Bosun</a>,
|
||||
<a href="https://www.wavefront.com/" target="_blank" rel="nofollow" class="external-link">Wavefront</a>,
|
||||
<a href="https://www.instana.com/supported-technologies/dropwizard/" target="_blank" rel="nofollow" class="external-link">Dropwizard</a>,
|
||||
<a href="https://druid.apache.org/" target="_blank" rel="nofollow" class="external-link">Druid.io</a>,
|
||||
<a href="https://bleemeo.com/" target="_blank" rel="nofollow" class="external-link">Bleemo</a>,
|
||||
<a href="https://www.site24x7.com/" target="_blank" rel="nofollow" class="external-link">Site24x7</a>,
|
||||
<a href="https://www.datadoghq.com/" target="_blank" rel="nofollow" class="external-link">Datadog</a>,
|
||||
<a href="https://www.microfocus.com/en-us/products/sitescope-application-monitoring/overview" target="_blank" rel="nofollow" class="external-link">Sitescope</a>,
|
||||
and many more. None of them provides the visualizations we had in mind. We wanted to plot each value of the time series data individually, so that we can identify the
|
||||
response times of a single request. But tools like Splunk, Kibana, Chronograf or Grafana only plot aggregated data (average, min/max, percentiles).
|
||||
<p>
|
||||
|
||||
@@ -14,18 +14,23 @@ export class PlotService {
|
||||
|
||||
constructor(private http: HttpClient) {
|
||||
this.plotTypes = new Array<PlotType>();
|
||||
this.plotTypes.push(new PlotType("Scatter", "scatter-chart2", true));
|
||||
this.plotTypes.push(new PlotType("Heatmap", "heatmap", false));
|
||||
this.plotTypes.push(new PlotType("Contour", "contour-chart", false));
|
||||
this.plotTypes.push(new PlotType("Cumulative Distribution", "cumulative-distribution-chart", true));
|
||||
this.plotTypes.push(new PlotType("Histogram", "histogram", false));
|
||||
this.plotTypes.push(new PlotType("Ridgelines", "ridgelines", false));
|
||||
this.plotTypes.push(new PlotType("Quantile-Quantile", "quantile-quantile", false));
|
||||
this.plotTypes.push(new PlotType("Parallel Requests", "parallel-requests-chart", true));
|
||||
this.plotTypes.push(new PlotType("Violin", "violin-chart", false));
|
||||
this.plotTypes.push(new PlotType("Strip", "strip-chart", false));
|
||||
this.plotTypes.push(new PlotType("Pie", "pie-chart", false));
|
||||
this.plotTypes.push(new PlotType("Bar", "bar-chart", false));
|
||||
this.plotTypes.push(new PlotType(
|
||||
"Scatter",
|
||||
"scatter-chart2",
|
||||
true,
|
||||
DataType.Time,
|
||||
DataType.Duration));
|
||||
this.plotTypes.push(new PlotType("Heatmap", "heatmap", false, DataType.Other, DataType.Other));
|
||||
this.plotTypes.push(new PlotType("Contour", "contour-chart", false, DataType.Time, DataType.Duration));
|
||||
this.plotTypes.push(new PlotType("Cumulative Distribution", "cumulative-distribution-chart", true, DataType.Percent, DataType.Duration));
|
||||
this.plotTypes.push(new PlotType("Histogram", "histogram", false, DataType.Group, DataType.Duration));
|
||||
this.plotTypes.push(new PlotType("Ridgelines", "ridgelines", false, DataType.Other, DataType.Other));
|
||||
this.plotTypes.push(new PlotType("Quantile-Quantile", "quantile-quantile", false, DataType.Other, DataType.Other));
|
||||
this.plotTypes.push(new PlotType("Parallel Requests", "parallel-requests-chart", true, DataType.Time, DataType.Count));
|
||||
this.plotTypes.push(new PlotType("Violin", "violin-chart", false, DataType.Group, DataType.Duration));
|
||||
this.plotTypes.push(new PlotType("Strip", "strip-chart", false, DataType.Group, DataType.Duration));
|
||||
this.plotTypes.push(new PlotType("Pie", "pie-chart", false, DataType.Other, DataType.Other));
|
||||
this.plotTypes.push(new PlotType("Bar", "bar-chart", false, DataType.Other, DataType.Other));
|
||||
|
||||
this.tagFields = new Array<TagField>();
|
||||
|
||||
@@ -57,12 +62,35 @@ export class PlotType {
|
||||
name: string;
|
||||
icon: string
|
||||
active: boolean;
|
||||
xAxis: DataType;
|
||||
yAxis: DataType;
|
||||
|
||||
constructor(name: string, icon: string, active: boolean) {
|
||||
constructor(name: string, icon: string, active: boolean, xAxis: DataType, yAxis: DataType) {
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
this.active = active;
|
||||
this.xAxis = xAxis;
|
||||
this.yAxis = yAxis;
|
||||
}
|
||||
|
||||
compatible(other: PlotType) : boolean {
|
||||
|
||||
const xEqual = this.xAxis === other.xAxis;
|
||||
const yEqual = this.yAxis === other.yAxis;
|
||||
const anyIsOther = this.xAxis === DataType.Other
|
||||
|| this.yAxis === DataType.Other
|
||||
|| other.xAxis === DataType.Other
|
||||
|| other.yAxis === DataType.Other;
|
||||
|
||||
var result = xEqual || yEqual;
|
||||
|
||||
// if either dimension is Other, then this plot is not compatible with any other plot
|
||||
result = result && !anyIsOther;
|
||||
|
||||
// is not the same
|
||||
result = result && this.name != other.name;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
export class TagField {
|
||||
@@ -73,4 +101,13 @@ export class TagField {
|
||||
}
|
||||
}
|
||||
|
||||
export enum DataType {
|
||||
Time,
|
||||
Duration,
|
||||
Percent,
|
||||
Count,
|
||||
Group,
|
||||
Metric,
|
||||
Other
|
||||
}
|
||||
|
||||
|
||||
@@ -7,19 +7,21 @@
|
||||
<input matInput placeholder="Query" value="{{query}}" />
|
||||
</div>
|
||||
<div id="filters">
|
||||
<button mat-button>
|
||||
<button mat-button (click)="plot()">
|
||||
<img src="assets/img/scatter-chart2.svg" class="icon-inline" aria-hidden="true" title="create plot" />
|
||||
Plot
|
||||
</button>
|
||||
<button mat-button>
|
||||
<!--
|
||||
<button mat-button (click)="gallery()">
|
||||
<img src="assets/img/four-squares-line.svg" class="icon-inline" aria-hidden="true" title="Create Gallery (only active if 'Split' is set)" />
|
||||
Gallery
|
||||
</button>
|
||||
-->
|
||||
|
||||
|
||||
<mat-form-field>
|
||||
<mat-label>Type:</mat-label>
|
||||
<mat-select [(value)]="selectedPlotType">
|
||||
<mat-select [formControl]="selectedPlotType">
|
||||
<mat-option *ngFor="let plotType of plotTypes" [value]="plotType.name">
|
||||
<img src="assets/img/{{plotType.icon}}.svg" class="icon-select" /> {{plotType.name}}
|
||||
</mat-option>
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { PlotService, PlotType } from '../plot.service';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { FormControl } from '@angular/forms';
|
||||
|
||||
@Component({
|
||||
selector: 'pdb-visualization-page',
|
||||
@@ -8,10 +11,12 @@ import { PlotService, PlotType } from '../plot.service';
|
||||
})
|
||||
export class VisualizationPageComponent implements OnInit {
|
||||
|
||||
selectedPlotType: string;
|
||||
availablePlotTypes = {};
|
||||
|
||||
selectedPlotType = new FormControl('');
|
||||
plotTypes: Array<any>;
|
||||
|
||||
selectedCombinePlotType: string;
|
||||
selectedCombinePlotType = new FormControl('');
|
||||
combinePlotTypes: Array<any>;
|
||||
|
||||
tagFields: Array<any>;
|
||||
@@ -23,21 +28,42 @@ export class VisualizationPageComponent implements OnInit {
|
||||
|
||||
query: string;
|
||||
|
||||
constructor(private plotService: PlotService) {
|
||||
constructor(private plotService: PlotService, private http: HttpClient) {
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
const that = this;
|
||||
this.query = "pod=*";
|
||||
this.plotTypes = this.plotService.getPlotTypes();
|
||||
this.selectedPlotType = this.plotTypes[0].name;
|
||||
this.selectedPlotType.setValue(this.plotTypes[0].name);
|
||||
|
||||
this.combinePlotTypes = this.plotTypes;
|
||||
this.plotTypes.forEach(pt => this.availablePlotTypes[pt.name] = pt);
|
||||
|
||||
this.combinePlotTypes = this.getCombinablePlotTypes(this.selectedPlotType.value);
|
||||
|
||||
this.tagFields = this.plotService.getTagFields();
|
||||
this.yAxis = "log";
|
||||
this.yAxisUnit = "MINUTES";
|
||||
this.minYValue = 0;
|
||||
this.maxYValue = 120;
|
||||
|
||||
|
||||
this.selectedPlotType.valueChanges.subscribe(function(selectedMainPlotType){
|
||||
that.combinePlotTypes = that.getCombinablePlotTypes(selectedMainPlotType);
|
||||
});
|
||||
}
|
||||
|
||||
getCombinablePlotTypes(selectedMainPlotType) : Array<any>{
|
||||
// get compatible plot types
|
||||
const mainPlotType = this.availablePlotTypes[selectedMainPlotType];
|
||||
|
||||
const compatiblePlotTypes = this.plotTypes.filter(pt => pt.compatible(mainPlotType));
|
||||
console.log(compatiblePlotTypes);
|
||||
return compatiblePlotTypes;
|
||||
}
|
||||
|
||||
plot(){
|
||||
console.log("plot clicked");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user