Time Span Events

Hello World Example for Angular

Time span events can be added to your Angular charting applications quickly and easily. With a properly formatted data source, your Angular apps can offer the powerful visual analysis capabilities of the ChartIQ Time Span Events module.

In this tutorial

You will clone the chartiq-angular-app GitHub project and customize the HelloWorldComponent to automatically display time span events when a basic chart loads.

Before you begin

This tutorial requires version 8.0.0 or later of the ChartIQ library.

The tutorial relies on concepts covered in the Implementation tutorial and Creating a Data Source tutorial. Please familiarize yourself with the prerequisite material before proceeding.

chartiq-angular-app

The chartiq-angular-app project on GitHub is a toolkit of Angular components. The components create everything from a basic chart, HelloWorldComponent, to a chart with a full-featured user interface, AdvancedChartComponent, to an active trader workstation, ActiveTraderComponent.

Getting started

Access the chartiq-angular-app project.

Follow the instructions in the “Getting started” section of the README to set up the project on your local system.

After you have installed and compiled the project, open your web browser to:

http://localhost:4200/

You should see a list of the toolkit's charting components. The list is created by the RouteListComponent.

Select HelloWorldComponent.

A basic time series chart should appear:

Basic chart with no user interface Figure. Basic chart with no user interface.

HelloWorldComponent

The HelloWorldComponent creates a time series chart with no user interface. The time series data comes from a static data source built into the component.

The component's source code is located in the src/app/chartiq-hello-world folder of the project:
HelloWorldComponent source files

Open the folder in your code editor. Let's look at the component source files.

hello-world.component.html

The HTML template file contains the markup for the chart:

<div style="margin: 20px;">
<h2>
    Hello world static chart example
</h2>
<div
    #chartContainer
    class="chartContainer"
    style="
        width: 800px;
        height: 460px;
        position: relative;
        border: solid 1px #aaa
    "></div>
</div>

The chart is created in the inner div. Note the #chartContainer template reference variable, which is used in hello-world.component.ts to provide a reference to the DOM node.

hello-world-component.scss

The style sheet file imports stx-chart.css, the basic style sheet required by all ChartIQ charts:

@import '~chartiq/css/stx-chart.css'; // Chart API

hello-world-component.ts

The component definition file creates the component and provides the static data source, masterData, for the chart.

The majority of our work will be done in this file. Here's our starting point:

import { Component, ViewChild, ElementRef, AfterViewInit, ViewEncapsulation } from '@angular/core';

import { CIQ } from 'chartiq/js/chartiq';

/**
 * The Hello World component creates a basic chart from a built-in static data source. The chart
 * does not have a user interface.
 */
@Component({
    selector: 'cq-hello-world',
    templateUrl: './hello-world.component.html',
    styleUrls: ['./hello-world.component.scss'],
    encapsulation: ViewEncapsulation.None
})
export class HelloWorldComponent implements AfterViewInit {
    @ViewChild('chartContainer', { static: true }) chartContainer: ElementRef;

    constructor() {}

    ngAfterViewInit() {
        const container = this.chartContainer.nativeElement;

        const stx = new CIQ.ChartEngine({ container });

        stx.loadChart('SPY', {
            masterData: this.getMasterData(),
            periodicity: {
                period: 1,
                interval: 5,
                timeUnit: 'minute',
            },
        });
    }

    getMasterData() {
        const masterData = [
            {Date:"20200331144000000",Open:156.64,High:156.66,Low:156.57,Close:156.59,Volume:932912},
            {Date:"20200331145000000",Open:156.58,High:156.62,Low:156.57,Close:156.61,Volume:700952},
            {Date:"20200331145500000",Open:156.59,High:156.60,Low:156.55,Close:156.58,Volume:1084428},
            {Date:"20200331150000000",Open:156.57,High:156.58,Low:156.53,Close:156.55,Volume:916684},
            {Date:"20200331150500000",Open:156.54,High:156.57,Low:156.52,Close:156.55,Volume:1360390},
            {Date:"20200331151000000",Open:156.56,High:156.60,Low:156.54,Close:156.58,Volume:2037170},
            {Date:"20200331151500000",Open:156.55,High:156.62,Low:156.54,Close:156.60,Volume:4280833},
            {Date:"20200331152000000",Open:156.61,High:156.62,Low:156.54,Close:156.57,Volume:3348274},
            {Date:"20200331152500000",Open:156.59,High:156.62,Low:156.52,Close:156.54,Volume:932912},
            {Date:"20200331153000000",Open:156.56,High:156.57,Low:156.50,Close:156.52,Volume:700952},
            {Date:"20200331153500000",Open:156.51,High:156.56,Low:156.50,Close:156.54,Volume:1084428},
            {Date:"20200331154000000",Open:156.52,High:156.56,Low:156.51,Close:156.55,Volume:916684},
            {Date:"20200331154500000",Open:156.56,High:156.57,Low:156.50,Close:156.53,Volume:1360390},
            {Date:"20200331155000000",Open:156.52,High:156.53,Low:156.49,Close:156.50,Volume:2037170},
            {Date:"20200331155500000",Open:156.51,High:156.52,Low:156.46,Close:156.48,Volume:4280833},
            {Date:"20200331160000000",Open:156.49,High:156.48,Low:156.44,Close:156.47,Volume:3348274},
            {Date:"20200401093000000",Open:156.41,High:156.48,Low:156.39,Close:156.46,Volume:1869466},
            {Date:"20200401093500000",Open:156.44,High:156.53,Low:156.40,Close:156.49,Volume:2937883},
            {Date:"20200401094000000",Open:156.48,High:156.54,Low:156.37,Close:156.43,Volume:2277682},
            {Date:"20200401094500000",Open:156.47,High:156.55,Low:156.45,Close:156.51,Volume:1714687},
            {Date:"20200401095000000",Open:156.49,High:156.58,Low:156.48,Close:156.54,Volume:1902583},
            {Date:"20200401095500000",Open:156.54,High:156.59,Low:156.50,Close:156.56,Volume:1325148},
            {Date:"20200401100000000",Open:156.56,High:156.60,Low:156.50,Close:156.53,Volume:2005588},
            {Date:"20200401100500000",Open:156.52,High:156.54,Low:156.42,Close:156.43,Volume:1277880},
            {Date:"20200401101000000",Open:156.44,High:156.46,Low:156.36,Close:156.37,Volume:1158301},
            {Date:"20200401101500000",Open:156.38,High:156.39,Low:156.26,Close:156.28,Volume:1987415},
            {Date:"20200401102000000",Open:156.26,High:156.33,Low:156.22,Close:156.32,Volume:1512742},
            {Date:"20200401102500000",Open:156.31,High:156.40,Low:156.31,Close:156.39,Volume:871592},
            {Date:"20200401103000000",Open:156.38,High:156.43,Low:156.35,Close:156.40,Volume:1132109},
            {Date:"20200401103500000",Open:156.40,High:156.44,Low:156.37,Close:156.41,Volume:725521},
            {Date:"20200401104000000",Open:156.41,High:156.50,Low:156.41,Close:156.48,Volume:704072},
            {Date:"20200401104500000",Open:156.48,High:156.50,Low:156.42,Close:156.46,Volume:844084},
            {Date:"20200401105000000",Open:156.47,High:156.47,Low:156.42,Close:156.45,Volume:392122},
            {Date:"20200401105500000",Open:156.45,High:156.47,Low:156.38,Close:156.41,Volume:544729},
            {Date:"20200401110000000",Open:156.43,High:156.47,Low:156.41,Close:156.44,Volume:660383},
            {Date:"20200401110500000",Open:156.43,High:156.47,Low:156.40,Close:156.41,Volume:640177},
            {Date:"20200401111000000",Open:156.41,High:156.44,Low:156.35,Close:156.39,Volume:845668},
            {Date:"20200401111500000",Open:156.38,High:156.41,Low:156.37,Close:156.39,Volume:503347},
            {Date:"20200401112000000",Open:156.39,High:156.43,Low:156.38,Close:156.41,Volume:360929},
            {Date:"20200401112500000",Open:156.40,High:156.42,Low:156.37,Close:156.38,Volume:749554},
            {Date:"20200401113000000",Open:156.39,High:156.44,Low:156.38,Close:156.42,Volume:723857},
            {Date:"20200401113500000",Open:156.40,High:156.45,Low:156.40,Close:156.44,Volume:455561},
            {Date:"20200401114000000",Open:156.43,High:156.48,Low:156.42,Close:156.45,Volume:670704},
            {Date:"20200401114500000",Open:156.44,High:156.54,Low:156.44,Close:156.50,Volume:827725},
            {Date:"20200401115000000",Open:156.51,High:156.55,Low:156.48,Close:156.53,Volume:828780},
            {Date:"20200401115500000",Open:156.53,High:156.55,Low:156.48,Close:156.49,Volume:687357},
            {Date:"20200401120000000",Open:156.48,High:156.52,Low:156.48,Close:156.51,Volume:343617},
            {Date:"20200401120500000",Open:156.50,High:156.58,Low:156.50,Close:156.57,Volume:444181},
            {Date:"20200401121000000",Open:156.57,High:156.61,Low:156.56,Close:156.57,Volume:932850},
            {Date:"20200401121500000",Open:156.58,High:156.63,Low:156.56,Close:156.61,Volume:622879},
            {Date:"20200401122000000",Open:156.61,High:156.64,Low:156.54,Close:156.56,Volume:417197},
            {Date:"20200401122500000",Open:156.57,High:156.60,Low:156.54,Close:156.56,Volume:524792},
            {Date:"20200401123000000",Open:156.57,High:156.63,Low:156.56,Close:156.63,Volume:547832},
            {Date:"20200401123500000",Open:156.63,High:156.69,Low:156.62,Close:156.65,Volume:1033940},
            {Date:"20200401124000000",Open:156.65,High:156.66,Low:156.59,Close:156.60,Volume:666020},
            {Date:"20200401124500000",Open:156.60,High:156.63,Low:156.52,Close:156.54,Volume:886571},
            {Date:"20200401125000000",Open:156.54,High:156.59,Low:156.53,Close:156.57,Volume:409824},
            {Date:"20200401125500000",Open:156.57,High:156.57,Low:156.52,Close:156.53,Volume:490971},
            {Date:"20200401130000000",Open:156.53,High:156.62,Low:156.53,Close:156.62,Volume:618202},
            {Date:"20200401130500000",Open:156.62,High:156.63,Low:156.56,Close:156.56,Volume:232977},
            {Date:"20200401131000000",Open:156.56,High:156.58,Low:156.52,Close:156.52,Volume:569834},
            {Date:"20200401131500000",Open:156.53,High:156.55,Low:156.50,Close:156.54,Volume:526717},
            {Date:"20200401132000000",Open:156.54,High:156.54,Low:156.48,Close:156.52,Volume:587983},
            {Date:"20200401132500000",Open:156.52,High:156.52,Low:156.46,Close:156.46,Volume:683988},
            {Date:"20200401133000000",Open:156.46,High:156.48,Low:156.44,Close:156.44,Volume:505235},
            {Date:"20200401133500000",Open:156.45,High:156.46,Low:156.41,Close:156.44,Volume:760274},
            {Date:"20200401134000000",Open:156.45,High:156.45,Low:156.41,Close:156.42,Volume:428196},
            {Date:"20200401134500000",Open:156.43,High:156.49,Low:156.42,Close:156.49,Volume:372145},
            {Date:"20200401135000000",Open:156.49,High:156.55,Low:156.42,Close:156.42,Volume:493463},
            {Date:"20200401135500000",Open:156.42,High:156.46,Low:156.37,Close:156.38,Volume:763911},
            {Date:"20200401140000000",Open:156.38,High:156.44,Low:156.38,Close:156.43,Volume:478714},
            {Date:"20200401140500000",Open:156.43,High:156.48,Low:156.40,Close:156.47,Volume:347221},
            {Date:"20200401141000000",Open:156.46,High:156.48,Low:156.44,Close:156.45,Volume:527388},
            {Date:"20200401141500000",Open:156.46,High:156.47,Low:156.39,Close:156.46,Volume:1254489},
            {Date:"20200401142000000",Open:156.47,High:156.52,Low:156.43,Close:156.50,Volume:588877},
            {Date:"20200401142500000",Open:156.49,High:156.50,Low:156.45,Close:156.46,Volume:391738},
            {Date:"20200401143000000",Open:156.46,High:156.50,Low:156.43,Close:156.46,Volume:835468},
            {Date:"20200401143500000",Open:156.46,High:156.51,Low:156.45,Close:156.48,Volume:465308},
            {Date:"20200401144000000",Open:156.48,High:156.50,Low:156.47,Close:156.49,Volume:389872},
            {Date:"20200401144500000",Open:156.48,High:156.53,Low:156.48,Close:156.50,Volume:530820},
            {Date:"20200401145000000",Open:156.50,High:156.53,Low:156.48,Close:156.53,Volume:554269},
            {Date:"20200401145500000",Open:156.53,High:156.57,Low:156.52,Close:156.56,Volume:622473},
            {Date:"20200401150000000",Open:156.57,High:156.59,Low:156.53,Close:156.59,Volume:593592},
            {Date:"20200401150500000",Open:156.59,High:156.61,Low:156.56,Close:156.58,Volume:1089712},
            {Date:"20200401151000000",Open:156.59,High:156.59,Low:156.55,Close:156.57,Volume:634702},
            {Date:"20200401151500000",Open:156.57,High:156.64,Low:156.57,Close:156.60,Volume:1206417},
            {Date:"20200401152000000",Open:156.60,High:156.61,Low:156.58,Close:156.60,Volume:641636},
            {Date:"20200401152500000",Open:156.59,High:156.60,Low:156.54,Close:156.55,Volume:873698},
            {Date:"20200401153000000",Open:156.55,High:156.64,Low:156.55,Close:156.59,Volume:1318720},
            {Date:"20200401153500000",Open:156.60,High:156.68,Low:156.59,Close:156.68,Volume:1520610},
            {Date:"20200401154000000",Open:156.68,High:156.74,Low:156.67,Close:156.74,Volume:1678678},
            {Date:"20200401154500000",Open:156.74,High:156.80,Low:156.73,Close:156.76,Volume:2854531},
            {Date:"20200401155000000",Open:156.75,High:156.79,Low:156.71,Close:156.72,Volume:2984534},
            {Date:"20200401155500000",Open:156.71,High:156.75,Low:156.63,Close:156.73,Volume:7105595},
            {Date:"20200401160000000",Open:156.73,High:156.78,Low:156.71,Close:156.77,Volume:3863507}
        ];
        return masterData;
    }
}

Install the Time Span Events plug-in

The first thing we need to do is make the Time Span Events plug-in available to the component.

Add the following import to hello-world.component.ts:

import "chartiq/plugins/timespanevent/timespanevent";

The plug-in import must come after the import of the CIQ namespace; for example:

import { CIQ } from 'chartiq/js/chartiq';
import "chartiq/plugins/timespanevent/timespanevent";

The Time Span Events plug-in relies on library routines in the advanced.js file to create the visual markers that depict time span events; and so, we need to also add the following import to hello-world.component.ts:

import "chartiq/js/advanced.js";

The import must come before the import of the Time Span Events plug-in, for example:

import { CIQ } from 'chartiq/js/chartiq';
import "chartiq/js/advanced.js";
import "chartiq/plugins/timespanevent/timespanevent";

See the Angular section of the Implementation tutorial for detailed information about installing the Time Span Events plug-in.

Instantiate the Time Span Events panel

Now we can create an instance of the Time Span Events panel. Time span event markers are displayed in the panel.

Add the following to the ngAfterViewInit function of hello-world.component.ts:

new CIQ.TimeSpanEventPanel({
    stx: stx,
    showTooltip: true,
    infoPanel: {
        spanEvent: "main",
        durationEvent: "main",
        singleEvent: "main"
    }
});

The CIQ.TimeSpanEventPanel constructor function requires a reference to the chart engine, stx; and so, you must add the function call after the instantiation of the chart engine.

For example, here's ngAfterViewInit with the Time Span Events panel instantiation:

ngAfterViewInit() {
    const container = this.chartContainer.nativeElement;

    const stx = new CIQ.ChartEngine({ container });

    new CIQ.TimeSpanEventPanel({
        stx: stx,
        showTooltip: true,
        infoPanel: {
            spanEvent: "main",
            durationEvent: "main",
            singleEvent: "main"
        }
    });

    stx.loadChart('SPY', {
        masterData: this.getMasterData(),
        periodicity: {
            period: 1,
            interval: 5,
            timeUnit: 'minute',
        },
    });

}

The showTooltip and infoPanel parameters configure display aspects of the time span event markers. See CIQ.TimeSpanEventPanel for more information.

Create the data

Next, we need to create data access objects for our time span events and for the swim lanes in which the events appear. The data access objects are based on the chart's masterData array.

See the Creating a Data Source tutorial for the details on creating time span event objects.

Event data objects

We'll create events for each of the three time span event types: spanEvent, singleEvent, and durationEvent.

Add the following function to hello-world.component.ts:

getTseData(eventType) {

    // Span events.
    const businessEvents = [
        {
            label: "Business",
            spanLabel: "Product Demo",
            startDate: "2020-04-01T09:30:00",
            endDate: "2020-04-01T11:00:00",
            bgColor: "#00f",
            headline: "New Product",
            story: "Presentation to media."
        },
        {
            label: "Business",
            spanLabel: "Board Meeting",
            startDate: "2020-04-01T12:00:00",
            endDate: "2020-04-01T16:00:00",
            bgColor: "#f90",
            textColor: "#000"
        },
    ];

    // Single events.
    const filingEvents = [
        {
            label: "Filing",
            startDate: "2020-04-01T11:30",
            markerShape: "square",
            bgColor: "#a09",
            headline: "SEC Filing",
            story: "10K"
        },
        {
            label: "Filing",
            startDate: "2020-04-01T14:35:00",
            markerShape: "square",
            bgColor: "#0a0",
            headline: "SEC Filing",
            story: "10Q"
        }
    ];

    // Duration events.
    const orderEvents = [
        {
            label: "Order",
            startDate: "2020-04-01T10:00",
            endDate: "2020-04-01T11:45",
            markerShape: "circle",
            category: "trade",
            subChildren: [
                {
                    date: new Date("2020-04-01T10:10:00"),
                    price: 156.46,
                    headline: "Trade Execution",
                    story: "Price: 156.46"
                },
                {
                    date: new Date("2020-04-01T10:40:00"),
                    price: 156.50,
                    headline: "Trade Execution",
                    story: "Price: 156.50"
                },
                {
                    date: new Date("2020-04-01T11:20:00"),
                    price: 156.43,
                    headline: "Trade Execution",
                    story: "Price: 156.43"
                },
                {
                    date: new Date("2020-04-01T11:45:00"),
                    price: 156.54,
                    headline: "Trade Execution",
                    story: "Price: 156.54"
                }
            ],
            headline: "Trade Start",
            story: new Date("2020-04-01T10:00"),
            bgColor: "#aa0"
        },
        {
            label: "Order",
            startDate: "2020-04-01T13:00",
            endDate: "2020-04-01T15:25",
            markerShape: "circle",
            category: "trade",
            subChildren: [
                {
                    date: new Date("2020-04-01T13:50:00"),
                    price: 156.55,
                    headline: "Trade Execution",
                    story: "Price: 156.55"
                },
                {
                    date: new Date("2020-04-01T14:25:00"),
                    price: 156.45,
                    headline: "Trade Execution",
                    story: "Price: 156.45"
                },
                {
                    date: new Date("2020-04-01T15:25:00"),
                    price: 156.54,
                    headline: "Trade Execution",
                    story: "Price: 156.54"
                }
            ],
            headline: "Trade Start",
            story: new Date("2020-04-01T10:40"),
            bgColor: "#0af",
            isActive: true
        }
    ];

}

The function will ultimately return the data for one of the event types ("Business", "Filing", or "Order"). The eventType parameter will be used to specify the type of event.

All the dates and prices of the event objects correspond to elements in masterData. You can locate the data elements from the date and time values of the events.

See the Creating a Data Source tutorial for information about the other object properties.

Swim lane data objects

Next, we'll create swim lane data access objects that contain and identify the time span events.

Add the following to the getTseData function in hello-world.component.ts after the array declarations:

const business = {
    type: "Business",
    events: businessEvents,
	spanType: "spanEvent"
}

const filing = {
    type: "Filing",
    events: filingEvents,
	spanType: "singleEvent"
}

const order = {
    type: "Order",
    events: orderEvents,
    spanType: "durationEvent"
}

switch (eventType.toLowerCase()) {
    case "business":
        return business;
    case "filing":
        return filing;
    case "order":
        return order;
}

The switch statement evaluates the argument passed to the getTseData function and returns the appropriate swim lane data object.

Display the events

The CIQ.TimeSpanEventPanel#showTimeSpanEvent function takes a swim lane object as an argument and displays the events contained in the object's events array in a swim lane of the Time Span Events panel.

Add the following to the bottom of the ngAfterViewInit function:

stx.timeSpanEventPanel.showTimeSpanEvent(this.getTseData("Filing"));
stx.timeSpanEventPanel.showTimeSpanEvent(this.getTseData("Business"));
stx.timeSpanEventPanel.showTimeSpanEvent(this.getTseData("Order"));

The chart engine, stx, acquired a reference to the Time Span Events panel when we instantiated the panel (see Instantiate the Time Span Events panel). So, we can call the showTimeSpanEvent function and pass our swim lane objects to it to create our custom time span events.

Run it!

Start the project with npm start.

Load http://localhost:4200/hello-world in your web browser. The chart now includes time span events:

Basic chart with custom time span events Figure. Basic chart with custom time span events (also known as life cycle events).

Time span event markers, including sub-event markers, are interactive. See the Introduction tutorial for information on interactivity.

Select any of the event markers. The sub-event markers (circles or squares) should appear, but they're a little large.

We need to add some CSS.

Add the style sheets

Time span events require two style sheet files:

  • chartiq.css — Positions and styles the sub-event pop-up displays
  • tradeAnalyticsSample.css — Sets the style of the sub-event markers

Add the following imports to hello-world.component.scss after the stx-chart.css import:

@import "~chartiq/css/chartiq.css";
@import "~chartiq/examples/markers/tradeAnalyticsSample.css";

Note: tradeAnalyticsSample.css must follow chartiq.css in the CSS cascade. Both files must follow stx-chart.css, the chart's main style sheet.

Load helloworld.html now and select some markers.

Close the panel

You may have noticed two controls that appear in the upper left corner of the time span events panel when you hover your mouse over the panel. The arrow repositions the panel to the top (or bottom) of the chart. The X closes the panel.

The arrow control works correctly. The X control always closes the panel, but any time span event pop-up displays that are on screen are not removed.

Let's fix that.

Add the following after the calls to showTimeSpanEvent in the ngAfterViewInit function in hello-world.component.ts:

stx.addEventListener("layout", ({ stx }) => {
    if (!stx.panels.timeSpanEventPanel) {
        stx.remove("draw");
        stx.timeSpanEventPanel.removeTimeSpanEvent("Filing");
        stx.timeSpanEventPanel.removeTimeSpanEvent("Business");
        stx.timeSpanEventPanel.removeTimeSpanEvent("Order");
    }
});

The listener responds to layout events, which signal the chart engine that the chart needs to be redrawn (see the layout event listener). The close control dispatches a layout event when it closes the time span events panel.

So, the first thing our listener does is check whether the Time Span Events panel has been closed; that is, removed from the list of panels maintained by the chart engine, stx. If so, we remove the event markers and pop-up displays.

Time span event pop-up displays are created by "draw" injections (see the Using API Injections tutorial). Our event listener removes the injections so they won't redraw the displays after we remove them. Then the listener calls the CIQ.TimeSpanEventPanel#removeTimeSpanEvent function to remove the event markers and their pop-up displays.

The completed file

Here's our completed hello-world.component.ts file:

import { Component, ViewChild, ElementRef, AfterViewInit, ViewEncapsulation } from '@angular/core';

import { CIQ } from 'chartiq/js/chartiq';
import "chartiq/js/advanced.js";
import "chartiq/plugins/timespanevent/timespanevent";

/**
 * The Hello World component creates a basic chart from a built-in static data source. The chart
 * does not have a user interface.
 */
@Component({
    selector: 'cq-hello-world',
    templateUrl: './hello-world.component.html',
    styleUrls: ['./hello-world.component.scss'],
    encapsulation: ViewEncapsulation.None
})
export class HelloWorldComponent implements AfterViewInit {
    @ViewChild('chartContainer', { static: true }) chartContainer: ElementRef;

    constructor() {}

    ngAfterViewInit() {
        const container = this.chartContainer.nativeElement;

        const stx = new CIQ.ChartEngine({ container });

        new CIQ.TimeSpanEventPanel({
            stx: stx,
            showTooltip: true,
            infoPanel: {
                spanEvent: "main",
                durationEvent: "main",
                singleEvent: "main"
            }
        });

        stx.loadChart('SPY', {
            masterData: this.getMasterData(),
            periodicity: {
                period: 1,
                interval: 5,
                timeUnit: 'minute',
            },
        });

        stx.timeSpanEventPanel.showTimeSpanEvent(this.getTseData("Filing"));
        stx.timeSpanEventPanel.showTimeSpanEvent(this.getTseData("Business"));
        stx.timeSpanEventPanel.showTimeSpanEvent(this.getTseData("Order"));

        stx.addEventListener("layout", ({ stx }) => {
            if (!stx.panels.timeSpanEventPanel) {
                stx.remove("draw");
                stx.timeSpanEventPanel.removeTimeSpanEvent("Filing");
                stx.timeSpanEventPanel.removeTimeSpanEvent("Business");
                stx.timeSpanEventPanel.removeTimeSpanEvent("Order");
            }
        });

    }

    /**
     * Gets the data for a swim lane of time span events.
     *
     * @param eventType Specifies the type of time span event. Must match the `type` property of
     *      a swim lane data object.
     * @return A swim lane data object, which contains an array of time span events.
     */
    getTseData(eventType) {

        // Span events.
        const businessEvents = [
            {
                label: "Business",
                spanLabel: "Product Demo",
                startDate: "2020-04-01T09:30:00",
                endDate: "2020-04-01T11:00:00",
                bgColor: "#00f",
                headline: "New Product",
                story: "Presentation to media."
            },
            {
                label: "Business",
                spanLabel: "Board Meeting",
                startDate: "2020-04-01T12:00:00",
                endDate: "2020-04-01T16:00:00",
                bgColor: "#f90",
                textColor: "#000"
            },
        ];

        // Single events.
        const filingEvents = [
            {
                label: "Filing",
                startDate: "2020-04-01T11:30",
                markerShape: "square",
                bgColor: "#a09",
                headline: "SEC Filing",
                story: "10K"
            },
            {
                label: "Filing",
                startDate: "2020-04-01T14:35:00",
                markerShape: "square",
                bgColor: "#0a0",
                headline: "SEC Filing",
                story: "10Q"
            }
        ];

        // Duration events.
        const orderEvents = [
            {
                label: "Order",
                startDate: "2020-04-01T10:00",
                endDate: "2020-04-01T11:45",
                markerShape: "circle",
                category: "trade",
                subChildren: [
                    {
                        date: new Date("2020-04-01T10:10:00"),
                        price: 156.46,
                        headline: "Trade Execution",
                        story: "Price: 156.46"
                    },
                    {
                        date: new Date("2020-04-01T10:40:00"),
                        price: 156.50,
                        headline: "Trade Execution",
                        story: "Price: 156.50"
                    },
                    {
                        date: new Date("2020-04-01T11:20:00"),
                        price: 156.43,
                        headline: "Trade Execution",
                        story: "Price: 156.43"
                    },
                    {
                        date: new Date("2020-04-01T11:45:00"),
                        price: 156.54,
                        headline: "Trade Execution",
                        story: "Price: 156.54"
                    }
                ],
                headline: "Trade Start",
                story: new Date("2020-04-01T10:00"),
                bgColor: "#aa0"
            },
            {
                label: "Order",
                startDate: "2020-04-01T13:00",
                endDate: "2020-04-01T15:25",
                markerShape: "circle",
                category: "trade",
                subChildren: [
                    {
                        date: new Date("2020-04-01T13:50:00"),
                        price: 156.55,
                        headline: "Trade Execution",
                        story: "Price: 156.55"
                    },
                    {
                        date: new Date("2020-04-01T14:25:00"),
                        price: 156.45,
                        headline: "Trade Execution",
                        story: "Price: 156.45"
                    },
                    {
                        date: new Date("2020-04-01T15:25:00"),
                        price: 156.54,
                        headline: "Trade Execution",
                        story: "Price: 156.54"
                    }
                ],
                headline: "Trade Start",
                story: new Date("2020-04-01T10:40"),
                bgColor: "#0af",
                isActive: true
            }
        ];

        // Swim lane objects.

        const business = {
            type: "Business",
            events: businessEvents,
            spanType: "spanEvent"
        }

        const filing = {
            type: "Filing",
            events: filingEvents,
            spanType: "singleEvent"
        }

        const order = {
            type: "Order",
            events: orderEvents,
            spanType: "durationEvent"
        }

        switch (eventType.toLowerCase()) {
            case "business":
                return business;
            case "filing":
                return filing;
            case "order":
                return order;
        }

    }

    getMasterData() {
        const masterData = [
            {Date:"20200331144000000",Open:156.64,High:156.66,Low:156.57,Close:156.59,Volume:932912},
            {Date:"20200331145000000",Open:156.58,High:156.62,Low:156.57,Close:156.61,Volume:700952},
            {Date:"20200331145500000",Open:156.59,High:156.60,Low:156.55,Close:156.58,Volume:1084428},
            {Date:"20200331150000000",Open:156.57,High:156.58,Low:156.53,Close:156.55,Volume:916684},
            {Date:"20200331150500000",Open:156.54,High:156.57,Low:156.52,Close:156.55,Volume:1360390},
            {Date:"20200331151000000",Open:156.56,High:156.60,Low:156.54,Close:156.58,Volume:2037170},
            {Date:"20200331151500000",Open:156.55,High:156.62,Low:156.54,Close:156.60,Volume:4280833},
            {Date:"20200331152000000",Open:156.61,High:156.62,Low:156.54,Close:156.57,Volume:3348274},
            {Date:"20200331152500000",Open:156.59,High:156.62,Low:156.52,Close:156.54,Volume:932912},
            {Date:"20200331153000000",Open:156.56,High:156.57,Low:156.50,Close:156.52,Volume:700952},
            {Date:"20200331153500000",Open:156.51,High:156.56,Low:156.50,Close:156.54,Volume:1084428},
            {Date:"20200331154000000",Open:156.52,High:156.56,Low:156.51,Close:156.55,Volume:916684},
            {Date:"20200331154500000",Open:156.56,High:156.57,Low:156.50,Close:156.53,Volume:1360390},
            {Date:"20200331155000000",Open:156.52,High:156.53,Low:156.49,Close:156.50,Volume:2037170},
            {Date:"20200331155500000",Open:156.51,High:156.52,Low:156.46,Close:156.48,Volume:4280833},
            {Date:"20200331160000000",Open:156.49,High:156.48,Low:156.44,Close:156.47,Volume:3348274},
            {Date:"20200401093000000",Open:156.41,High:156.48,Low:156.39,Close:156.46,Volume:1869466},
            {Date:"20200401093500000",Open:156.44,High:156.53,Low:156.40,Close:156.49,Volume:2937883},
            {Date:"20200401094000000",Open:156.48,High:156.54,Low:156.37,Close:156.43,Volume:2277682},
            {Date:"20200401094500000",Open:156.47,High:156.55,Low:156.45,Close:156.51,Volume:1714687},
            {Date:"20200401095000000",Open:156.49,High:156.58,Low:156.48,Close:156.54,Volume:1902583},
            {Date:"20200401095500000",Open:156.54,High:156.59,Low:156.50,Close:156.56,Volume:1325148},
            {Date:"20200401100000000",Open:156.56,High:156.60,Low:156.50,Close:156.53,Volume:2005588},
            {Date:"20200401100500000",Open:156.52,High:156.54,Low:156.42,Close:156.43,Volume:1277880},
            {Date:"20200401101000000",Open:156.44,High:156.46,Low:156.36,Close:156.37,Volume:1158301},
            {Date:"20200401101500000",Open:156.38,High:156.39,Low:156.26,Close:156.28,Volume:1987415},
            {Date:"20200401102000000",Open:156.26,High:156.33,Low:156.22,Close:156.32,Volume:1512742},
            {Date:"20200401102500000",Open:156.31,High:156.40,Low:156.31,Close:156.39,Volume:871592},
            {Date:"20200401103000000",Open:156.38,High:156.43,Low:156.35,Close:156.40,Volume:1132109},
            {Date:"20200401103500000",Open:156.40,High:156.44,Low:156.37,Close:156.41,Volume:725521},
            {Date:"20200401104000000",Open:156.41,High:156.50,Low:156.41,Close:156.48,Volume:704072},
            {Date:"20200401104500000",Open:156.48,High:156.50,Low:156.42,Close:156.46,Volume:844084},
            {Date:"20200401105000000",Open:156.47,High:156.47,Low:156.42,Close:156.45,Volume:392122},
            {Date:"20200401105500000",Open:156.45,High:156.47,Low:156.38,Close:156.41,Volume:544729},
            {Date:"20200401110000000",Open:156.43,High:156.47,Low:156.41,Close:156.44,Volume:660383},
            {Date:"20200401110500000",Open:156.43,High:156.47,Low:156.40,Close:156.41,Volume:640177},
            {Date:"20200401111000000",Open:156.41,High:156.44,Low:156.35,Close:156.39,Volume:845668},
            {Date:"20200401111500000",Open:156.38,High:156.41,Low:156.37,Close:156.39,Volume:503347},
            {Date:"20200401112000000",Open:156.39,High:156.43,Low:156.38,Close:156.41,Volume:360929},
            {Date:"20200401112500000",Open:156.40,High:156.42,Low:156.37,Close:156.38,Volume:749554},
            {Date:"20200401113000000",Open:156.39,High:156.44,Low:156.38,Close:156.42,Volume:723857},
            {Date:"20200401113500000",Open:156.40,High:156.45,Low:156.40,Close:156.44,Volume:455561},
            {Date:"20200401114000000",Open:156.43,High:156.48,Low:156.42,Close:156.45,Volume:670704},
            {Date:"20200401114500000",Open:156.44,High:156.54,Low:156.44,Close:156.50,Volume:827725},
            {Date:"20200401115000000",Open:156.51,High:156.55,Low:156.48,Close:156.53,Volume:828780},
            {Date:"20200401115500000",Open:156.53,High:156.55,Low:156.48,Close:156.49,Volume:687357},
            {Date:"20200401120000000",Open:156.48,High:156.52,Low:156.48,Close:156.51,Volume:343617},
            {Date:"20200401120500000",Open:156.50,High:156.58,Low:156.50,Close:156.57,Volume:444181},
            {Date:"20200401121000000",Open:156.57,High:156.61,Low:156.56,Close:156.57,Volume:932850},
            {Date:"20200401121500000",Open:156.58,High:156.63,Low:156.56,Close:156.61,Volume:622879},
            {Date:"20200401122000000",Open:156.61,High:156.64,Low:156.54,Close:156.56,Volume:417197},
            {Date:"20200401122500000",Open:156.57,High:156.60,Low:156.54,Close:156.56,Volume:524792},
            {Date:"20200401123000000",Open:156.57,High:156.63,Low:156.56,Close:156.63,Volume:547832},
            {Date:"20200401123500000",Open:156.63,High:156.69,Low:156.62,Close:156.65,Volume:1033940},
            {Date:"20200401124000000",Open:156.65,High:156.66,Low:156.59,Close:156.60,Volume:666020},
            {Date:"20200401124500000",Open:156.60,High:156.63,Low:156.52,Close:156.54,Volume:886571},
            {Date:"20200401125000000",Open:156.54,High:156.59,Low:156.53,Close:156.57,Volume:409824},
            {Date:"20200401125500000",Open:156.57,High:156.57,Low:156.52,Close:156.53,Volume:490971},
            {Date:"20200401130000000",Open:156.53,High:156.62,Low:156.53,Close:156.62,Volume:618202},
            {Date:"20200401130500000",Open:156.62,High:156.63,Low:156.56,Close:156.56,Volume:232977},
            {Date:"20200401131000000",Open:156.56,High:156.58,Low:156.52,Close:156.52,Volume:569834},
            {Date:"20200401131500000",Open:156.53,High:156.55,Low:156.50,Close:156.54,Volume:526717},
            {Date:"20200401132000000",Open:156.54,High:156.54,Low:156.48,Close:156.52,Volume:587983},
            {Date:"20200401132500000",Open:156.52,High:156.52,Low:156.46,Close:156.46,Volume:683988},
            {Date:"20200401133000000",Open:156.46,High:156.48,Low:156.44,Close:156.44,Volume:505235},
            {Date:"20200401133500000",Open:156.45,High:156.46,Low:156.41,Close:156.44,Volume:760274},
            {Date:"20200401134000000",Open:156.45,High:156.45,Low:156.41,Close:156.42,Volume:428196},
            {Date:"20200401134500000",Open:156.43,High:156.49,Low:156.42,Close:156.49,Volume:372145},
            {Date:"20200401135000000",Open:156.49,High:156.55,Low:156.42,Close:156.42,Volume:493463},
            {Date:"20200401135500000",Open:156.42,High:156.46,Low:156.37,Close:156.38,Volume:763911},
            {Date:"20200401140000000",Open:156.38,High:156.44,Low:156.38,Close:156.43,Volume:478714},
            {Date:"20200401140500000",Open:156.43,High:156.48,Low:156.40,Close:156.47,Volume:347221},
            {Date:"20200401141000000",Open:156.46,High:156.48,Low:156.44,Close:156.45,Volume:527388},
            {Date:"20200401141500000",Open:156.46,High:156.47,Low:156.39,Close:156.46,Volume:1254489},
            {Date:"20200401142000000",Open:156.47,High:156.52,Low:156.43,Close:156.50,Volume:588877},
            {Date:"20200401142500000",Open:156.49,High:156.50,Low:156.45,Close:156.46,Volume:391738},
            {Date:"20200401143000000",Open:156.46,High:156.50,Low:156.43,Close:156.46,Volume:835468},
            {Date:"20200401143500000",Open:156.46,High:156.51,Low:156.45,Close:156.48,Volume:465308},
            {Date:"20200401144000000",Open:156.48,High:156.50,Low:156.47,Close:156.49,Volume:389872},
            {Date:"20200401144500000",Open:156.48,High:156.53,Low:156.48,Close:156.50,Volume:530820},
            {Date:"20200401145000000",Open:156.50,High:156.53,Low:156.48,Close:156.53,Volume:554269},
            {Date:"20200401145500000",Open:156.53,High:156.57,Low:156.52,Close:156.56,Volume:622473},
            {Date:"20200401150000000",Open:156.57,High:156.59,Low:156.53,Close:156.59,Volume:593592},
            {Date:"20200401150500000",Open:156.59,High:156.61,Low:156.56,Close:156.58,Volume:1089712},
            {Date:"20200401151000000",Open:156.59,High:156.59,Low:156.55,Close:156.57,Volume:634702},
            {Date:"20200401151500000",Open:156.57,High:156.64,Low:156.57,Close:156.60,Volume:1206417},
            {Date:"20200401152000000",Open:156.60,High:156.61,Low:156.58,Close:156.60,Volume:641636},
            {Date:"20200401152500000",Open:156.59,High:156.60,Low:156.54,Close:156.55,Volume:873698},
            {Date:"20200401153000000",Open:156.55,High:156.64,Low:156.55,Close:156.59,Volume:1318720},
            {Date:"20200401153500000",Open:156.60,High:156.68,Low:156.59,Close:156.68,Volume:1520610},
            {Date:"20200401154000000",Open:156.68,High:156.74,Low:156.67,Close:156.74,Volume:1678678},
            {Date:"20200401154500000",Open:156.74,High:156.80,Low:156.73,Close:156.76,Volume:2854531},
            {Date:"20200401155000000",Open:156.75,High:156.79,Low:156.71,Close:156.72,Volume:2984534},
            {Date:"20200401155500000",Open:156.71,High:156.75,Low:156.63,Close:156.73,Volume:7105595},
            {Date:"20200401160000000",Open:156.73,High:156.78,Low:156.71,Close:156.77,Volume:3863507}
        ];
        return masterData;
    }
}

Run it!

Reload http://localhost:4200/hello-world and try interacting with the event markers. Close the panel with some pop-up displays on screen (you'll have to reload the page to reopen the panel.)

Here's the chart with several time span event markers and sub-event markers selected:

Basic chart with time span events and sub-events selected Figure. Basic chart with time span events and sub-events selected.

Customization

Let's makes some changes to the pop-up displays and sub-event markers.

First, we'll increase the background opacity of the pop-up boxes and give them a dark border.

Open chartiq.css (you'll find it in the css folder of your library or in the node_modules/chartiq/css folder of the project).

Search for ".stx-performance-marker.stx-marker-expand":

.stx-performance-marker.stx-marker-expand {
    background: rgba(255, 255, 255, 0.75);
    max-width: 200px;
    max-height: 200px;
    padding: 10px;
    opacity: 1;
    color: #000;
    display: block;
    border: 1px solid rgba(255, 255, 255, 0.3);
    overflow: auto;
    position: absolute;
}

Copy the rule-set to hello-world.component.scss.

Place it after the imported style sheets so that it succeeds them in the CSS cascade.

Note: You should never change any of the CSS files in your library. You can always override or modify a style by redefining it later in the CSS cascade. Also, keeping your CSS changes in a separate customizations file or folder makes upgrading the library easier.

Revise the rule-set as follows:

.stx-performance-marker.stx-marker-expand {
    background: rgba(255, 255, 255, 0.90);
    max-width: 200px;
    max-height: 200px;
    padding: 10px;
    opacity: 1;
    color: #000;
    display: block;
    border: 1px solid rgba(180, 180, 180, 0.90);
    overflow: auto;
    position: absolute;
}

Next, let's restyle the pop-up display text.

Open tradeAnalyticsSample.css (in the examples/markers folder of your library or the node_modules/chartiq/examples/markers folder of the project).

Copy the h4 heading rule-set to hello-world.component.scss:

.stx-performance-marker.stx-marker-expand h4 {
    display: block;
}

Change the font size of the heading:

.stx-performance-marker.stx-marker-expand h4 {
    display: block;
    font-size: 0.80rem;
}

Change the look of the pop-up display body text by creating a new rule-set:

.stx-performance-marker.stx-marker-expand p {
    font-variant: small-caps;
}

Finally, let's make the sub-event markers a little larger.

Copy the following rule-set from tradeAnalyticsSample.css to hello-world.component.scss:

.stx-marker.trade .stx-visual {
    background: #C950d7;
    width: 5px;
    height: 5px;
}

Revise the values for width and height:

.stx-marker.trade .stx-visual {
    background: #C950d7;
    width: 8px;
    height: 8px;
}

Note: Changing the background color in this rule-set won't have any effect. The setting is overridden by the color we specified in the event data objects (see the bgColor property in the event object arrays in hello-world.component.ts). Remove the bgColor property from an event object, then modify the CSS. (See the Event data objects section of the Creating a Data Source tutorial for information on the bgColor property.)

Here are the final contents of hello-world.component.scss:

@import '~chartiq/css/stx-chart.css'; // Chart API
@import "~chartiq/css/chartiq.css";
@import "~chartiq/examples/markers/tradeAnalyticsSample.css";

// Customize the sub-event markers and pop-up displays.

// Sub-event marker pop-up displays.
.stx-performance-marker.stx-marker-expand {
    background: rgba(255, 255, 255, 0.90);
    max-width: 200px;
    max-height: 200px;
    padding: 10px;
    opacity: 1;
    color: #000;
    display: block;
    border: 1px solid rgba(180, 180, 180, 0.90);
    overflow: auto;
    position: absolute;
}

// Pop-up display heading text.
.stx-performance-marker.stx-marker-expand h4 {
    display: block;
    font-size: 0.80rem;
}

// Pop-up display body text.
.stx-performance-marker.stx-marker-expand p {
    font-variant: small-caps;
}

// Sub-event markers.
.stx-marker.trade .stx-visual {
    background: #C950d7;
    width: 8px;
    height: 8px;
}

And here are our customizations:

Basic chart with time span events and customized sub-event markers and pop-up displays Figure. Basic chart with time span events and customized sub-event markers and pop-up displays.

For information on how the CSS selectors used above relate to the structure of sub-event marker DOM elements and their class attributes, see CSS in the "Customization" section of the Creating a Data Source tutorial.

Conclusion

In this tutorial you learned the basics of adding time span events to Angular charting applications.

Save your Angular project because we'll use it in the next tutorial to create an example of time span events controlled from the user interface.

Next Steps: