Implementing UI

All About Menus and Dialogs

Note: ChartIQ provides Angular 1, Angular 2, React, iOS, and Android starter kits and sample applications through the following public Github repos. This tutorial can be used along with the sample code to get your project started:

React

Angular 1.5

Angular 2

iOS -Basic

iOS

Android

Note: We do not recommend using the web components from template-advanced.html within Angular, React, iOS, or Android. Unless you have very advanced skills, you are better off using the seed projects and/or building Angular, React, Swift/ObjectiveC, or Java components that interface with the charting library.

Overview

ChartIQ's SDK comes with a drop-in sample UI template called "template-advanced.html". This example is an excellent starting point for developers looking to get up and running quickly. This application can be used right out of the box. "template-advanced.html" is composed from W3C Standard WebComponents, so you can cherry-pick the parts you want to use for your project.

However, there are cases when you might not want to use a built-in template:

  • Your application requires a completely different look and feel
  • You're integrating the charts into an existing application with its own UI (menus, dialogs, etc)
  • You prefer a deep integration with UI frameworks such as Angular or React.

Integrating the charting library into your own, custom built UI is straightforward. To wire up your UI, it is necessary to understand just a few paradigms. This tutorial describes these UI concepts and provides concrete code examples.

Please note: In order to keep the examples simple, this tutorial will generally assume that the developer is using the "pull" method for data. See the Data Integration tutorial to learn how to set up your data with the "pull" method.

Please note: To keep examples simple, this tutorials uses jquery syntax

Types Of Controls

When developing a custom UI, developers will need to create a variety of controls:

Symbol Entry

Providing users with the ability to change the stock symbol is a fundamental requirement for most stock charting applications. Developers usually choose from three typical approaches:

  • Input box - Users enter stock symbols and then hit enter to force the chart to reload the stock. Users are expected to know the "symbology" for the application.

Screenshot of input box

  • Lookup - Typically provided as an "autocomplete" or "type ahead". As users enter characters, a search by symbol or description is initiated. Results are displayed in a clickable list.

Screenshot of lookup dropdown

  • Browse - When working with a limited set of symbols (such as FX trading), a browsable list is a reasonable alternative. Such lists are often provided in a side panel on the left side of the screen. "Watchlists" are another example of browsable lists.

Screenshot of browsable list

Regardless of the UI choice, the user's selected symbol must be sent to the chart. The chart will use the symbol to request data and render itself.

Menus (that change the state of the chart)

A menu allows the user to adjust the state of the chart. The ChartIQ templates include several built in functions for displaying, populating, and closing menus. However, if more customization is needed, it's easy to render your own menus. There are several approaches to making a given menu reflect the state of the chart. The most common approaches include binding directly to the chart objects, using an intermediary data store, and intercepting UI activity to manually update any changes.

Binding directly to the chart objects is the safest and most straightforward of these options. Binding to the chart objects is typically very easy and intuitive within a framework like Angular but it can also be implemented in vanilla JavaScript if you wish.

Whatever your preferred method is, the developer must make sure that all the data stays in sync with the chart objects to reflect the true state of the chart.

Screenshot of menu

Toggles

A toggle is a control through which a user can easily switch from one state to the next and back again. Toggles are usually represented by a button. A common use of a toggle in a charting UI is to turn crosshairs on or off.

Screenshot of crosshairs toggle

Dialogs (for user input that affects the chart)

Dialogs give the user an opportunity to provide input. Custom themes and study parameters are common uses of dialogs.

Structurally speaking, dialogs often reside outside of the chart DOM, becoming visible when triggered by the chart. The most common ways to trigger a dialog to show and hide is through events.

The ChartIQ SDK has several built-in helpers to assist with populating dialogs.

Screenshot of dialog

Floating Controls (UI that is superimposed on the chart)

Floating controls are used when it is desirable to put user interface on the chart itself. An example of a floating control is the comparison legend in template-advanced.html. Implementing floating controls brings the UI into the chart and creates a more immersive experience for the end user.

Screenshot of markers Screenshot of comparison legend

Drawings

Drawing tools are used to help the end user perform more accurate technical analysis, complement a technical indicator, or to highlight a point of interest on the chart. The ChartIQ SDK makes it very easy to implement a drawing toolbar that includes many built in tools.

