FinancialChart 101

Getting Started

Steps for getting started with the FinancialChart in AngularJS applications:

  1. Add references to AngularJS, Wijmo, and Wijmo's AngularJS directives.
  2. Include the Wijmo 5 directives in the app module:
    var app = angular.module('app', ['wj']);
  3. Add a controller to provide data and logic.
  4. Add a FinancialChart to the page and bind it to the data.
  5. Add some CSS to customize the chart's appearance.
<html> <head> <link rel="stylesheet" type="text/css" href="css/bootstrap.css"/> <link rel="stylesheet" type="text/css" href="css/wijmo.css" /> <link href="css/app.css" rel="stylesheet" type="text/css" /> <script src="scripts/angular.js" type="text/javascript"></script> <script src="scripts/wijmo.js" type="text/javascript"></script> <script src="scripts/wijmo.chart.js" type="text/javascript"></script> <script src="scripts/wijmo.chart.interaction.js" type="text/javascript"> </script> <script src="scripts/wijmo.chart.analytics.js" type="text/javascript"></script> <script src="scripts/wijmo.chart.annotation.js" type="text/javascript"></script> <script src="scripts/wijmo.chart.animation.js" type="text/javascript"></script> <script src="scripts/wijmo.chart.finance.js" type="text/javascript"></script> <script src="scripts/wijmo.angular.js" type="text/javascript"></script> <script src="scripts/app.js" type="text/javascript"></script> </head> <body ng-app="app" ng-controller="appCtrl"> <!-- this is the financial chart --> <wj-financial-chart items-source="data" binding-x="date"> <wj-financial-chart-series name="Open" binding="open"></wj-financial-chart-series> <wj-financial-chart-series name="Close" binding="close"></wj-financial-chart-series> </wj-financial-chart> </body> </html>
// declare app module var app = angular.module('app', ['wj']); // app controller provides data app.controller('appCtrl', function appCtrl($scope) { // add data array to scope $scope.data = loadData(); }); $scope.chartProps = { header: 'Facebook, Inc. (FB)' };
/* set default chart style */ .wj-flexchart { height: 400px; background-color: white; box-shadow: 4px 4px 10px 0px rgba(50, 50, 50, 0.75); padding: 8px; margin-bottom: 12px; }

Result (live):

Chart Types

The FinancialChart control supports various chart types to allow customization.

The example below shows what happens when you change the chartType.

<wj-financial-chart items-source="data" symbol-size="4" header={{chartProps.header}} chart-type="{{chartProps.chartType}}" binding-x="date"> <wj-financial-chart-series binding="{{chartProps.bindingY}}"></wj-financial-chart-series> </wj-financial-chart> <wj-menu value="chartProps.chartType" header="Chart Type"> <wj-menu-item value="4">Area</wj-menu-item> <wj-menu-item value="2">Line</wj-menu-item> <wj-menu-item value="0">Column</wj-menu-item> <wj-menu-item value="5">Candlestick</wj-menu-item> <wj-menu-item value="6">HighLowOpenClose</wj-menu-item> <wj-menu-item value="7">HeikinAshi</wj-menu-item> <wj-menu-item value="8">LineBreak</wj-menu-item> <wj-menu-item value="9">Renko</wj-menu-item> <wj-menu-item value="10">Kagi</wj-menu-item> <wj-menu-item value="11">ColumnVolume</wj-menu-item> <wj-menu-item value="12">EquiVolume</wj-menu-item> <wj-menu-item value="13">CandleVolume</wj-menu-item> <wj-menu-item value="14">ArmsCandleVolume</wj-menu-item> </wj-menu>
// add chart properties to scope $scope.data = data; $scope.chartProps = { chartType: wijmo.chart.finance.FinancialChartType.Line, header: 'Facebook, Inc. (FB)', bindingY: 'close' }; $scope.tpChart = null; // chart types var bindingYs = { 0: 'close', 2: 'close', 5: 'high,low,open,close', 6: 'high,low,open,close', 7: 'high,low,open,close', 8: 'high,low,open,close', 9: 'high,low,open,close', 10: 'high,low,open,close', 11: 'close,volume', 12: 'high,low,open,close,volume', 13: 'high,low,open,close,volume', 14: 'high,low,open,close,volume' }; $scope.$watch('chartProps.chartType', function () { var chartProps = $scope.chartProps, tpChart = $scope.tpChart; if (!tpChart) { return; } chartProps.bindingY = bindingYs[chartProps.chartType]; switch (chartProps.chartType) { case wijmo.chart.finance.FinancialChartType.LineBreak: tpChart.options = { lineBreak: { breaks: 3 } }; break; case wijmo.chart.finance.FinancialChartType.Renko: tpChart.options = { renko: { size: 2, unit: 'Fixed', field: 'Close', rounding: false } }; break; case wijmo.chart.finance.FinancialChartType.Kagi: tpChart.options = { kagi: { reversal: 1, unit: 'Fixed', field: 'Close' } }; break; default: break; } }); $scope.$watch('tpChart', function () { var tpChart = $scope.tpChart; if (!tpChart) { return; } tpChart.tooltip.content = function (ht) { var dateStr = 'Date: ' + ht.x + '<br/>', hlocStr = 'Open: ' + wijmo.Globalize.format(ht.item.open, 'n2') + '<br/>' + 'High: ' + wijmo.Globalize.format(ht.item.high, 'n2') + '<br/>' + 'Low: ' + wijmo.Globalize.format(ht.item.low, 'n2') + '<br/>' + 'Close: ' + wijmo.Globalize.format(ht.item.close, 'n2') + '<br/>', closeStr = 'Close: ' + wijmo.Globalize.format(ht.item.close, 'n2'), volStr = 'Volume: ' + wijmo.Globalize.format(ht.item.volume, 'n0'), toolTipStr; switch ($scope.chartProps.chartType) { case wijmo.chart.finance.FinancialChartType.Line: case wijmo.chart.finance.FinancialChartType.Column: toolTipStr = dateStr + closeStr; break; case wijmo.chart.finance.FinancialChartType.ColumnVolume: toolTipStr = dateStr + closeStr + '<br/>' + volStr; break; case wijmo.chart.finance.FinancialChartType.EquiVolume: case wijmo.chart.finance.FinancialChartType.CandleVolume: case wijmo.chart.finance.FinancialChartType.ArmsCandleVolume: toolTipStr = dateStr + hlocStr + volStr; break; default: toolTipStr = dateStr + hlocStr; break; } return toolTipStr; }; });

Result (live):

Area Line Column Candlestick HighLowOpenClose HeikinAshi LineBreak Renko Kagi ColumnVolume EquiVolume CandleVolume ArmsCandleVolume

Marker

The marker on FinancialChart consists of a text area with content reflecting data point values, and an optional vertical or horizontal line (or both for a cross-hair effect) positioned over the plot area.

In the example below, the vertical and horizontal lines, both get displayed when mouse is hovered over the plot area. The data values corresponding to the marker position are displayed next to x and y axes.

<wj-financial-chart control="lmChart" items-source="data" header="{{chartProps.header}}" chart-type="Candlestick" symbol-size="4" binding-x="date"> <wj-financial-chart-series binding="high,low,open,close"> </wj-financial-chart-series> <wj-flex-chart-line-marker lines="Both" interaction="Move" alignment="7" content="changeContent" position-changed="midPosChanged(s,e)"> </wj-flex-chart-line-marker> <wj-flex-chart-line-marker lines="None" interaction="Move" horizontal-position="1" content="changeYContent"> </wj-flex-chart-line-marker> <wj-flex-chart-line-marker lines="None" interaction="Move" vertical-position="1" content="changeXContent"> </wj-flex-chart-line-marker> </wj-financial-chart>
// add chart properties to scope $scope.data = data; $scope.chartProps = { header: 'Facebook, Inc. (FB)' }; $scope.lmChart = null; var pt = new wijmo.Point(), markcontents, pOffset; $scope.$watch('lmChart', function () { var lmChart = $scope.lmChart; if (!lmChart) { return; } lmChart.tooltip.content = ''; lmChart.axisY.position = 3; lmChart.rendered.addHandler(function () { var chartHostEle = lmChart.hostElement, pa = chartHostEle.querySelector('.wj-plot-area'); pOffset = wijmo.getElementRect(pa); }); var lineMarkers = lmChart.hostElement.querySelectorAll('.wj-chart-linemarker-container'); markershowing(lineMarkers,'hidden'); lmChart.hostElement.onmouseenter = function (e) { markershowing(lineMarkers, 'visible'); } lmChart.hostElement.onmouseleave = function (e) { markershowing(lineMarkers, 'hidden'); } }); $scope.midPosChanged = function (s, e) { pt = e; }; $scope.changeContent = function () { markcontents = getMarkerContents(new wijmo.Point(pt.x, pt.y)); return markcontents ? markcontents.content : ''; }; $scope.changeYContent = function () { return markcontents && markcontents.y ? markcontents.y.toString() : ''; } $scope.changeXContent = function () { return markcontents && markcontents.x ? markcontents.x.toString() : ''; } function markershowing(lineMarkers, visible) { for (var i = 0; i < lineMarkers.length; i++) { lineMarkers[i].style.visibility = visible; } } //get line marker content function getMarkerContents(pt) { //get line marker content ... return { content: '', x: xContent, y: yContent }; }

Result (live):

Range Selector

Range selector allows the user to choose the range of data to display on the FinancialChart.

In the example below, the FinancialChart control's min and max values change with the selection of range on range selector.

<wj-financial-chart style="border-bottom: 0 none; margin-bottom: 0px;" control="stChart" items-source="data" header="{{chartProps.header}}" chart-type="Candlestick" symbol-size="4" binding-x="date"> <wj-financial-chart-series name="Close" binding="high,low,open,close"></wj-financial-chart-series> </wj-financial-chart> <wj-financial-chart style="height:90px" control="rsChart" items-source="data" chart-type="Line" binding-x="date"> <wj-financial-chart-series binding="close"></wj-financial-chart-series> <wj-flex-chart-range-selector control="chartProps.rangeSelector" seamless="true" range-changed="rangeChanged(s,e)"> </wj-flex-chart-range-selector> </wj-financial-chart>
// add chart properties to scope $scope.data = data; $scope.chartProps = { header: 'Facebook, Inc. (FB)', rangeSelector: null }; $scope.rsChart = null; $scope.stChart = null; // range selector $scope.$watch('stChart', function () { var stChart = $scope.stChart; if (!stChart) { return; } stChart.axisX.labels = false; stChart.axisX.axisLine = false; stChart.legend.position = 0; stChart.plotMargin = '60 30 0 50'; stChart.tooltip.content = function (ht) { return 'Date: ' + ht.x + '<br/>' + 'Open: ' + wijmo.Globalize.format(ht.item.open, 'n2') + '<br/>' + 'High: ' + wijmo.Globalize.format(ht.item.high, 'n2') + '<br/>' + 'Low: ' + wijmo.Globalize.format(ht.item.low, 'n2') + '<br/>' + 'Close: ' + wijmo.Globalize.format(ht.item.close, 'n2') + '<br/>' + 'Volume: ' + wijmo.Globalize.format(ht.item.volume, 'n0'); }; }); $scope.$watch('rsChart', function () { var rsChart = $scope.rsChart; if (!rsChart) { return; } rsChart.axisY.labels = false; rsChart.axisY.majorGrid = false; rsChart.tooltip.content = ''; rsChart.plotMargin = '0 30 NaN 50'; }); $scope.rangeChanged = function (sender, e) { var stChart = $scope.stChart, rs = $scope.chartProps.rangeSelector; if (stChart && rs) { stChart.axisX.min = rs.min; stChart.axisX.max = rs.max; stChart.invalidate(); } };

Result (live):

Trend Lines

Trend lines are used to represent trends in data and to examine the problems of prediction.

The following example indicates moving average trend based on the past prices. User can change the period and type of the moving average line.

  1. period: the calculation period of the moving average line.
  2. type: the calculation type of the moving average line. This includes Simple, Weighted, Exponential and Triangular types.
