diff --git a/projects/distributed-tracing/src/public-api.ts b/projects/distributed-tracing/src/public-api.ts index 30cb53956..da4035075 100644 --- a/projects/distributed-tracing/src/public-api.ts +++ b/projects/distributed-tracing/src/public-api.ts @@ -95,3 +95,7 @@ export { WaterfallData } from './shared/dashboard/widgets/waterfall/waterfall/wa // Datasources export * from './shared/dashboard/widgets/span-detail/data/span-detail-data-source.model'; export * from './shared/dashboard/widgets/trace-detail/data/trace-detail-data-source.model'; + +// Detail Sheet +export * from './shared/dashboard/interaction/detail-sheet/detail-sheet-interaction.module'; +export * from './shared/dashboard/interaction/detail-sheet/detail-sheet-interaction-handler.service'; diff --git a/projects/observability/src/shared/components/gauge/gauge.component.ts b/projects/observability/src/shared/components/gauge/gauge.component.ts index b14889876..4cddee554 100644 --- a/projects/observability/src/shared/components/gauge/gauge.component.ts +++ b/projects/observability/src/shared/components/gauge/gauge.component.ts @@ -67,7 +67,7 @@ export class GaugeComponent implements OnChanges { const radius = this.buildRadius(boundingBox); return { - origin: this.buildOrigin(boundingBox, radius), + origin: this.buildOrigin(boundingBox), backgroundArc: this.buildBackgroundArc(radius), data: this.buildGaugeData(radius, inputData) }; @@ -107,23 +107,20 @@ export class GaugeComponent implements OnChanges { } private buildRadius(boundingBox: ClientRect): number { - return Math.min( - boundingBox.height - GaugeComponent.GAUGE_AXIS_PADDING, - boundingBox.height / 2 + Math.min(boundingBox.height, boundingBox.width) / 2 - ); + return Math.min(boundingBox.height - GaugeComponent.GAUGE_AXIS_PADDING, boundingBox.width / 2); } - private buildOrigin(boundingBox: ClientRect, radius: number): Point { + private buildOrigin(boundingBox: ClientRect): Point { return { x: boundingBox.width / 2, - y: radius + y: boundingBox.height - GaugeComponent.GAUGE_AXIS_PADDING }; } private calculateInputData(): GaugeInputData | undefined { if (this.value !== undefined && this.maxValue !== undefined && this.maxValue > 0 && this.thresholds.length > 0) { const currentThreshold = this.thresholds.find( - threshold => this.value! >= threshold.start && this.value! < threshold.end + threshold => this.value! >= threshold.start && this.value! <= threshold.end ); if (currentThreshold) { @@ -141,7 +138,7 @@ export interface GaugeThreshold { label: string; start: number; end: number; - color: Color; + color: Color | string; } interface GaugeSvgRendererData { diff --git a/projects/observability/src/shared/dashboard/widgets/gauge/gauge-widget.model.test.ts b/projects/observability/src/shared/dashboard/widgets/gauge/gauge-widget.model.test.ts index dc44f2d34..528afa5fb 100644 --- a/projects/observability/src/shared/dashboard/widgets/gauge/gauge-widget.model.test.ts +++ b/projects/observability/src/shared/dashboard/widgets/gauge/gauge-widget.model.test.ts @@ -3,29 +3,17 @@ import { createModelFactory } from '@hypertrace/dashboards/testing'; import { MODEL_PROPERTY_TYPES } from '@hypertrace/hyperdash-angular'; import { runFakeRxjs } from '@hypertrace/test-utils'; import { of } from 'rxjs'; -import { GaugeWidgetData } from './gauge-widget'; import { GaugeWidgetModel } from './gauge-widget.model'; describe('Gauge widget model', () => { test('uses colors from color map', () => { const modelFactory = createModelFactory(); - const data: GaugeWidgetData = { - value: 5, - maxValue: 10, - thresholds: [ - { - start: 0, - end: 6, - label: 'Medium', - color: Color.Brown1 - } - ] - }; + const value = 5; const spectator = modelFactory(GaugeWidgetModel, { api: { - getData: () => of(data) + getData: () => of(value) }, providers: [ { @@ -34,7 +22,16 @@ describe('Gauge widget model', () => { } ], properties: { - title: 'Test Title' + title: 'Test Title', + maxValue: 10, + thresholds: [ + { + start: 0, + end: 6, + label: 'Medium', + color: Color.Brown1 + } + ] } }); diff --git a/projects/observability/src/shared/dashboard/widgets/gauge/gauge-widget.model.ts b/projects/observability/src/shared/dashboard/widgets/gauge/gauge-widget.model.ts index c770ce3e3..c3f99cf5c 100644 --- a/projects/observability/src/shared/dashboard/widgets/gauge/gauge-widget.model.ts +++ b/projects/observability/src/shared/dashboard/widgets/gauge/gauge-widget.model.ts @@ -1,8 +1,16 @@ -import { Model, ModelApi, ModelProperty, STRING_PROPERTY } from '@hypertrace/hyperdash'; +import { + ARRAY_PROPERTY, + Model, + ModelApi, + ModelProperty, + NUMBER_PROPERTY, + STRING_PROPERTY +} from '@hypertrace/hyperdash'; import { ModelInject, MODEL_API } from '@hypertrace/hyperdash-angular'; import { Observable } from 'rxjs'; +import { map } from 'rxjs/operators'; import { GaugeWidgetData } from './gauge-widget'; - +import { GaugeThresholdModel } from './thresholds/gauge-threshold.model'; @Model({ type: 'gauge-widget' }) @@ -13,10 +21,30 @@ export class GaugeWidgetModel { }) public title?: string; + @ModelProperty({ + key: 'max-value', + type: NUMBER_PROPERTY.type, + required: true + }) + public maxValue!: number; + + @ModelProperty({ + key: 'thresholds', + type: ARRAY_PROPERTY.type, + required: true + }) + public thresholds!: GaugeThresholdModel[]; + @ModelInject(MODEL_API) private readonly api!: ModelApi; public getData(): Observable { - return this.api.getData(); + return this.api.getData().pipe( + map(value => ({ + value: value, + maxValue: this.maxValue, + thresholds: this.thresholds + })) + ); } } diff --git a/projects/observability/src/shared/dashboard/widgets/gauge/thresholds/gauge-threshold.model.ts b/projects/observability/src/shared/dashboard/widgets/gauge/thresholds/gauge-threshold.model.ts new file mode 100644 index 000000000..fda570420 --- /dev/null +++ b/projects/observability/src/shared/dashboard/widgets/gauge/thresholds/gauge-threshold.model.ts @@ -0,0 +1,34 @@ +import { Model, ModelProperty, NUMBER_PROPERTY, STRING_PROPERTY, UNKNOWN_PROPERTY } from '@hypertrace/hyperdash'; + +@Model({ + type: 'gauge-threshold' +}) +export class GaugeThresholdModel { + @ModelProperty({ + key: 'start', + type: NUMBER_PROPERTY.type, + required: true + }) + public start!: number; + + @ModelProperty({ + key: 'end', + type: NUMBER_PROPERTY.type, + required: true + }) + public end!: number; + + @ModelProperty({ + key: 'label', + type: STRING_PROPERTY.type, + required: true + }) + public label!: string; + + @ModelProperty({ + key: 'color', + type: UNKNOWN_PROPERTY.type, + required: true + }) + public color!: string; +}