Skip to content

Showing a chart on a page

In order to show a chart on a page, you need to

Instantiate a data feed

For details on the concept of a feed please see the dedicated page here

There should only be one instance of the feed per page, the reason being that we need a common place for data shared between the charts (for example, timeseries cache).

Here’s how you’d typically instantiate and initialize a feed:

import { initFeed, BarchartSiteDataFeed } from "@barchart/chart-lib";
// initFeed(feedConstructor, config = {})
const feed = initFeed(BarchartSiteDataFeed);
const isReady = await feed.ready();
if (isReady) {
// you can start adding charts now
}

If you call the initFeed more than once, you will get a runtime exception. You may but are not required to store the feed instance. You can get the feed instance at any point by calling getFeed().

The config you may optionally provide will be merged in with the default one, so feel free to provide only override values. By default, config is

{
validateInput: false,
isAlt64: true,
defaultTemplate: "/chart.def.json",
cachedAnnotationsCount: 0,
throttleMillis: 0,
showResizeHandles: false, // DEPRECATED
scrollBehavior: "wheel+shift",
tooltipMovement: "Auto",
tooltipHeaders: undefined, // please see below for details
touchCrosshairTimeoutMillis: undefined, // please see below for details
bypassSmoothing: false,
showGoToLatest: undefined,
mode: "Unspecified",
hostingModel: "Page",
overrides: undefined, // please see below for details
baseUrl: {
"futures": "/proxies/futures",
"timeseries": "/proxies/timeseries",
"ondemand": "/proxies/ondemand",
"coreapi": "/proxies/coreapi"
},
async fetch: function(kind, relativeUrl) {
// fetches the data, you may override this method
}
}

validateInput is currently false but it’s strongly recommended to turn this on (set to true) because it ensures that chart definitions do not get corrupted due to incorrect API use. We will turns this on by default fairly soon.

isAlt64 relates to the way fractional prices are displayed - whether we display normal 64ths (this value is false) or 32nds and halves (this value is true, AKA we show “alternate” 64ths). It’s N/A if you’re using your own data feed implementation.

defaultTemplate is the URL of the template (chart definition) the chart will load upon initialization, when no customization has been applied. You may override it if you find yourself needing more than one default (say, when you want to load different default chart for mobile and desktop site), by default it is /chart.def.json (note it’s relative to the site). You may provide absolute URLs, but it’s up to you to ensure CORS is taken care of.

cachedAnnotationsCount should be used if you’d like the chart to cache annotations for main Symbol plots. If you set this to a number N higher than 0, the annotation handling changes from simply preserving annotations across symbol changes to caching last used annotations, per symbol, limited to N entries (N symbols effectively). Attention: this will grow the size of each definition stored, so don’t set this to a very high number. Also, due to the way this is handled, there’s no symbol mapping of any kind performed, so you should not give the chart symbols that need resolution like ES*1 otherwise we’ll store annotations for essentially different symbols as time passes.

throttleMillis can be used to slow down streaming data updates, it’s a number of milliseconds we should buffer all updates coming in. If your data stream has a very high throughput, for performance reasons (lots of updates result in lots of redraw) it is recommended to add at least 25-50 ms of throttling.

DEPRECATED showResizeHandles is not meaningful in the v2 of the product

scrollBehavior dictates the way we perform zooming; wheel+shift is default and requires users to hold shift button while zooming - this is meant for all hosts which have the chart inside a web page which itself can be scrolled using the mouse wheel; other two options wheel and none are simple - the former is meant for “apps” which use a fixed page layout and don’t need browser to scroll the page and the latter disables scrolling altogether.

tooltipMovement applies to tooltip mode standard (global tooltip for all plots) only. By default (Auto), it will move the tooltip “out of the way” of the crosshair/mouse pointer. It can also be set to Draggable which allows the user to click and drag the tooltip to any (fixed) position on the chart.

tooltipHeaders only applies to the tooltip mode cards. It’s an object which can have two properties: showMainPlot (boolean) which will include the main plot in this tooltip mode (is excluded by default for historical reasons) and includeTimestamp (boolean) which adds the current timestamp in this tooltip mode (also excluded by default).

touchCrosshairDelayMillis only applies when the device is touch-only (a mobile phone or a tablet). It represents a number of milliseconds the chart will wait until it switches from the panning mode to the price tracking mode (which shows the tooltip).

touchCrosshairTimeoutMillis only applies when the device is touch-only (a mobile phone or a tablet). It represents a number of milliseconds the chart will wait - after being put (through long press) in the price tracking mode - until it reverts to the panning mode.

bypassSmoothing defines the drawing behavior of all vertical and horizontal lines, best seen on OHLC charts with lots of such lines. Since the chart uses HTML5 Canvas for the drawing, all the lines drawn are anti-aliased, making them look a bit “fuzzy” (less visible on high resolution screens). Turning this option on (setting it to true) will ensure that all plots are drawn as crisp as possible.

showGoToLatest is a global on/off setting for the button which lets the user quickly scroll back to the latest bar. It should only be set if you always want this behavior on or off. If you omit it, then the setting inside the chart (by default it is false) definition dictates what happens. The API supports toggling the setting in the definition, but please remember: if you set the value here (in the config) it will override the value found in the chart definition.

mode is a pre-defined named set of presets used only in cases where it’s known in advance which settings correspond to a given “mode”. It’s only used internally by Barchart.

hostingModel helps with the interaction between the chart and the HTML surrounding it. If on a touch-only device, it becomes important to distinguish two primary use cases: web page (Page) and and an app (Application). The difference is that the app uses full screen of the browser and does not allow scrolling while the page hosts a chart in an area surrounded with other text, tables and data. In the latter case (page), it’s very much expected that panning - especially vertical panning - be allowed regardless if the user is touching the chart or the surrounding surface. In the former case (app) all touch events will be handled by the chart and the browser will be prevented from seeing them, which helps with some unwanted scrolling, zooming and such.

overrides is a set of options which allow external code to modify some aspects of the chart rendering; it’s completely optional - you may configure no properties, some of them or all of them. It’s an object with the following shape:

{
yAxis: {
tickProvider: function(options) { /*...*/ }
},
xAxis: {
getLocaleName: function() { /*...*/ }
}
}

The property yAxis contains overrides related to the y (or vertical/price axis). You may supply:

  • tickProvider method, returns array of numbers representing the ticks; receives object with the properties:
    • height, pane height, in pixels (number)
    • approxLineHeight, approximative line height, in pixels (number)
    • domain, the data domain, array of two numbers, [min, max] (adjusted for necessary padding)
    • autoTicks, the ticks that chart has automatically computed, array of numbers

The property xAxis contains overrides related to the x (or horizontal/time axis). You may supply:

  • getLocaleName method, returns the name of the locale used to format dates; at the moment, only two values are supported: fr for French and undefined (or null) for the default locale which is en-US

baseUrl is a list of mappings between the data servers Barchart uses and their base URLs. Under normal circumstances, you don’t need to set this - chart will try to use well-known relative proxy URLs (as shown above). However, relative URLs are only usable when the server hosting the charts is under our control and implements the respective proxies correctly (maps to correct absolute URLs and handles any authentication, CORS and whatnot).

If the server is not under our control (it’s a 3rd party server) and the data feed is not custom, then you need to set these URLs to the absolute URLs, for example timeseries URL might be http://ds01.ddfplus.com/historical. Also note that (by design) we don’t handle authentication in any way in the chart. When relative URLs are used the host can take care of this but if you set absolute URLs it’s up to you to handle this whichever way is appropriate.

If you find yourself in neither of the situations (yet still not using a custom feed) or simply would like more control over data fetching, replace the fetch function with your own (the this will be set to the config object for convenience). The function should return a Promise which returns a string which is a text value of the resource being fetched. You will do this in cases where the data fetching is involved either because of authentication, CORS or some other factors. By default, this function simply concatenates the this.baseUrl[kind] and relativeUrl and then uses fetch to get the text behind that URL.

Before you begin creating charts, you need to make sure that the feed has been initialized properly. It’s an implementation detail but the feed will actually asynchronously load the default template file while initializing, hence the need to wait for the feed to be ready (the default template is needed for cases where you’d call addChart and provide just a symbol name without specifying the template/definition to use).

If you’re hosting the chart yourself, please don’t forget to ensure that the default template is available from the URL you’ve set in the config above.

Everywhere in the chart’s API we use Promises as defined in EcmaScript 2015 for all async work. Additionally, as a convention, all of the objects that do something asynchronous expose ready method (in spirit quite like jQuery’s method with the same name) which returns a Promise (hence the use of then method); if you are using EcmaScript 2017 or later you may even use async and await, for example the above (without error handling) would be

const isReady = await feed.ready();

Instantiate a chart

There are two ways to use the chart - the expected (you could say obvious) way is to have it shown on a page (after all, chart is by design graphical/visual) but you could also have it headless, running with no UI.

The headless mode is simpler; you create a chart, get an instance back, run actions against it, then you can get back the state of the chart as a regular definition (or a template). It’s not as obvious why this would be useful because all of the modifications would not be visually shown, but it’s a perfectly valid way to use a chart.

Getting a headless chart is simple, you just call

feed.getHeadlessChart();

and that’s it. Please make sure you save the instance somewhere because it does not get an id like a visible chart does (see below).

Getting a regular chart with UI is just slightly more involved because you need to place a chart somewhere. Tell it where to go on a page (must be an id of an element, typically a div) and optionally give it a config object

// continuation of code above
var myChart = feed.addChart("domElementId", config)); // config is optional

Initializing the chart does nothing fancy except some interop with the page it’s hosted in.

The optional config is just a convenience. It allows to immediately execute one of the main APIs which is to set the main symbol or expression of the chart. It also allows you to override the template the symbol/expression will be applied to. It’s very simple:

{
"symbol": "aSymbolName",
"expression": "anExpression",
"template": "aTemplate"
}

You may omit this, by default it’s null and won’t set anything at initialization. If you do provide the object, note that fields symbol and expression are mutually exclusive, please only provide one of them.

You may also provide a template in which case the chart will use your provided template and not the default template. This is not an URL, it’s a JavaScript object serialized to JSON.

For convenience, the domElementId is stored in the chart instance as a property elementId.

If you did not provide the config, nothing will be shown. It’s assumed you’ll call myChart.load("aDefinition") immediately in order to populate the chart. Or that you’ll call myChart.load("aTemplate") followed by an API call to fully populate the chart. If you’re still unclear on the difference between a template and a definition, it’s described here.

You may store the chart you get back from the addChart or just store its id (you provided it during the call), then at any point call feed.get("domElementId") to get the instance of the chart.

Dispose of a chart

There are quite a few resources used when the chart is instantiated. Apart from several JavaScript objects created by us, there are sometimes data subscriptions made (in case of streaming updates) and finally there’s the DOM of the visual portion of the chart.

If you are hosting the chart in a simple scenario where upon page load the chart(s) never disappear (hiding through CSS does not count) - even if user might change the chart in non-trivial ways like change main symbol, add/remove studies etc. - you will never need to dispose of anything, unless you want to create a new instance of a chart and put it into the same DOM element.

If however you have an advanced scenario where multiple charts are open per page and the new ones get added/removed quite often (this usually means you have implemented a “window management” of sorts, like a virtual desktop), you must ensure that respective resources are cleaned up by calling

// remember, you can always get the feed instance by calling 'getFeed()' (see above)
// the domElementId is stored as 'elementId' property of the chart
feed.removeChart("domElementId");

This call cleans up everything, including the DOM. If there’s any caching involved, that’ll be taken care of too.

Fetch taxonomies

There are several taxonomies (AKA list of possible values) that chart uses internally that might be exposed in the UI in some way. If you need these, you can call the function getTaxonomies (note that it lives in the same “namespace” like the rest of the chart, see above). The method returns the following:

  • studies which contains a list of studies, the properties are described in the study taxonomy
  • (Barchart specific) incomeStatements is alphabetically sorted list of Income Statement objects { id: "id", name: "name" }
  • (Barchart specific) balanceSheets is alphabetically sorted list of Balance Sheet objects { id: "id", name: "name" }
  • studyFields is (not sorted) list of Fields used in the studies; you can use it for mapping between field id and field name (the former is used everywhere internally, the latter to show to the user in the UI)
  • curveStyles is (not sorted) list of styles you can apply to curves, not all are applicable to all plots, please see discussion in the chart definition for details
  • annotations is a list of objects of the form { id: "annnotationId", traits: { /*...*/ } where id is the id of the annotation and the traits are possible (visual) traits you can set on that annotation; for details please see the annotations’ docs.