Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Commit

Permalink
fix(chart): Fix dynamic heatfield generation that was not possible.
Browse files Browse the repository at this point in the history
Fixes an issue where the heatfields could not be created dynamic.

Fixes #1580
  • Loading branch information
Lukas Holzer authored and lukasholzer committed Oct 5, 2020
1 parent a3e6936 commit 796b9e9
Show file tree
Hide file tree
Showing 7 changed files with 274 additions and 74 deletions.
4 changes: 3 additions & 1 deletion apps/components-e2e/src/components/chart/chart.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { DtChartModule } from '@dynatrace/barista-components/chart';
import { BasicChart } from './chart/chart';
import { ChartHighchartsUI } from './highcharts/chart-highcharts-ui';
import { PieChart } from './pie-chart/pie-chart';
import { Heatfield } from './heatfield/heatfield';
import {
DT_UI_TEST_CONFIG,
DT_DEFAULT_UI_TEST_CONFIG,
Expand All @@ -29,6 +30,7 @@ import {
const routes: Route[] = [
{ path: '', component: BasicChart },
{ path: 'highcharts', component: ChartHighchartsUI },
{ path: 'heatfield', component: Heatfield },
{
path: 'selection-area',
loadChildren: () =>
Expand All @@ -40,7 +42,7 @@ const routes: Route[] = [
];

@NgModule({
declarations: [BasicChart, ChartHighchartsUI, PieChart],
declarations: [BasicChart, ChartHighchartsUI, PieChart, Heatfield],
imports: [CommonModule, RouterModule.forChild(routes), DtChartModule],
exports: [],
providers: [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/**
* @license
* Copyright 2020 Dynatrace LLC
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { Selector } from 'testcafe';
import { resetWindowSizeToDefault, waitForAngular } from '../../../utils';

fixture('Chart Heatfield')
.page('http://localhost:4200/chart/heatfield')
.beforeEach(async () => {
await resetWindowSizeToDefault();
await waitForAngular();
});

const chart = (chartIndex = 1) => Selector('.dt-chart').nth(chartIndex);
const heatfieldMarker = (chartIndex?: number) =>
chart(chartIndex).find('.dt-chart-heatfield-marker');
export const overlay = Selector('.dt-chart-heatfield-overlay');

test('should display a heatfield correctly', async (testController: TestController) => {
await testController
.expect(heatfieldMarker().count)
.eql(1)
.expect(heatfieldMarker().getBoundingClientRectProperty('width'))
.eql(108)
.click(chart())
.click(heatfieldMarker())
.expect(overlay.textContent)
.match(/heatfield content/g)
.click(heatfieldMarker())
.expect(overlay.exists)
.notOk();
});

test('should update the heatfields programmatically', async (testController: TestController) => {
await testController
.expect(heatfieldMarker().count)
.eql(1)
.click(heatfieldMarker())
.expect(overlay.exists)
.ok()
.click(heatfieldMarker())
.expect(overlay.exists)
.notOk()
.click(Selector('#update-heatfield-stream'))
.expect(heatfieldMarker().count)
.eql(2)
.click(heatfieldMarker().nth(1))
.expect(overlay.textContent)
.ok();
});
36 changes: 36 additions & 0 deletions apps/components-e2e/src/components/chart/heatfield/heatfield.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<dt-chart [options]="options" [series]="series">
<dt-chart-heatfield
*ngFor="let heatfield of heatfields"
[start]="heatfield.start"
[end]="heatfield.end"
>
heatfield content
</dt-chart-heatfield>
</dt-chart>

<button (click)="heatfields = [{ start: 3000, end: 4000 }]">
update Heatfields
</button>
<hr />

<dt-chart [options]="options" [series]="series">
<dt-chart-heatfield
*ngFor="let heatfield of heatfields$ | async"
[start]="heatfield.start"
[end]="heatfield.end"
>
heatfield content
</dt-chart-heatfield>
</dt-chart>

<button
id="update-heatfield-stream"
(click)="
heatfields$.next([
{ start: 70000, end: 90000 },
{ start: 50000, end: 60000 }
])
"
>
update Heatfields stream
</button>
88 changes: 88 additions & 0 deletions apps/components-e2e/src/components/chart/heatfield/heatfield.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/**
* @license
* Copyright 2020 Dynatrace LLC
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { Component } from '@angular/core';
import { generateData } from '@dynatrace/testing/fixtures';
import { BehaviorSubject } from 'rxjs';

@Component({
selector: 'dt-e2e-heat-field',
templateUrl: 'heatfield.html',
styles: [
`
:host {
display: block;
margin-top: 100px;
}
`,
],
})
export class Heatfield {
value = 0;

options: Highcharts.Options = {
chart: {
spacingLeft: 100,
spacingRight: 100,
},
xAxis: {
type: 'datetime',
min: 0,
max: 100000,
},
yAxis: [
{
title: undefined,
labels: {
enabled: false,
},
tickLength: 0,
},
],
plotOptions: {
column: {
stacking: 'normal',
},
series: {
marker: {
enabled: false,
},
},
},
};

series: Highcharts.SeriesOptionsType[] = [
{
name: 'Requests',
type: 'line',
data: generateData(11, 0, 200, 0, 10000),
},
];

heatfields$ = new BehaviorSubject([
{
start: 10000,
end: 20000,
},
]);

heatfields = [
{
start: 1000,
end: 2000,
},
];
}
26 changes: 15 additions & 11 deletions libs/barista-components/chart/src/chart.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// tslint:disable no-any max-file-line-count no-unbound-method use-component-selector

import { Component } from '@angular/core';
import { async, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { fakeAsync, flush, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import {
DtChart,
Expand All @@ -45,7 +45,7 @@ import {
import { BehaviorSubject } from 'rxjs';

describe('DtChart', () => {
beforeEach(async(() => {
beforeEach(() => {
TestBed.configureTestingModule({
imports: [DtChartModule, DtThemingModule],
declarations: [
Expand All @@ -68,7 +68,7 @@ describe('DtChart', () => {
});

TestBed.compileComponents();
}));
});

describe('Data', () => {
it('should display static data', () => {
Expand Down Expand Up @@ -412,20 +412,24 @@ describe('DtChart', () => {
const fixture = createComponent(HeatfieldError);
const chartDebugElement = fixture.debugElement.query(By.css('dt-chart'));
const chartComponent = chartDebugElement.componentInstance as DtChart;
fixture.detectChanges();

chartComponent._plotBackground$ = new BehaviorSubject(
(rect as unknown) as SVGRectElement,
);
try {
chartComponent._plotBackground$ = new BehaviorSubject(
(rect as unknown) as SVGRectElement,
);
chartComponent._afterRender.next();
tick(1000);
fixture.detectChanges();
flush();
} catch (e) {
expect(e.message).toBe(getDtHeatfieldUnsupportedChartError().message);
} finally {
tick(1000);
expect.assertions(1);
fixture.destroy();
}
// This was the only solution to clear the pending timers in the queue.
// If I would do a tick or flush it would trigger the error again and then it fails with the
// getDtHeatfieldUnsupportedChartError twice.
(global as any).Zone.current.get(
'FakeAsyncTestZoneSpec',
).pendingTimers = [];
}));
});

Expand Down
Loading

0 comments on commit 796b9e9

Please sign in to comment.