<wj-financial-chart control="tlChart" header="{{chartProps.header}}" items-source="data" chart-type="Line" symbol-size="4" binding-x="date"> <wj-financial-chart-series name="Close" binding="close"></wj-financial-chart-series> <wj-flex-chart-moving-average binding="close" name="{{ chartProps.movingAverageName }}" period="{{ chartProps.movingAveragePeriod }}" type ="{{ chartProps.movingAverageType }}"> </wj-flex-chart-moving-average> <wj-flex-chart-legend position="Top"></wj-flex-chart-legend> <wj-flex-chart-axis wj-property="axisY" position="Right"></wj-flex-chart-axis> </wj-financial-chart> <dl class="dl-horizontal"> <dt>Period</dt> <dd> <wj-input-number control="inputPeriod" id="inputPeriod" class="period" value="movingAveragePeriod" min="2" max="200" step="1" format="n0"> </wj-input-number> </dd> <dt>Type</dt> <dd> <wj-menu value="chartProps.movingAverageType" header="Moving Average Type"> <wj-menu-item value="0">Simple</wj-menu-item> <wj-menu-item value="1">Weighted</wj-menu-item> <wj-menu-item value="2">Exponential</wj-menu-item> <wj-menu-item value="3">Triangular</wj-menu-item> </wj-menu> </dd> </dl>
// add chart properties to scope $scope.data = data; $scope.inputPeriod = null; $scope.movingAveragePeriod = 2; $scope.chartProps = { header: 'Facebook, Inc. (FB)', movingAveragePeriod: 2, movingAverageType: 0, movingAverageName: wijmo.chart.analytics.MovingAverageType.Simple, }; $scope.$watch('chartProps.movingAverageType', function () { $scope.chartProps.movingAverageName = wijmo.chart.analytics.MovingAverageType[$scope.chartProps.movingAverageType] + ' Moving Average'; }); $scope.$watch('movingAveragePeriod', function () { var input = $scope.inputPeriod, val = $scope.movingAveragePeriod; if (!input) { return; } if (val < input.min || val > input.max) { return; } $scope.chartProps.movingAveragePeriod = val; });

Result (live):

Period
Type
Simple Weighted Exponential Triangular

Event Annotation

Annotations are used to mark important news or events that can be attached to a specific data point on FinancialChart. Users can hover over the event to display the full annotation text.

There are Circle, Ellipse, Image, Line, Polygon, Rectangle, Square and Text annotations that can be used to mark an event.

<wj-financial-chart control="anChart" header="{{chartProps.header}}" items-source="data" chart-type="Line" binding-x="date"> <wj-financial-chart-series name="Close" binding="close"></wj-financial-chart-series> <wj-flex-chart-annotation-layer> <wj-flex-chart-annotation ng-repeat="a in annotations" content="E" attachment="DataIndex" type="{{ a.type }}" height="{{ a.height }}" width="{{ a.width }}" radius="{{ a.radius }}" length = "{{ a.length }}" tooltip="{{ a.tooltip }}" point-index="{{ a.pointIndex }}" style="{'fill': '#cccccc', 'stroke': '#888888', 'fill-opacity': 1, 'stroke-width': 1, 'stroke-opacity': 1 }"> </wj-flex-chart-annotation> </wj-flex-chart-annotation-layer> </wj-financial-chart>
// add chart properties to scope $scope.data = data; $scope.chartProps = { chartType: wijmo.chart.finance.FinancialChartType.Line, header: 'Facebook, Inc. (FB)' }; $scope.annotations = [ { type: 'Rectangle', width: 40, height: 30, pointIndex: 16, tooltip: 'FACEBOOK INC Files SEC form 8-K, Results of Operations and Financial Condition', position: 'Center', attachment: 'DataIndex', content: 'E' }, { type: 'Ellipse', width: 40, height: 30, pointIndex: 17, //01/29/15 position: 'Center', attachment: 'DataIndex', content: 'E', tooltip: 'FACEBOOK INC Files SEC form 10-K, Annual Report' }, { type: 'Circle', radius: 20, pointIndex: 49, //03/17/15 tooltip: 'Coverage initiated on Facebook by Brean Capital', position: 'Center', attachment: 'DataIndex', content: 'E' }, { type: 'Square', length: 30, pointIndex: 75, //04/22/15 tooltip: 'FACEBOOK INC Files SEC form 8-K, Results of Operations and Financial Condition', position: 'Center', attachment: 'DataIndex', content: 'E' } ];

Result (live):

Animation

The FinancialChart control can play animation with wijmo.chart.animation extension.

The example below shows how to play animation in FinancialChart control.

Click on chart to refresh and play animation.

<wj-financial-chart items-source="data" control="animationChart" symbol-size="4" header={{chartProps.header}} footer={{chartProps.footer}} chart-type="{{chartProps.animationChartType}}" binding-x="date"> <wj-financial-chart-series binding="{{chartProps.bindingY1}}"></wj-financial-chart-series> <wj-flex-chart-animation easing="{{chartProps.easing}}" duration="{{chartProps.duration}}"></wj-flex-chart-animation> </wj-financial-chart> <dl class="dl-horizontal"> <dt>Type</dt> <dd> <wj-menu value="chartProps.animationChartType" header="Chart Type"> <wj-menu-item value="4">Area</wj-menu-item> <wj-menu-item value="2">Line</wj-menu-item> <wj-menu-item value="0">Column</wj-menu-item> <wj-menu-item value="5">Candlestick</wj-menu-item> <wj-menu-item value="6">HighLowOpenClose</wj-menu-item> </wj-menu> </dd> <dt>Easing</dt> <dd> <wj-menu value="chartProps.easing" header="Easing"> <wj-menu-item value="'Linear'">Linear</wj-menu-item> <wj-menu-item value="'Swing'">Swing</wj-menu-item> <wj-menu-item value="'EaseInQuad'">EaseInQuad</wj-menu-item> <wj-menu-item value="'EaseInCubic'">EaseInCubic</wj-menu-item> <wj-menu-item value="'EaseInQuart'">EaseInQuart</wj-menu-item> <wj-menu-item value="'EaseInQuint'">EaseInQuint</wj-menu-item> <wj-menu-item value="'EaseInSine'">EaseInSine</wj-menu-item> <wj-menu-item value="'EaseInExpo'">EaseInExpo</wj-menu-item> <wj-menu-item value="'EaseInCirc'">EaseInCirc</wj-menu-item> <wj-menu-item value="'EaseInBack'">EaseInBack</wj-menu-item> <wj-menu-item value="'EaseInBounce'">EaseInBounce</wj-menu-item> <wj-menu-item value="'EaseInElastic'">EaseInElastic</wj-menu-item> </wj-menu> </dd> <dt>Duration</dt> <dd> <wj-input-number control="inputDuration" value="iptDuration" min="200" max="5000" step="200" format="n0"> </wj-input-number> </dd> </dl>
// add chart properties to scope $scope.data = data; $scope.chartProps = { animationChartType: wijmo.chart.finance.FinancialChartType.Line, header: 'Facebook, Inc. (FB)', footer: 'Click on chart to refresh', bindingY: 'close', easing: 'Swing', duration: 400 }; $scope.animationChart = null; // chart types var bindingYs = { 0: 'close', 2: 'close', 4: 'high,low,open,close', 5: 'high,low,open,close', 6: 'high,low,open,close' }; $scope.$watch('chartProps.animationChartType', function () { var chartProps = $scope.animationChartType, animationChart = $scope.animationChart; if (!animationChart) { return; } chartProps.bindingY = bindingYs[chartProps.animationChartType]; }); $scope.$watch('animationChart', function () { var animationChart = $scope.animationChart; if (!animationChart) { return; } animationChart.tooltip.content = function (ht) { var dateStr = 'Date: ' + ht.x + '
', hlocStr = 'Open: ' + wijmo.Globalize.format(ht.item.open, 'n2') + '
' + 'High: ' + wijmo.Globalize.format(ht.item.high, 'n2') + '
' + 'Low: ' + wijmo.Globalize.format(ht.item.low, 'n2') + '
' + 'Close: ' + wijmo.Globalize.format(ht.item.close, 'n2') + '
', closeStr = 'Close: ' + wijmo.Globalize.format(ht.item.close, 'n2'), volStr = 'Volume: ' + wijmo.Globalize.format(ht.item.volume, 'n0'), toolTipStr; switch ($scope.chartProps.animationChartType) { case wijmo.chart.finance.FinancialChartType.Line: case wijmo.chart.finance.FinancialChartType.Column: toolTipStr = dateStr + closeStr; break; default: toolTipStr = dateStr + hlocStr; break; } return toolTipStr; }; animationChart.hostElement.addEventListener('click', function () { animationChart.refresh(true); }); }); $scope.$watch('chartProps.easing', function () { var animationChart = $scope.animationChart, easing = $scope.chartProps.easing; if (!easing || easing === '') { return; } if (animationChart) { animationChart.refresh(true); } }); $scope.$watch('chartProps.duration', function () { var animationChart = $scope.animationChart; if (animationChart) { animationChart.refresh(true); } });

Result (live):

Type
Area Line Column Candlestick HighLowOpenClose
Easing
Linear Swing EaseInQuad EaseInCubic EaseInQuart EaseInQuint EaseInSine EaseInExpo EaseInCirc EaseInBack EaseInBounce EaseInElastic
Duration