Implementing UI - Detailed Discussion and Examples

Symbol Entry

Symbol Input

Changing the symbol on a chart is straightforward:

stxx.newChart("MSFT");  // Do this to set or change the symbol in your existing chart

Note: This example assumes use of a quotefeed.

Calling newChart without parameters will load a blank chart:

stxx.newChart();

When more than one field is required to support your symbology, use a symbolObject.

stxx.newChart({symbol:"MSFT", id: 5632311}); // For instance, a data feed that requires an id

symbolObject must contain a "symbol" property but can include any other fields that may be necessary for your data servers. You can also use the symbolObject for storing useful information such as the name of the company (description) for later reference or display.

Please note that newChart is asynchronous and takes an optional callback parameter. The callback will be triggered when the chart data has been fetched and rendered. This can be useful for a number of things such as setting the range or updating other data with the change. To learn more about the newChart function, see CIQ.ChartEngine#newChart.

Autocomplete is a useful feature to implement with symbol input. Frequently users won't know the exact symbol. An autocomplete can dynamically search symbol names and descriptions on a server based on partial input from the user. The drop-in UI in template-advanced.html includes an autocomplete that is built using WebComponens. You can of course build your own using plugins for your framework!

Adding Comparison Symbols

Adding a comparison to a chart means adding an additional set of data onto the same chart. From a developer's perspective we call this adding a "series". Use the addSeries function to add additional data points.

Example: Add "AAPL" as a comparison symbol to the current chart and make the line blue.

stxx.addSeries("AAPL",{isComparison:true, color:"#0000ff");

See CIQ.ChartEngine#addSeries for a complete list of parameters and a variety of examples.

To remove a series, use the removeSeries function:

stxx.removeSeries("AAPL");

Menus

As mentioned earlier, there are several approaches to making a menu reflect the state of a chart:

  • Binding directly to the chart objects (bind to stxx.__)
  • Using an intermediary data store (for instance React state)
  • Intercepting UI activity to manually update

There are some pitfalls with using the latter two approaches. Additional layers between user interaction and state change puts the burden of managing data synchronization completely on the developer.

It is of course not necessary for the menu to reflect the state of the chart but does improve the user experience.

Periodicity Menu

To learn more about periodicity see Periodicity.

Utilize the setPeriodicity function to change the periodicity of a chart.

Terminology:

  • period is a multiplier that is applied to interval. If your interval is 1 (representing 1 minute bars from your data server) then setting period to 5 will cause the chart to display 5 minute bars (by rolling up the bars). For most use cases period will be 1.
  • interval is the length represented by each data point that is returned from your data server. For instance, setting interval to 1 will cause a quotefeed to request "1 minute" bars from your data server. Interval can be set to any integer (to represent minutes, seconds or millseconds) or "day", "week", or "month". Set interval to "tick" for "tick charts".
  • timeUnit further qualify numeric intervals set timeUnit to "millisecond", "second", "minute".

Note: Periodicity should not be confused with "range". Periodicity describes how much time is represented by a data point (bar). Range describes the range of dates to display on a chart. See CIQ.ChartEngine#setRange and CIQ.ChartEngine#setSpan.

Depending on your data and use cases, you may set periodicity in a variety of different ways:

stxx.setPeriodicity({period:5, interval:1});    // Request 1 minute bars. Roll them up to 5 minute bars.
stxx.setPeriodicity({period:1, interval:5});    // Request 5 minute bars.
stxx.setPeriodicity({period:1, interval:5, timeUnit:"second"});   // Request 5 second bars.
stxx.setPeriodicity({period:1, interval:"day"});   // Request daily bars.
stxx.setPeriodicity({period:1, interval:"week"});   // Request daily bars. Roll them to weekly bars.

See CIQ.ChartEngine#setPeriodicity.

Chart Type Menu

The charting library supports several chart types, including candlestick, line, mountain and bar. See CIQ.ChartEngine#setChartType for a complete list.

Generally, the chart type can be changed with a single line of code:

stxx.setChartType("line");

When displaying "aggregated" chart types such as Heikin Ashi or Kagi charts, an addtional line of code is required:

stxx.setChartType("candle");
stxx.setAggregationType("kagi");

See CIQ.ChartEngine#setAggregationType for a complete list of aggregated chart types.

Themes Menu

There are two types of themes: "predefined" and "custom".

  • Predefined theme - is configured by a developer. Users select predefined themes from a menu. A theme is really nothing more than a set of CSS styles that are set dynamically.
  • Custom theme - is configured by the end user. The user will pick colors for each of the components of a chart. For more information about custom themes, see the Custom Themes section.

The ChartIQ template comes with two predefined themes: Light and Dark. Themes are represented as CSS classes. The built in themes can be found in the "sass" directory.

To programatically set the theme to one of the built in themes, simply add the appropriate corresponding class to your HTML. For example, if I wanted to use the Dark theme:

...
<body class="Dark">
...
<script>
  // Switch from Dark to Light theme
  $("body").removeClass("Dark"); $("body").addClass("Light");
  stxx.clearStyles(); // This forces the chart to load the new CSS
</script>

In this case we set the class on the body, but it could be on a parent div:

<body>
    <div class="Dark">
        <div class="chartContainer">...your chart here...</div>
    </div>
</body>

There are two aspects to a theme: the chart and the UI. You should think about whether switching themes would change the styling of menus, dialogs, etc. In the provided template-advanced.html example, we do change much of the UI when swapping themes, but in your use case it may make sense just to affect the chart.

If you add Sass entries, run Sass to generate a CSS file and include that CSS file in your HTML. To generate your CSS, first make sure you have Sass installed on your machine, then run sass chartiq.scss output.css in the terminal, replacing 'output' with your desired file name. If you want to write your own custom theme, use _ciq-night.scss as a template.

Study menu

The list of supported study types and their full names can be found by calling CIQ.Studies.getStudyList(). To create a menu of studies simply bind to the resulting object and display them in your HTML.

Each study in the list is represented by an object called a "study descriptor". This object defines the input parameters for the study as well as the output color or colors. We will use this later to populate a study dialog. Here is an example of what the RSI study descriptor looks like in the studyLibrary object:

rsi:{
    calculateFN: function(stx,sd),
    inputs: {Object},
    name: "RSI",
    outputs: {Object},
    parameters: {Object},
    range: "0 to 100"
}

The most important part of this object for the study menu is the name. Use the name to populate your study menu.

To add a study to the chart, utilize the addStudy function:

CIQ.Studies.addStudy(stxx, "rsi"); // stxx is your existing chart object. "rsi" is he studyLibrary entry (not the name).

See CIQ.Studies.addStudy.

To learn how to support editing studies, go to the Editing a Study section.

Toggles

Crosshairs

A crosshairs tool can allow the user to perform technical analysis more accurately by visually extending the location of the cursor. Some users find crosshairs distracting, so it's a nice feature to be able to toggle the crosshairs on and off. The state of the crosshairs is a boolean value and is stored in an object called ciq.layout.crosshair.

Toggling is easy!

ciq.layout.crosshair=!ciq.layout.crosshair;
Drawing Toolbar

A drawing toolbar may not always need to be present in the UI. To help maximize the chart area, a good option can be to make the drawing toolbar a toggle. It's easy to show and hide the toolbar using any framework standard or just plain Javascript or CSS.

Dialogs

Study Settings Dialog

Users sometimes want to customize the input parameters and output colors of a study. The CIQ.Studies.DialogHelper object can be used to power a custom built study dialog. The DialogHelper takes the name of a study and a chart instance as parameters. It returns a list of controls and settings to display in a dialog. To create a study dialog helper, use the new operator:

// stxx is your existing chart instance
var helper=new CIQ.Studies.DialogHelper({name:"ATR",stx:stxx});

The DialogHelper returns an object that can be used to create your dialog. Here is an example of what the object looks like:

{
    attributes:{Object},
    inputs:[Array],
    libraryEntry:{Object},
    name:"ATR",
    outputs:[Array],
    parameters[Array],
    sd:{Object},
    stx:CIQ.ChartEngine,
    title:"ATR"
}

The most important parts of this object for your dialog are inputs, outputs, and parameters. Each "input" will describe a form field that should be generated. Each "output" will describe a color swatch that should be generated. Each "parameter" will describe a form field and a color swatch that should be generated. It is up to the developer to implement color picker. See this sidebar about color pickers.

To update a study with new values selected by the user in the dialog, utilize updateStudy:

helper.updateStudy({inputs:newInputValues,outputs:newOutputValues,parameters:newParameters});

To learn more about the DialogHelper, see CIQ.Studies#DialogHelper

Time Zone Picker

Users generally display intraday charts in the timezone that is set in their browser (default behavior). Sometimes a user wishes to explicitly set the timezone. If you wish to allow this, then you will need to implement a timezone picker dialog.

All of the time zones included with the library can be found in the object CIQ.timeZoneMap. To list all of these time zones in a menu, simply bind to the object and list them in your HTML. To change the time zone, use the setTimeZone function and pass the selected timezone as the second parameters.

To reflect the change immediately on the chart, call ciq.draw(); to redraw the chart.

Example:

// stxx is your existing chart object
function changeTimeZone(zone){
    stxx.setTimeZone(stxx.dataZone, zone); // maintain the existing dataZone
    stxx.draw();
}

To learn more about the setTimeZone function, see CIQ.ChartEngine#setTimeZone.

Custom Theme Creator

Sometimes users wish to change the colors on the chart. We call this creating a custom theme. CIQ.ThemeHelper makes it easy to implement custom themes. It returns an object that can be used to power a dialog which allows a user to set their color preferences. The initial values in the returned object contain the existing values in the current chart. Generally theme dialogs are implemented as swatches that can be changed with a color picker. In order to update the theme simply edit themeHelper.settings and call update();.

Here is an example of how to change the color of "up" candles (usually green):

var helper=new CIQ.ThemeHelper({"stx":stxx});  // stxx is your existing chart instance
console.log(helper.settings);   // Shows the current chart theme settings
helper.settings.chartTypes["Candle/Bar"].up.color="rgba(126,97,170,1)";
helper.update();  // The chart will now reflect the change in the settings

In order to let your user define this change, color pickers should be provided in the dialog for each setting. It is up to the developer to create this color picker but to learn about the expected structure and behavior, see this sidebar about color pickers.

To add custom themes to a menu for later selection, push a clone of the settings object that represents that theme into the menu object along with the name of the theme. When the user selects that theme, use the corresponding settings object.

Example:

var themes=[{name:"firstCustomTheme",settings:{chart:{Object},chartTypes{Object}}}];
function createNewTheme(themeName, themeSettings){
    var newTheme={name: themeName, settings: themeSettings};
    themes.push(newTheme);
}

createNewTheme("Roger's theme", new CIQ.ThemeHelper({stx:stxx}));

To learn more about the ThemeHelper, take a look at the CIQ#ThemeHelper.

Color Pickers

Many good open source color pickers exist but if you're not finding exactly what you want, you can always make one yourself.

There are two parts to a functional color picker: the "swatch" and the color picker itself. For instance, a theme dialog might have many swatches, but they would typically all share a single color picker. When a user clicks on a swatch, the color picker should be moved to the location of the click and then displayed. When the user picks a color, the color picker should close and the swatch updated to reflect the new color. Don't forget to update the study or theme helper with any changes!

Color pickers may seem like dialogs but there are notable differences with their behavior. A menu dialog can almost always display in the same position on the screen because they are intended to require the user's full attention until the task is complete. A color picker is only intended to help define a small detail of the task. The color picker's location is in comparison to the swatch that is being edited. Without proper positioning, the user will be mislead as to what they are editing.

Right Click Context Menu (Overlay Studies)

The chart accepts right click and "tap" events on studies that overlay the chart (overlays). The default behavior for right-click is to delete the study however you can optionally implement a context menu. Such a context menu would typically give the user the ability to either edit or delete the study.

Example, chart with a context menu that allows a user to edit or delete an overlay:

Study Overlay Context Menu

To implement a context-menu you will need to respond to the studyOverlayEdit callback. This callback will pass a "study handle" object that you should then retain. Your context menu will need access to this object in order to delete or edit the study.

To edit the study, create a CIQ.Studies.DialogHelper object with the study handle object:

stxx.callbacks.studyOverlayEdit=function(handle){
      // present context menu
      if(userPressedEdit){
      var helper=new CIQ.Studies.DialogHelper(handle);
      // create a study dialog using the helper, see above
    }
}

If the user chooses to delete the overlay, then you can remove it with a single function call:

stxx.callbacks.studyOverlayEdit=function(handle){
      ...
      if(userPressedEdit){
      var helper=new CIQ.Studies.DialogHelper(handle);
      ...
    }
    // If user presses delete then just remove the study by passing in the study descriptor
    if(userPressedDelete){
      CIQ.Studies.removeStudy(handle.stx, handle.sd);
    }
}
Right Click Context Menu (Series)

By default a series will be highlighted on 'mouse-over' and a context menu displayed to allow you to delete it. If you create a custom legend, you may want the chart to highlight the series when user hovers on item in the legend.

To do this, your code will need to loop trough all series renderers, find the series you are looking for, and set highlight and anyHighlighted properties to true.

Here is the sample code:

var chat = stxx.chart;
for(n in chart.seriesRenderers){
    var r2=chart.seriesRenderers[n];
    if(!r2.params.highlightable) continue; //might not be necessary to check this here
    for(var m2=0;m2<r2.seriesParams.length;m2++){
      var series=r2.seriesParams[m2];
      if(series.symbol == 'yourSymbol') {
         series.highlight=true;
         stxx.anyHighlighted=true;
      }
    }
}
stxx.draw();

Then, reverse to false when you want the highlights to disapear.

Floating Controls

Comparison legend

It is useful for the user to have a legend to help differentiate their comparisons. All the data from the comparisons that are added to the chart are stored in the object stxx.chart.series. Here is an example of this object for the symbol MSFT:

MSFT{
    display:"MSFT",
    parameters:{
        chartName:"chart",
        color:"#000000",
        data:{
            useDefaultQuoteFeed:true
        },
        isComparison:true,
        panel:"chart",
        shareYAxis:true
    }
}

The parts of this object that are meaningful to a comparison legend are display and parameters.color. Bind to these two things in your HTML for your symbol and color and style them appropriately.

Markers

The charting library provides developers with the ability to place DOM objects on the chart using a mechanism called "markers". Markers can be placed at a fixed position on the chart or at a specific candle or price location. We use markers to implement floating controls. To learn more about implementing markers, see the Marker Tutorial.

Drawings

Getting and setting the tools

To get a list of the built in tools, simply call CIQ.Drawing.getDrawingToolList({});. This returns an object containing names and types for each built in tool. If you don't want to offer all the built in tools, just pass in a list of the tools you want to exclude (i.e. CIQ.Drawing.getDrawingToolList({"vertical":true,"annotation":true});). Plug this list into a drop down menu in your drawing toolbar and you're set!

The next step is to enable the tool when the user selects it from the menu of options you have provided. To enable a drawing tool, pass the name of the selected tool into your function as a string and call stxx.changeVectorType(tool);. To disable any drawing tool, pass an empty string into the function (i.e. stxx.changeVectorType("");).

Getting and setting tool parameters

Each tool will be activated with it's own default parameters when you call changeVectorType(tool);, but if you want to allow your end user to change the colors or line patterns of any of the tools you can easily do that too! To get the parameters for any built in tool, call CIQ.Drawing.getDrawingParameters(stxx, tool);: stxx being your chart instance and tool being the string representation of the name of the tool. This will return an object representation of the parameters for that tool and their default values. For example, here is the object representing the parameters for the rectangle tool:


{
    color: "auto",
    fillColor: "#7DA65F",
    lineWidth: 1,
    pattern: "solid"
}

In the above example, the keys are the names of the parameters that the user has the option to edit for that drawing tool and the corresponding values are the defaults.

Setting a parameter of a tool with a new value is straight forward. Just pass the name of the parameter you wish to change and the new value you want to change it to into the function stxx.changeVectorParameter(parameter, newParameterValue);. For example, this is how we would update the pattern parameter of the rectangle tool to a dotted line pattern:

stxx.changeVectorParameter("pattern", "dotted");

Notes

This tutorial covered implementing UI for a browser based project. Designing a UI for mobile web or mobile native requires a slightly different UX approach but the same mechanisms from this tutorial can be used for those interfaces. In mobile, we would recommend utilizing slide out menus and well thought out toolbars. We recommend the Framework7 and Ionic toolkits for building mobile web UI.


Next Steps: