Selection area

The selection area allows you to interact with existing components (e.g. zoom in or analyze). The component is most commonly used with charts. The interaction with charts can either consist of selecting a specific timestamp or creating a timeframe to analyze one or more metrics.

´ Loading interactive demo...
<dt-chart [options]="options" [series]="series" [dtChartSelectionArea]="area"></dt-chart> <dt-selection-area #area="dtSelectionArea" (changed)="handleChange($event)"> {{left | date: 'MMM d, y - HH:mm':'GMT' }} - {{right | date: 'MMM d, y - HH:mm':'GMT'}} <dt-selection-area-actions> <button dt-button>Zoom in</button> </dt-selection-area-actions> </dt-selection-area> export class SelectionAreaChartExample { @ViewChild(DtChart) chart: DtChart; @ViewChild(DtSelectionArea) selectionArea: DtSelectionArea; left: number; right: number; options: Highcharts.Options = { xAxis: { type: 'datetime', min: 1370302200000, startOnTick: true, }, yAxis: [ { title: null, labels: { format: '{value}', }, tickInterval: 10, }, { title: null, labels: { format: '{value}/min', }, opposite: true, tickInterval: 50, }, ], plotOptions: { column: { stacking: 'normal', }, series: { marker: { enabled: false, }, }, }, tooltip: { formatter(): string | boolean { return `${this.series.name}&nbsp${this.y}`; }, }, }; series: Highcharts.IndividualSeriesOptions[] = [ { name: 'Failure rate', type: 'line', data: generateData(40, 0, 20, 1370304000000, 900000), }, { name: 'Requests', type: 'column', yAxis: 1, data: generateData(40, 0, 200, 1370304000000, 900000), }, { name: 'Failed requests', type: 'column', yAxis: 1, data: generateData(40, 0, 15, 1370304000000, 900000), }]; handleChange(ev: DtSelectionAreaChange): void { this.left = ev.left; this.right = ev.right; } } export function randomize(min: number, max: number): number { return Math.floor(Math.random() * (max - min) + min); } export function generateData( amount: number, min: number, max: number, timestampStart: number, timestampTick: number ): Array<[number, number]> { return Array.from(Array(amount).keys()) .map((v) => [ timestampStart + (timestampTick * v), randomize(min, max), ] as [number, number]); } {{left | date: 'MMM d, y - HH:mm':'GMT' }} - {{right | date: 'MMM d, y - HH:mm':'GMT'}} export class SelectionAreaChartExample { @ViewChild(DtChart) chart: DtChart; @ViewChild(DtSelectionArea) selectionArea: DtSelectionArea; left: number; right: number; options: Highcharts.Options = { xAxis: { type: 'datetime', min: 1370302200000, startOnTick: true, }, yAxis: [ { title: null, labels: { format: '{value}', }, tickInterval: 10, }, { title: null, labels: { format: '{value}/min', }, opposite: true, tickInterval: 50, }, ], plotOptions: { column: { stacking: 'normal', }, series: { marker: { enabled: false, }, }, }, tooltip: { formatter(): string | boolean { return `${this.series.name} ${this.y}`; }, }, }; series: Highcharts.IndividualSeriesOptions[] = [ { name: 'Failure rate', type: 'line', data: generateData(40, 0, 20, 1370304000000, 900000), }, { name: 'Requests', type: 'column', yAxis: 1, data: generateData(40, 0, 200, 1370304000000, 900000), }, { name: 'Failed requests', type: 'column', yAxis: 1, data: generateData(40, 0, 15, 1370304000000, 900000), }]; handleChange(ev: DtSelectionAreaChange): void { this.left = ev.left; this.right = ev.right; } } export function randomize(min: number, max: number): number { return Math.floor(Math.random() * (max - min) + min); } export function generateData( amount: number, min: number, max: number, timestampStart: number, timestampTick: number ): Array<[number, number]=""> { return Array.from(Array(amount).keys()) .map((v) => [ timestampStart + (timestampTick * v), randomize(min, max), ] as [number, number]); }

Behavior & corner cases

Our selection area was built for mouse, keyboard and touch support. However functionality will diverge slightly depending on what you use.

Mouse

  • Timestamp: clicking triggers a line with an overlay. The overlay consists of a close button and the selected time. As soon as the timestamp is set, tables and lists will be filtered accordingly. The time can be reseted by clicking the close button.
  • Timeframe: click and drag creates an area. The overlay additionally consists of an analyze button. By clicking analyze the chart will zoom into the selected timeframe. An analysis timeframe will appear in form of a global timeframe overlay. It can be reseted by clicking the close button.
Analysis timeframe overlay
Analysis timeframe overlay
  • Positioning and adjustments: The chosen timeframe and can be adjusted with handles or by moving the whole area via drag and drop. A timestamp can be positioned by creating a new one via click.

Keyboard

To be able to create a timeframe or timestamp it is necessary to focus the chart first.

  • Timestamp: enter will create a line with an overlay in the middle of the chart.
  • Timeframe: a timestamp will transform into an area as soon as you push Shift left or Shift right.
  • Positioning and adjustments: timestamp and timeframe can be adjusted or moved to a preferred position by using keys aligned with WAI-ARIA practices. For further informations on how to use keyboard support visit the W3C Horizontal Multi-Thumb Slider Example

Touch

  • Timestamp: to create a timestamp tap on a preferred position.
  • Timeframe: dragging will create an area.
  • Positioning and adjustments: same behavior as for mouse support is used.

Selection area in use

´ Loading interactive demo...
<div class="origin" [dtSelectionArea]="area"></div> <dt-selection-area #area="dtSelectionArea" (changed)="handleChange($event)"> {{overlayContent}} <dt-selection-area-actions> <button dt-button>Zoom in</button> </dt-selection-area-actions> </dt-selection-area> export class SelectionAreaDefaultExample { overlayContent = ''; handleChange(ev: DtSelectionAreaChange): void { this.overlayContent = `Left: ${ev.left}, Right: ${ev.right}`; } }
{{overlayContent}}
export class SelectionAreaDefaultExample { overlayContent = ''; handleChange(ev: DtSelectionAreaChange): void { this.overlayContent = `Left: ${ev.left}, Right: ${ev.right}`; } }
´ Loading interactive demo...
<dt-chart [options]="options" [series]="series" [dtChartSelectionArea]="area"></dt-chart> <dt-selection-area #area="dtSelectionArea" (changed)="handleChange($event)"> {{left | date: 'MMM d, y - HH:mm':'GMT' }} - {{right | date: 'MMM d, y - HH:mm':'GMT'}} <dt-selection-area-actions> <button dt-button>Zoom in</button> </dt-selection-area-actions> </dt-selection-area> export class SelectionAreaChartExample { @ViewChild(DtChart) chart: DtChart; @ViewChild(DtSelectionArea) selectionArea: DtSelectionArea; left: number; right: number; options: Highcharts.Options = { xAxis: { type: 'datetime', min: 1370302200000, startOnTick: true, }, yAxis: [ { title: null, labels: { format: '{value}', }, tickInterval: 10, }, { title: null, labels: { format: '{value}/min', }, opposite: true, tickInterval: 50, }, ], plotOptions: { column: { stacking: 'normal', }, series: { marker: { enabled: false, }, }, }, tooltip: { formatter(): string | boolean { return `${this.series.name}&nbsp${this.y}`; }, }, }; series: Highcharts.IndividualSeriesOptions[] = [ { name: 'Failure rate', type: 'line', data: generateData(40, 0, 20, 1370304000000, 900000), }, { name: 'Requests', type: 'column', yAxis: 1, data: generateData(40, 0, 200, 1370304000000, 900000), }, { name: 'Failed requests', type: 'column', yAxis: 1, data: generateData(40, 0, 15, 1370304000000, 900000), }]; handleChange(ev: DtSelectionAreaChange): void { this.left = ev.left; this.right = ev.right; } } export function randomize(min: number, max: number): number { return Math.floor(Math.random() * (max - min) + min); } export function generateData( amount: number, min: number, max: number, timestampStart: number, timestampTick: number ): Array<[number, number]> { return Array.from(Array(amount).keys()) .map((v) => [ timestampStart + (timestampTick * v), randomize(min, max), ] as [number, number]); } {{left | date: 'MMM d, y - HH:mm':'GMT' }} - {{right | date: 'MMM d, y - HH:mm':'GMT'}} export class SelectionAreaChartExample { @ViewChild(DtChart) chart: DtChart; @ViewChild(DtSelectionArea) selectionArea: DtSelectionArea; left: number; right: number; options: Highcharts.Options = { xAxis: { type: 'datetime', min: 1370302200000, startOnTick: true, }, yAxis: [ { title: null, labels: { format: '{value}', }, tickInterval: 10, }, { title: null, labels: { format: '{value}/min', }, opposite: true, tickInterval: 50, }, ], plotOptions: { column: { stacking: 'normal', }, series: { marker: { enabled: false, }, }, }, tooltip: { formatter(): string | boolean { return `${this.series.name} ${this.y}`; }, }, }; series: Highcharts.IndividualSeriesOptions[] = [ { name: 'Failure rate', type: 'line', data: generateData(40, 0, 20, 1370304000000, 900000), }, { name: 'Requests', type: 'column', yAxis: 1, data: generateData(40, 0, 200, 1370304000000, 900000), }, { name: 'Failed requests', type: 'column', yAxis: 1, data: generateData(40, 0, 15, 1370304000000, 900000), }]; handleChange(ev: DtSelectionAreaChange): void { this.left = ev.left; this.right = ev.right; } } export function randomize(min: number, max: number): number { return Math.floor(Math.random() * (max - min) + min); } export function generateData( amount: number, min: number, max: number, timestampStart: number, timestampTick: number ): Array<[number, number]=""> { return Array.from(Array(amount).keys()) .map((v) => [ timestampStart + (timestampTick * v), randomize(min, max), ] as [number, number]); }

The <dt-selection-area> creates the possibility to create a selected area inside an origin element and drag the edges or the entire selected area within the constraints of the origin element. The selection area itself is not tightly coupled with the chart component but this is the main usecase. To connect the selection area and the chart you have to use the dtChartSelectionArea directive on the dt-chart component and provide the instance of the dt-selection-area component as an input.

<dt-chart ... [dtChartSelectionArea]="area"></dt-chart>
<dt-selection-area #area="dtSelectionArea" ...>
...
</dt-selection-area>

Inside the dt-selection-area tags you can specify the content of the overlay that gets created when creating the selected area. A special outlet for the action button is available called dt-selection-area-actions.

...
<dt-selection-area>
  some overlay content
  <dt-selection-area-actions>
    <button dt-button i18n>Zoom in</button>
  </dt-selection-area-actions>
</dt-selection-area>

The dt-selection-area component will fire a change event when the selected area changes with the values for the positions of the handles. When used with a chart the values in the event are the x Axis values for the chart. If used with any other element the values will be pixel values.

When you want to use the selection area connected to any other element than a dt-chart you have to use the dtSelectionArea directive on the origin element and connect the area the same way.

<div class="origin" ... [dtSelectionArea]="area"></div>
<dt-selection-area #area="dtSelectionArea" ...>
...
</dt-selection-area>

Imports

You have to import the DtSelectionAreaModule when you want to use the dt-selection-area. Note that you also need the DtChartModule when using with the dt-chart component.


@NgModule({
  imports: [
  DtSelectionAreaModule,
  DtChartModule,
  ],
})
class MyModule {}

Accessibility

Selection areas should be given meaningful labels via aria-label-selected-area, aria-label-left-handle, aria-label-right-handle and aria-label-close-button, because all those interactive elements don't have a text.

Options & Properties

Name Type Default Description
@Input('aria-label-selected-area') ariaLabelselectedArea string Aria label of the selected area that is created and can be moved.
@Input('aria-label-left-handle') ariaLabelLeftHandle string Aria label of the left handle of the selected area.
@Input('aria-label-right-handle') ariaLabelRightHandle string Aria label of the right handle of the selected area.
@Input('aria-label-close-button') ariaLabelCloseButton string Aria label of the close button inside the overlay.
@Ouput() changed EventEmitter<DtSelectionAreaChange> Event emitted when the position or width of the selected area changes.
@Ouput() closed EventEmitter<void> Event emitted when the selected area is closed.

Methods

Name Description Return value
close Closes the selection area's selected area.
focus Focuses the selected area if one is available.

Examples

Usage on a non chart origin

You can use the selection area connected to any element. Not only charts are supported.

´ Loading interactive demo...
<div class="origin" [dtSelectionArea]="area"></div> <dt-selection-area #area="dtSelectionArea" (changed)="handleChange($event)"> {{overlayContent}} <dt-selection-area-actions> <button dt-button>Zoom in</button> </dt-selection-area-actions> </dt-selection-area> export class SelectionAreaDefaultExample { overlayContent = ''; handleChange(ev: DtSelectionAreaChange): void { this.overlayContent = `Left: ${ev.left}, Right: ${ev.right}`; } }
{{overlayContent}}
export class SelectionAreaDefaultExample { overlayContent = ''; handleChange(ev: DtSelectionAreaChange): void { this.overlayContent = `Left: ${ev.left}, Right: ${ev.right}`; } }