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

Commit

Permalink
fix(chart): Fixes an issue where the range could not be re-opened aft…
Browse files Browse the repository at this point in the history
…er closing.

Fixed a regression that was introduced in version 5.1.0 where range could not be
re-opened in a range only mode after it was closed once.
  • Loading branch information
Lukas Holzer authored and lukasholzer committed Feb 6, 2020
1 parent ec0d901 commit 1718a21
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
rangeSelection,
selection,
overlayText,
closeButton,
} from '../selection-area.po';

const closeCounter = Selector('.closed-counter');
Expand All @@ -44,7 +45,6 @@ test('should not have an initial range selection', async (testController: TestCo

test('should not close the range when a click is performed somewhere else in the chart', async () => {
await createRange(520, { x: 310, y: 100 })
.wait(500)
.expect(rangeSelection.exists)
.ok()
.expect(overlayText.textContent)
Expand All @@ -59,3 +59,18 @@ test('should not close the range when a click is performed somewhere else in the
.expect(overlayText.textContent)
.match(/Jul 31 \d{2}:17 — \d{2}:23/g);
});

test('should be possible to create a range again after it was closed', async () => {
await createRange(520, { x: 310, y: 100 })
.expect(rangeSelection.exists)
.ok()
.click(closeButton, { speed: 0.3 })
.expect(rangeSelection.exists)
.notOk();

await createRange(520, { x: 310, y: 100 })
.expect(rangeSelection.exists)
.ok()
.expect(overlayText.textContent)
.match(/Jul 31 \d{2}:17 — \d{2}:23/g);
});
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { DtChartModule } from '@dynatrace/barista-components/chart';
import { DtE2ESelectionArea } from './selection-area';
import { DtE2ERange } from './range/range';
import { DataService } from '../../../services/data.service';
import { DtE2ETimestamp } from './timestamp/timestamp';

const routes: Route[] = [
{
Expand All @@ -34,10 +35,14 @@ const routes: Route[] = [
path: 'range',
component: DtE2ERange,
},
{
path: 'timestamp',
component: DtE2ETimestamp,
},
];

@NgModule({
declarations: [DtE2ESelectionArea, DtE2ERange],
declarations: [DtE2ESelectionArea, DtE2ERange, DtE2ETimestamp],
imports: [
CommonModule,
DtChartModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function createRange(
return controller.drag(plotBackground, width, 0, {
offsetX: start.x,
offsetY: start.y,
speed: 0.01,
speed: 0.05,
});
}

Expand Down
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 { Selector } from 'testcafe';
import { waitForAngular } from '../../../../utils';
import {
chartClickTargets,
closeButton,
createTimestamp,
overlayText,
rangeSelection,
selection,
timestampSelection,
createRange,
} from '../selection-area.po';

const closeCounter = Selector('.closed-counter');

fixture('Selection Area Timestamp Only')
.page('http://localhost:4200/chart/selection-area/timestamp')
.beforeEach(async (testController: TestController) => {
await testController.resizeWindow(1200, 800);
await waitForAngular();
});

test('should not have an initial timestamp selection', async (testController: TestController) => {
await testController
.expect(selection.exists)
.notOk()
.expect(timestampSelection.exists)
.notOk()
.expect(closeCounter.textContent)
.eql('0');
});

test('should create a timestamp close it and reopen it', async (testController: TestController) => {
await createTimestamp(
{ x: 450, y: 100 },
chartClickTargets[1],
testController,
)
.expect(overlayText.textContent)
.match(/Jul 31, \d{2}:19/g)
.click(closeButton, { speed: 0.3 })
.expect(rangeSelection.exists)
.notOk();

await createTimestamp(
{ x: 450, y: 100 },
chartClickTargets[1],
testController,
)
.expect(timestampSelection.exists)
.ok()
.expect(overlayText.textContent)
.match(/Jul 31, \d{2}:19/g);
});

test('should leave the timestamp untouched if a range is created in a timestamp only mode', async (testController: TestController) => {
await createTimestamp(
{ x: 450, y: 100 },
chartClickTargets[1],
testController,
)
.expect(timestampSelection.exists)
.ok();

await createRange(520, { x: 310, y: 100 })
.expect(rangeSelection.exists)
.notOk()
.expect(timestampSelection.exists)
.ok()
.expect(overlayText.textContent)
.match(/Jul 31, \d{2}:19/g);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<dt-chart [options]="options" [series]="series$ | async">
<dt-chart-timestamp
aria-label-close="Close the selection"
(closed)="closed()"
(valueChanges)="valueChanges($event)"
></dt-chart-timestamp>
</dt-chart>

<div class="closed-counter">{{ closedCounter }}</div>
<div class="current-value">{{ currentValue }}</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* @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 { DtE2EChartBase } from '../../chart-base';
import { DataService } from '../../../../services/data.service';

@Component({
selector: 'dt-e2e-timestamp',
templateUrl: './timestamp.html',
styles: [
`
:host {
display: block;
width: 1200px;
}
`,
],
})
export class DtE2ETimestamp extends DtE2EChartBase {
closedCounter = 0;
currentValue;

constructor(dataService: DataService) {
super(dataService);
}

closed(): void {
this.closedCounter++;
}

valueChanges(_value: number): void {
this.currentValue = _value;
}
}
42 changes: 33 additions & 9 deletions components/chart/src/selection-area/selection-area.ts
Original file line number Diff line number Diff line change
Expand Up @@ -726,12 +726,21 @@ export class DtChartSelectionArea implements AfterContentInit, OnDestroy {
// On a mousedown the range and the timestamp have to be hidden.
const startShowingTimestamp$ = this._click$.pipe(mapTo(true));
const startShowingRange$ = this._drag$.pipe(mapTo(true));
let hideTimestampAndRange$ =
this._chart._range && !this._chart._timestamp
? EMPTY
: touchStartAndMouseDown$.pipe(mapTo(false));
let hideTimestampAndRange$ = touchStartAndMouseDown$.pipe(mapTo(false));

merge(startShowingRange$, hideTimestampAndRange$)
// If there is only a timestamp a click should hide and show a timestamp
if (this._chart._timestamp && !this._chart._range) {
hideTimestampAndRange$ = this._click$.pipe(mapTo(false));
}

// If we only have a range it should be only closed on overlay close.
if (this._chart._range && !this._chart._timestamp) {
hideTimestampAndRange$ = this._chart._range!._closeOverlay.pipe(
mapTo(false),
);
}

merge(hideTimestampAndRange$, startShowingRange$)
.pipe(
distinctUntilChanged(),
takeUntil(this._destroy$),
Expand All @@ -740,7 +749,7 @@ export class DtChartSelectionArea implements AfterContentInit, OnDestroy {
this._toggleRange(show);
});

merge(startShowingTimestamp$, hideTimestampAndRange$)
merge(hideTimestampAndRange$, startShowingTimestamp$)
.pipe(
distinctUntilChanged(),
takeUntil(this._destroy$),
Expand Down Expand Up @@ -782,12 +791,27 @@ export class DtChartSelectionArea implements AfterContentInit, OnDestroy {
// –––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––––
// listen for a _closeOverlay event if there is a timestamp or a range

// close the overlay in range + timestamp mode on every new interaction start with
// a mouse or touch down.
let closeOverlay$ = touchStartAndMouseDown$;

// If there is only a timestamp than we have to close it only on mousedown
// when it is not hidden
if (!this._chart._range && this._chart._timestamp) {
closeOverlay$ = touchStartAndMouseDown$.pipe(
filter(() => this._chart._timestamp!._hidden),
);
}

// If we have only a range we don't have to add some additional closing behavior
if (this._chart._range && !this._chart._timestamp) {
closeOverlay$ = EMPTY;
}

merge(
this._chart._timestamp ? this._chart._timestamp._closeOverlay : EMPTY,
this._chart._range ? this._chart._range._closeOverlay : EMPTY,
this._chart._range && !this._chart._timestamp
? EMPTY
: touchStartAndMouseDown$,
closeOverlay$,
)
.pipe(takeUntil(this._destroy$))
.subscribe(() => {
Expand Down

0 comments on commit 1718a21

Please sign in to comment.