Time Span Events

Hello World Example

Time span events can be added to your charting applications with just a few lines of JavaScript code. With a properly formatted data source, your charts can easily offer the powerful visualization capabilities of ChartIQ's Time Span Events module.

In this tutorial

You will customize the helloworld.html template to automatically display time span events when the 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 Creating a Data Source tutorial. Please familiarize yourself with the data source information before proceeding.

helloworld.html

The helloworld.html template displays a basic time series chart. The time series data comes from a static data source. The chart does not have a user interface.

The template is in the root folder of your charting library.

Here are the contents of the file:

<!doctype html>
<!--
This file provides an example of the most basic way to load a chart into an HTML page. It includes no UI.
-->
<html>
<head>
<!-- Set the display for mobile devices. -->
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">

<!-- Reference the default style sheet. -->
<link rel="stylesheet" type="text/css" href="css/stx-chart.css" media="screen" />
</head>

<body>

<!--
Create the chart container. The container can be positioned anywhere on your web page and sized any way you wish,
but the CSS position property must have the value "relative".
-->
<div class="chartContainer" style="width:800px;height:460px;position:relative;"></div>

<script type="module" crossorigin="use-credentials">
// This inline script acts as the entry point, without creating a separate external file.

// Reference a file of statically defined chart data.
import sample5min from "./examples/data/STX_SAMPLE_5MIN.js";

// Reference the charting library.
import { CIQ } from "./js/chartiq.js";

// Instantiate a CIQ.ChartEngine object, the main object for creating charts.
let stxx = new CIQ.ChartEngine({
    container: document.querySelector(".chartContainer")
});

// Display the chart.  The five-minute periodicity matches the sample data.
stxx.loadChart("SPY", {
    masterData: sample5min,
    periodicity: {
        period: 1,
        interval: 5,
        timeUnit: "minute"
    }
});
</script>
</body>
</html>

Sample data source

The static data source for the chart created by helloworld.html is provided by the STX_SAMPLE_5MIN.js file (see the examples/data folder of your library).

We'll create time span event data objects based on the chart's data source, so let's replace STX_SAMPLE_5MIN.js with a sample data source that better suits our purposes.

Create the data source

Open helloworld.html in your editor.

Add the following script to the bottom of helloworld.html inside the body tag:

<script>
const sampleData = [
    {Date:"2020-03-31 14:40", Open:156.64, High:156.66, Low:156.57, Close:156.59, Volume:932912},
    {Date:"2020-03-31 14:50", Open:156.58, High:156.62, Low:156.57, Close:156.61, Volume:700952},
    {Date:"2020-03-31 14:55", Open:156.59, High:156.60, Low:156.55, Close:156.58, Volume:1084428},
    {Date:"2020-03-31 15:00", Open:156.57, High:156.58, Low:156.53, Close:156.55, Volume:916684},
    {Date:"2020-03-31 15:05", Open:156.54, High:156.57, Low:156.52, Close:156.55, Volume:1360390},
    {Date:"2020-03-31 15:10", Open:156.56, High:156.60, Low:156.54, Close:156.58, Volume:2037170},
    {Date:"2020-03-31 15:15", Open:156.55, High:156.62, Low:156.54, Close:156.60, Volume:4280833},
    {Date:"2020-03-31 15:20", Open:156.61, High:156.62, Low:156.54, Close:156.57, Volume:3348274},
    {Date:"2020-03-31 15:25", Open:156.59, High:156.62, Low:156.52, Close:156.54, Volume:932912},
    {Date:"2020-03-31 15:30", Open:156.56, High:156.57, Low:156.50, Close:156.52, Volume:700952},
    {Date:"2020-03-31 15:35", Open:156.51, High:156.56, Low:156.50, Close:156.54, Volume:1084428},
    {Date:"2020-03-31 15:40", Open:156.52, High:156.56, Low:156.51, Close:156.55, Volume:916684},
    {Date:"2020-03-31 15:45", Open:156.56, High:156.57, Low:156.50, Close:156.53, Volume:1360390},
    {Date:"2020-03-31 15:50", Open:156.52, High:156.53, Low:156.49, Close:156.50, Volume:2037170},
    {Date:"2020-03-31 15:55", Open:156.51, High:156.52, Low:156.46, Close:156.48, Volume:4280833},
    {Date:"2020-03-31 16:00", Open:156.49, High:156.48, Low:156.44, Close:156.47, Volume:3348274},
    {Date:"2020-04-01 09:30", Open:156.41, High:156.48, Low:156.39, Close:156.46, Volume:1869466},
    {Date:"2020-04-01 09:35", Open:156.44, High:156.53, Low:156.40, Close:156.49, Volume:2937883},
    {Date:"2020-04-01 09:40", Open:156.48, High:156.54, Low:156.37, Close:156.43, Volume:2277682},
    {Date:"2020-04-01 09:45", Open:156.47, High:156.55, Low:156.45, Close:156.51, Volume:1714687},
    {Date:"2020-04-01 09:50", Open:156.49, High:156.58, Low:156.48, Close:156.54, Volume:1902583},
    {Date:"2020-04-01 09:55", Open:156.54, High:156.59, Low:156.50, Close:156.56, Volume:1325148},
    {Date:"2020-04-01 10:00", Open:156.56, High:156.60, Low:156.50, Close:156.53, Volume:2005588},
    {Date:"2020-04-01 10:05", Open:156.52, High:156.54, Low:156.42, Close:156.43, Volume:1277880},
    {Date:"2020-04-01 10:10", Open:156.44, High:156.46, Low:156.36, Close:156.37, Volume:1158301},
    {Date:"2020-04-01 10:15", Open:156.38, High:156.39, Low:156.26, Close:156.28, Volume:1987415},
    {Date:"2020-04-01 10:20", Open:156.26, High:156.33, Low:156.22, Close:156.32, Volume:1512742},
    {Date:"2020-04-01 10:25", Open:156.31, High:156.40, Low:156.31, Close:156.39, Volume:871592},
    {Date:"2020-04-01 10:30", Open:156.38, High:156.43, Low:156.35, Close:156.40, Volume:1132109},
    {Date:"2020-04-01 10:35", Open:156.40, High:156.44, Low:156.37, Close:156.41, Volume:725521},
    {Date:"2020-04-01 10:40", Open:156.41, High:156.50, Low:156.41, Close:156.48, Volume:704072},
    {Date:"2020-04-01 10:45", Open:156.48, High:156.50, Low:156.42, Close:156.46, Volume:844084},
    {Date:"2020-04-01 10:50", Open:156.47, High:156.47, Low:156.42, Close:156.45, Volume:392122},
    {Date:"2020-04-01 10:55", Open:156.45, High:156.47, Low:156.38, Close:156.41, Volume:544729},
    {Date:"2020-04-01 11:00", Open:156.43, High:156.47, Low:156.41, Close:156.44, Volume:660383},
    {Date:"2020-04-01 11:05", Open:156.43, High:156.47, Low:156.40, Close:156.41, Volume:640177},
    {Date:"2020-04-01 11:10", Open:156.41, High:156.44, Low:156.35, Close:156.39, Volume:845668},
    {Date:"2020-04-01 11:15", Open:156.38, High:156.41, Low:156.37, Close:156.39, Volume:503347},
    {Date:"2020-04-01 11:20", Open:156.39, High:156.43, Low:156.38, Close:156.41, Volume:360929},
    {Date:"2020-04-01 11:25", Open:156.40, High:156.42, Low:156.37, Close:156.38, Volume:749554},
    {Date:"2020-04-01 11:30", Open:156.39, High:156.44, Low:156.38, Close:156.42, Volume:723857},
    {Date:"2020-04-01 11:35", Open:156.40, High:156.45, Low:156.40, Close:156.44, Volume:455561},
    {Date:"2020-04-01 11:40", Open:156.43, High:156.48, Low:156.42, Close:156.45, Volume:670704},
    {Date:"2020-04-01 11:45", Open:156.44, High:156.54, Low:156.44, Close:156.50, Volume:827725},
    {Date:"2020-04-01 11:50", Open:156.51, High:156.55, Low:156.48, Close:156.53, Volume:828780},
    {Date:"2020-04-01 11:55", Open:156.53, High:156.55, Low:156.48, Close:156.49, Volume:687357},
    {Date:"2020-04-01 12:00", Open:156.48, High:156.52, Low:156.48, Close:156.51, Volume:343617},
    {Date:"2020-04-01 12:05", Open:156.50, High:156.58, Low:156.50, Close:156.57, Volume:444181},
    {Date:"2020-04-01 12:10", Open:156.57, High:156.61, Low:156.56, Close:156.57, Volume:932850},
    {Date:"2020-04-01 12:15", Open:156.58, High:156.63, Low:156.56, Close:156.61, Volume:622879},
    {Date:"2020-04-01 12:20", Open:156.61, High:156.64, Low:156.54, Close:156.56, Volume:417197},
    {Date:"2020-04-01 12:25", Open:156.57, High:156.60, Low:156.54, Close:156.56, Volume:524792},
    {Date:"2020-04-01 12:30", Open:156.57, High:156.63, Low:156.56, Close:156.63, Volume:547832},
    {Date:"2020-04-01 12:35", Open:156.63, High:156.69, Low:156.62, Close:156.65, Volume:1033940},
    {Date:"2020-04-01 12:40", Open:156.65, High:156.66, Low:156.59, Close:156.60, Volume:666020},
    {Date:"2020-04-01 12:45", Open:156.60, High:156.63, Low:156.52, Close:156.54, Volume:886571},
    {Date:"2020-04-01 12:50", Open:156.54, High:156.59, Low:156.53, Close:156.57, Volume:409824},
    {Date:"2020-04-01 12:55", Open:156.57, High:156.57, Low:156.52, Close:156.53, Volume:490971},
    {Date:"2020-04-01 13:00", Open:156.53, High:156.62, Low:156.53, Close:156.62, Volume:618202},
    {Date:"2020-04-01 13:05", Open:156.62, High:156.63, Low:156.56, Close:156.56, Volume:232977},
    {Date:"2020-04-01 13:10", Open:156.56, High:156.58, Low:156.52, Close:156.52, Volume:569834},
    {Date:"2020-04-01 13:15", Open:156.53, High:156.55, Low:156.50, Close:156.54, Volume:526717},
    {Date:"2020-04-01 13:20", Open:156.54, High:156.54, Low:156.48, Close:156.52, Volume:587983},
    {Date:"2020-04-01 13:25", Open:156.52, High:156.52, Low:156.46, Close:156.46, Volume:683988},
    {Date:"2020-04-01 13:30", Open:156.46, High:156.48, Low:156.44, Close:156.44, Volume:505235},
    {Date:"2020-04-01 13:35", Open:156.45, High:156.46, Low:156.41, Close:156.44, Volume:760274},
    {Date:"2020-04-01 13:40", Open:156.45, High:156.45, Low:156.41, Close:156.42, Volume:428196},
    {Date:"2020-04-01 13:45", Open:156.43, High:156.49, Low:156.42, Close:156.49, Volume:372145},
    {Date:"2020-04-01 13:50", Open:156.49, High:156.55, Low:156.42, Close:156.42, Volume:493463},
    {Date:"2020-04-01 13:55", Open:156.42, High:156.46, Low:156.37, Close:156.38, Volume:763911},
    {Date:"2020-04-01 14:00", Open:156.38, High:156.44, Low:156.38, Close:156.43, Volume:478714},
    {Date:"2020-04-01 14:05", Open:156.43, High:156.48, Low:156.40, Close:156.47, Volume:347221},
    {Date:"2020-04-01 14:10", Open:156.46, High:156.48, Low:156.44, Close:156.45, Volume:527388},
    {Date:"2020-04-01 14:15", Open:156.46, High:156.47, Low:156.39, Close:156.46, Volume:1254489},
    {Date:"2020-04-01 14:20", Open:156.47, High:156.52, Low:156.43, Close:156.50, Volume:588877},
    {Date:"2020-04-01 14:25", Open:156.49, High:156.50, Low:156.45, Close:156.46, Volume:391738},
    {Date:"2020-04-01 14:30", Open:156.46, High:156.50, Low:156.43, Close:156.46, Volume:835468},
    {Date:"2020-04-01 14:35", Open:156.46, High:156.51, Low:156.45, Close:156.48, Volume:465308},
    {Date:"2020-04-01 14:40", Open:156.48, High:156.50, Low:156.47, Close:156.49, Volume:389872},
    {Date:"2020-04-01 14:45", Open:156.48, High:156.53, Low:156.48, Close:156.50, Volume:530820},
    {Date:"2020-04-01 14:50", Open:156.50, High:156.53, Low:156.48, Close:156.53, Volume:554269},
    {Date:"2020-04-01 14:55", Open:156.53, High:156.57, Low:156.52, Close:156.56, Volume:622473},
    {Date:"2020-04-01 15:00", Open:156.57, High:156.59, Low:156.53, Close:156.59, Volume:593592},
    {Date:"2020-04-01 15:05", Open:156.59, High:156.61, Low:156.56, Close:156.58, Volume:1089712},
    {Date:"2020-04-01 15:10", Open:156.59, High:156.59, Low:156.55, Close:156.57, Volume:634702},
    {Date:"2020-04-01 15:15", Open:156.57, High:156.64, Low:156.57, Close:156.60, Volume:1206417},
    {Date:"2020-04-01 15:20", Open:156.60, High:156.61, Low:156.58, Close:156.60, Volume:641636},
    {Date:"2020-04-01 15:25", Open:156.59, High:156.60, Low:156.54, Close:156.55, Volume:873698},
    {Date:"2020-04-01 15:30", Open:156.55, High:156.64, Low:156.55, Close:156.59, Volume:1318720},
    {Date:"2020-04-01 15:35", Open:156.60, High:156.68, Low:156.59, Close:156.68, Volume:1520610},
    {Date:"2020-04-01 15:40", Open:156.68, High:156.74, Low:156.67, Close:156.74, Volume:1678678},
    {Date:"2020-04-01 15:45", Open:156.74, High:156.80, Low:156.73, Close:156.76, Volume:2854531},
    {Date:"2020-04-01 15:50", Open:156.75, High:156.79, Low:156.71, Close:156.72, Volume:2984534},
    {Date:"2020-04-01 15:55", Open:156.71, High:156.75, Low:156.63, Close:156.73, Volume:7105595},
    {Date:"2020-04-01 16:00", Open:156.73, High:156.78, Low:156.71, Close:156.77, Volume:3863507}
];
</script>

The sampleData variable represents the new static data source. The variable is assigned an array of object literals, each of which represents a stock quote.

Our time span event data objects will be based on these simulated quotes; primarily their dates, but also their price values.

Update the chart data source

Revise the value of the masterData property in the call to the loadChart function. Set sampleData as the value (replacing sample5min):

stxx.loadChart("SPY", {
	masterData: sampleData,
	periodicity: {
		period: 1,
		interval: 5,
		timeUnit: 'minute'
	}
});

Remove the old data source

Remove the following lines from helloworld.html:

// Reference a file of statically defined chart data.
import sample5min from "./examples/data/STX_SAMPLE_5MIN.js";

Run it!

Load helloworld.html from your editor or on a web server. The chart should look like this:

Basic chart with static data source Figure. Basic chart with static data source.

Add the Time Span Events plug-in

Now, for the real work of creating time span events.

The first thing we need to do is make the Time Span Events plug-in part of our application.

Add the following import to helloworld.html:

import "./plugins/timespanevent/timespanevent.js";

The plug-in import must come after the import that references the charting library; for example:

// Reference the charting library.
import {CIQ} from "./js/chartiq.js";

// Access the Time Span Events plug-in.
import "./plugins/timespanevent/timespanevent.js";

The Time Span Events plug-in relies on library routines to create the visual markers that depict time span events; and so, we need to give the plug‑in access to the marker code.

Add the following import to helloworld.html:

import "./js/advanced.js";

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

// Access markers.
import "./js/advanced.js";

// Access the Time Span Events plug-in.
import "./plugins/timespanevent/timespanevent.js";

The plug-in uses jQuery, so we need to also add jQuery to helloworld.html.

Add the following script tag as the last line in the <head> section of the file:

<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js'></script>

Instantiate the Time Span Events panel

Now that the plug-in has been added and properly set up, we can create an instance of the Time Span Events panel. Time span event markers are displayed in the panel.

Add the following to helloworld.html:

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

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

// Instantiate a CIQ.ChartEngine object, the main object for creating charts.
let stxx = new CIQ.ChartEngine({
    container: document.querySelector(".chartContainer")
});

// Instantiate the Time Span Events panel object.
new CIQ.TimeSpanEventPanel({
    stx: stxx,
    showTooltip: true,
    infoPanel: {
        spanEvent: "main",
        durationEvent: "main",
        singleEvent: "main"
    }
});

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 some time span events and for the swim lanes in which the events appear. The data access objects are based on the chart's sample data source.

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 script at the bottom of helloworld.html:

<script>
// 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
    }
];
</script>

All the dates and prices correspond to elements in sampleData (see sample data source). You can locate the data elements from the date and time values of the time span events.

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

Swim lane data objects

We now have to create swim lane data access objects that hold the time span events and specify their type.

Add the following object declarations to the script tag that contains the array declarations for the event data objects:

Note: Add the code 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"
}

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 after the loadChart function in helloworld.html:

stxx.timeSpanEventPanel.showTimeSpanEvent(filing);
stxx.timeSpanEventPanel.showTimeSpanEvent(business);
stxx.timeSpanEventPanel.showTimeSpanEvent(order);

The chart engine, stxx, 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!

Load helloworld.html from your editor or on a web server. The chart should now look like this:

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. You should see spots (or squares) — big ones. Select one of the spots. A pop‑up display should appear, but way out of position, maybe even off the screen to the right (you can scroll the chart to look for it).

Some CSS is needed.

Add the style sheets

CSS files provide the styles for the sub-event markers and sub-event pop-up displays.

Add the following link tags to helloworld.html:

<link rel="stylesheet" type="text/css" href="css/chartiq.css" media="screen" />

<link rel="stylesheet" type="text/css" href="examples/markers/tradeAnalyticsSample.css" media="screen" />

The chartiq.css file takes care of the pop-up display positioning and styling; tradeAnalyticsSample.css styles the sub-event markers.

The tags must be placed in the following order to create the correct cascade of styles: tradeAnalyticsSample.css must follow chartiq.css; both must follow stx-chart.css, which is the main style sheet for charts.

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.

We can fix that.

Add the following after the calls to showTimeSpanEvent in helloworld.html:

stxx.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 managed by the chart engine, stxx. 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 what our completed helloworld.html file should look like:

<!doctype html>
<!--
This file provides an example of the most basic way to load a chart into an HTML page. It includes no UI.
-->
<html>
<head>
<!-- Set the display for mobile devices. -->
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1">

<!-- Reference the default style sheet. -->
<link rel="stylesheet" type="text/css" href="css/stx-chart.css" media="screen" />

<!-- Position and style the time span event marker pop-up displays. -->
<link rel="stylesheet" type="text/css" href="css/chartiq.css" media="screen" />

<!-- Style the sub-event markers. -->
<link rel="stylesheet" type="text/css" href="examples/markers/tradeAnalyticsSample.css" media="screen" />

<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js'></script>
</head>

<body>

<!--
Create the chart container. The container can be positioned anywhere on your web page and sized any way you wish,
but the CSS position property must have the value "relative".
-->
<div class="chartContainer" style="width:800px;height:460px;position:relative;"></div>

<script type="module" crossorigin="use-credentials">

// This inline script acts as the entry point, without creating a separate external file.

// Reference the charting library.
import {CIQ} from "./js/chartiq.js";

// Access markers.
import "./js/advanced.js";

// Access the Time Span Events plug-in.
import "./plugins/timespanevent/timespanevent.js";

// Instantiate a CIQ.ChartEngine object, the main object for creating charts.
let stxx=new CIQ.ChartEngine({container:document.querySelector(".chartContainer")});

// Instantiate the Time Span Events panel object.
new CIQ.TimeSpanEventPanel({
    stx: stxx,
    showTooltip: true,
    infoPanel: {
        spanEvent: "main",
        durationEvent: "main",
        singleEvent: "main"
    }
});

// Display the chart.  The five-minute periodicity matches the sample data.
stxx.loadChart("SPY", {
    masterData: sampleData,
    periodicity: {
        period: 1,
        interval: 5,
        timeUnit: 'minute'
    }
});

// Create the time span event swim lanes.
stxx.timeSpanEventPanel.showTimeSpanEvent(filing);
stxx.timeSpanEventPanel.showTimeSpanEvent(business);
stxx.timeSpanEventPanel.showTimeSpanEvent(order);

// Respond to the close control of the Time Span Events panel.
stxx.addEventListener("layout", ({ stx }) => {
	if (!stx.panels.timeSpanEventPanel) {
        // Remove the "draw" injections that create the sub-event pop-up displays.
        stx.remove("draw");
        // Remove the event swim lanes and any sub-event markers and pop-up displays.
        stx.timeSpanEventPanel.removeTimeSpanEvent("Filing");
        stx.timeSpanEventPanel.removeTimeSpanEvent("Business");
        stx.timeSpanEventPanel.removeTimeSpanEvent("Order");
    }
});

</script>

<script>
const sampleData = [
    {Date:"2020-03-31 14:40", Open:156.64, High:156.66, Low:156.57, Close:156.59, Volume:932912},
    {Date:"2020-03-31 14:50", Open:156.58, High:156.62, Low:156.57, Close:156.61, Volume:700952},
    {Date:"2020-03-31 14:55", Open:156.59, High:156.60, Low:156.55, Close:156.58, Volume:1084428},
    {Date:"2020-03-31 15:00", Open:156.57, High:156.58, Low:156.53, Close:156.55, Volume:916684},
    {Date:"2020-03-31 15:05", Open:156.54, High:156.57, Low:156.52, Close:156.55, Volume:1360390},
    {Date:"2020-03-31 15:10", Open:156.56, High:156.60, Low:156.54, Close:156.58, Volume:2037170},
    {Date:"2020-03-31 15:15", Open:156.55, High:156.62, Low:156.54, Close:156.60, Volume:4280833},
    {Date:"2020-03-31 15:20", Open:156.61, High:156.62, Low:156.54, Close:156.57, Volume:3348274},
    {Date:"2020-03-31 15:25", Open:156.59, High:156.62, Low:156.52, Close:156.54, Volume:932912},
    {Date:"2020-03-31 15:30", Open:156.56, High:156.57, Low:156.50, Close:156.52, Volume:700952},
    {Date:"2020-03-31 15:35", Open:156.51, High:156.56, Low:156.50, Close:156.54, Volume:1084428},
    {Date:"2020-03-31 15:40", Open:156.52, High:156.56, Low:156.51, Close:156.55, Volume:916684},
    {Date:"2020-03-31 15:45", Open:156.56, High:156.57, Low:156.50, Close:156.53, Volume:1360390},
    {Date:"2020-03-31 15:50", Open:156.52, High:156.53, Low:156.49, Close:156.50, Volume:2037170},
    {Date:"2020-03-31 15:55", Open:156.51, High:156.52, Low:156.46, Close:156.48, Volume:4280833},
    {Date:"2020-03-31 16:00", Open:156.49, High:156.48, Low:156.44, Close:156.47, Volume:3348274},
    {Date:"2020-04-01 09:30", Open:156.41, High:156.48, Low:156.39, Close:156.46, Volume:1869466},
    {Date:"2020-04-01 09:35", Open:156.44, High:156.53, Low:156.40, Close:156.49, Volume:2937883},
    {Date:"2020-04-01 09:40", Open:156.48, High:156.54, Low:156.37, Close:156.43, Volume:2277682},
    {Date:"2020-04-01 09:45", Open:156.47, High:156.55, Low:156.45, Close:156.51, Volume:1714687},
    {Date:"2020-04-01 09:50", Open:156.49, High:156.58, Low:156.48, Close:156.54, Volume:1902583},
    {Date:"2020-04-01 09:55", Open:156.54, High:156.59, Low:156.50, Close:156.56, Volume:1325148},
    {Date:"2020-04-01 10:00", Open:156.56, High:156.60, Low:156.50, Close:156.53, Volume:2005588},
    {Date:"2020-04-01 10:05", Open:156.52, High:156.54, Low:156.42, Close:156.43, Volume:1277880},
    {Date:"2020-04-01 10:10", Open:156.44, High:156.46, Low:156.36, Close:156.37, Volume:1158301},
    {Date:"2020-04-01 10:15", Open:156.38, High:156.39, Low:156.26, Close:156.28, Volume:1987415},
    {Date:"2020-04-01 10:20", Open:156.26, High:156.33, Low:156.22, Close:156.32, Volume:1512742},
    {Date:"2020-04-01 10:25", Open:156.31, High:156.40, Low:156.31, Close:156.39, Volume:871592},
    {Date:"2020-04-01 10:30", Open:156.38, High:156.43, Low:156.35, Close:156.40, Volume:1132109},
    {Date:"2020-04-01 10:35", Open:156.40, High:156.44, Low:156.37, Close:156.41, Volume:725521},
    {Date:"2020-04-01 10:40", Open:156.41, High:156.50, Low:156.41, Close:156.48, Volume:704072},
    {Date:"2020-04-01 10:45", Open:156.48, High:156.50, Low:156.42, Close:156.46, Volume:844084},
    {Date:"2020-04-01 10:50", Open:156.47, High:156.47, Low:156.42, Close:156.45, Volume:392122},
    {Date:"2020-04-01 10:55", Open:156.45, High:156.47, Low:156.38, Close:156.41, Volume:544729},
    {Date:"2020-04-01 11:00", Open:156.43, High:156.47, Low:156.41, Close:156.44, Volume:660383},
    {Date:"2020-04-01 11:05", Open:156.43, High:156.47, Low:156.40, Close:156.41, Volume:640177},
    {Date:"2020-04-01 11:10", Open:156.41, High:156.44, Low:156.35, Close:156.39, Volume:845668},
    {Date:"2020-04-01 11:15", Open:156.38, High:156.41, Low:156.37, Close:156.39, Volume:503347},
    {Date:"2020-04-01 11:20", Open:156.39, High:156.43, Low:156.38, Close:156.41, Volume:360929},
    {Date:"2020-04-01 11:25", Open:156.40, High:156.42, Low:156.37, Close:156.38, Volume:749554},
    {Date:"2020-04-01 11:30", Open:156.39, High:156.44, Low:156.38, Close:156.42, Volume:723857},
    {Date:"2020-04-01 11:35", Open:156.40, High:156.45, Low:156.40, Close:156.44, Volume:455561},
    {Date:"2020-04-01 11:40", Open:156.43, High:156.48, Low:156.42, Close:156.45, Volume:670704},
    {Date:"2020-04-01 11:45", Open:156.44, High:156.54, Low:156.44, Close:156.50, Volume:827725},
    {Date:"2020-04-01 11:50", Open:156.51, High:156.55, Low:156.48, Close:156.53, Volume:828780},
    {Date:"2020-04-01 11:55", Open:156.53, High:156.55, Low:156.48, Close:156.49, Volume:687357},
    {Date:"2020-04-01 12:00", Open:156.48, High:156.52, Low:156.48, Close:156.51, Volume:343617},
    {Date:"2020-04-01 12:05", Open:156.50, High:156.58, Low:156.50, Close:156.57, Volume:444181},
    {Date:"2020-04-01 12:10", Open:156.57, High:156.61, Low:156.56, Close:156.57, Volume:932850},
    {Date:"2020-04-01 12:15", Open:156.58, High:156.63, Low:156.56, Close:156.61, Volume:622879},
    {Date:"2020-04-01 12:20", Open:156.61, High:156.64, Low:156.54, Close:156.56, Volume:417197},
    {Date:"2020-04-01 12:25", Open:156.57, High:156.60, Low:156.54, Close:156.56, Volume:524792},
    {Date:"2020-04-01 12:30", Open:156.57, High:156.63, Low:156.56, Close:156.63, Volume:547832},
    {Date:"2020-04-01 12:35", Open:156.63, High:156.69, Low:156.62, Close:156.65, Volume:1033940},
    {Date:"2020-04-01 12:40", Open:156.65, High:156.66, Low:156.59, Close:156.60, Volume:666020},
    {Date:"2020-04-01 12:45", Open:156.60, High:156.63, Low:156.52, Close:156.54, Volume:886571},
    {Date:"2020-04-01 12:50", Open:156.54, High:156.59, Low:156.53, Close:156.57, Volume:409824},
    {Date:"2020-04-01 12:55", Open:156.57, High:156.57, Low:156.52, Close:156.53, Volume:490971},
    {Date:"2020-04-01 13:00", Open:156.53, High:156.62, Low:156.53, Close:156.62, Volume:618202},
    {Date:"2020-04-01 13:05", Open:156.62, High:156.63, Low:156.56, Close:156.56, Volume:232977},
    {Date:"2020-04-01 13:10", Open:156.56, High:156.58, Low:156.52, Close:156.52, Volume:569834},
    {Date:"2020-04-01 13:15", Open:156.53, High:156.55, Low:156.50, Close:156.54, Volume:526717},
    {Date:"2020-04-01 13:20", Open:156.54, High:156.54, Low:156.48, Close:156.52, Volume:587983},
    {Date:"2020-04-01 13:25", Open:156.52, High:156.52, Low:156.46, Close:156.46, Volume:683988},
    {Date:"2020-04-01 13:30", Open:156.46, High:156.48, Low:156.44, Close:156.44, Volume:505235},
    {Date:"2020-04-01 13:35", Open:156.45, High:156.46, Low:156.41, Close:156.44, Volume:760274},
    {Date:"2020-04-01 13:40", Open:156.45, High:156.45, Low:156.41, Close:156.42, Volume:428196},
    {Date:"2020-04-01 13:45", Open:156.43, High:156.49, Low:156.42, Close:156.49, Volume:372145},
    {Date:"2020-04-01 13:50", Open:156.49, High:156.55, Low:156.42, Close:156.42, Volume:493463},
    {Date:"2020-04-01 13:55", Open:156.42, High:156.46, Low:156.37, Close:156.38, Volume:763911},
    {Date:"2020-04-01 14:00", Open:156.38, High:156.44, Low:156.38, Close:156.43, Volume:478714},
    {Date:"2020-04-01 14:05", Open:156.43, High:156.48, Low:156.40, Close:156.47, Volume:347221},
    {Date:"2020-04-01 14:10", Open:156.46, High:156.48, Low:156.44, Close:156.45, Volume:527388},
    {Date:"2020-04-01 14:15", Open:156.46, High:156.47, Low:156.39, Close:156.46, Volume:1254489},
    {Date:"2020-04-01 14:20", Open:156.47, High:156.52, Low:156.43, Close:156.50, Volume:588877},
    {Date:"2020-04-01 14:25", Open:156.49, High:156.50, Low:156.45, Close:156.46, Volume:391738},
    {Date:"2020-04-01 14:30", Open:156.46, High:156.50, Low:156.43, Close:156.46, Volume:835468},
    {Date:"2020-04-01 14:35", Open:156.46, High:156.51, Low:156.45, Close:156.48, Volume:465308},
    {Date:"2020-04-01 14:40", Open:156.48, High:156.50, Low:156.47, Close:156.49, Volume:389872},
    {Date:"2020-04-01 14:45", Open:156.48, High:156.53, Low:156.48, Close:156.50, Volume:530820},
    {Date:"2020-04-01 14:50", Open:156.50, High:156.53, Low:156.48, Close:156.53, Volume:554269},
    {Date:"2020-04-01 14:55", Open:156.53, High:156.57, Low:156.52, Close:156.56, Volume:622473},
    {Date:"2020-04-01 15:00", Open:156.57, High:156.59, Low:156.53, Close:156.59, Volume:593592},
    {Date:"2020-04-01 15:05", Open:156.59, High:156.61, Low:156.56, Close:156.58, Volume:1089712},
    {Date:"2020-04-01 15:10", Open:156.59, High:156.59, Low:156.55, Close:156.57, Volume:634702},
    {Date:"2020-04-01 15:15", Open:156.57, High:156.64, Low:156.57, Close:156.60, Volume:1206417},
    {Date:"2020-04-01 15:20", Open:156.60, High:156.61, Low:156.58, Close:156.60, Volume:641636},
    {Date:"2020-04-01 15:25", Open:156.59, High:156.60, Low:156.54, Close:156.55, Volume:873698},
    {Date:"2020-04-01 15:30", Open:156.55, High:156.64, Low:156.55, Close:156.59, Volume:1318720},
    {Date:"2020-04-01 15:35", Open:156.60, High:156.68, Low:156.59, Close:156.68, Volume:1520610},
    {Date:"2020-04-01 15:40", Open:156.68, High:156.74, Low:156.67, Close:156.74, Volume:1678678},
    {Date:"2020-04-01 15:45", Open:156.74, High:156.80, Low:156.73, Close:156.76, Volume:2854531},
    {Date:"2020-04-01 15:50", Open:156.75, High:156.79, Low:156.71, Close:156.72, Volume:2984534},
    {Date:"2020-04-01 15:55", Open:156.71, High:156.75, Low:156.63, Close:156.73, Volume:7105595},
    {Date:"2020-04-01 16:00", Open:156.73, High:156.78, Low:156.71, Close:156.77, Volume:3863507}
];
</script>

<script>
// 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
    }
];

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

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

const order = {
    type: "Order",
    events: orderEvents,
    spanType: "durationEvent"
}
</script>

</body>
</html>

Run it!

Load helloworld.html again 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

The pop-up displays could be a little better defined. Let's makes some changes to the CSS.

Add a style element to helloworld.html.

Place the element after the link tags that reference the chartiq.css and tradeAnalyticsSample.css style sheets, thereby succeeding them in the CSS cascade. For example:

<link rel="stylesheet" type="text/css" href="css/chartiq.css" media="screen" />

<link rel="stylesheet" type="text/css" href="examples/markers/tradeAnalyticsSample.css" media="screen" />

<style>
</style>

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).

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 the style element in helloworld.html.

Note: You should never change any of the CSS files in your library. You don't need to — 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).

Copy the h4 heading rule-set to the styles element:

.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 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 the style element:

.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 helloworld.html). 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's the finished style element:

<!-- Customize the sub-event markers and pop-up displays. -->
<style>
/* 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;
}
</style>

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 your charting applications.

Next, we'll create an example of time span events controlled through the user interface.

Next Steps: