Wijmo 5

FinancialChart 101

This page shows how to get started with Wijmo's FinancialChart control.

Getting Started

Steps for getting started with the FinancialChart control in JavaScript applications:

  1. Add references to Wijmo.
  2. Add markup to serve as the Wijmo control's host.
  3. Initialize the Wijmo control(s) via JavaScript.
  4. Add some CSS to customize the input control's appearance (Optional).
<!DOCTYPE html> <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 wj-src="wijmo" src="bin/Devel/loaders/wijmo.load.module.js" type="text/javascript"></script> <script wj-src="wijmo.input" src="bin/Devel/loaders/wijmo.load.module.js" type="text/javascript"></script> <script wj-src="wijmo.chart" src="bin/Devel/loaders/wijmo.load.module.js" type="text/javascript"></script> <script wj-src="wijmo.chart.interaction" src="bin/Devel/loaders/wijmo.load.module.js" type="text/javascript"></script> <script wj-src="wijmo.chart.analytics" src="bin/Devel/loaders/wijmo.load.module.js" type="text/javascript"></script> <script wj-src="wijmo.chart.annotation" src="bin/Devel/loaders/wijmo.load.module.js" type="text/javascript"></script> <script wj-src="wijmo.chart.animation" src="bin/Devel/loaders/wijmo.load.module.js" type="text/javascript"></script> <script wj-src="wijmo.chart.finance" src="bin/Devel/loaders/wijmo.load.module.js" type="text/javascript"></script> </head> <body> <!-- FinancialChart --> <div id="introChart"></div> </body> </html>
// create controls var chart = new wijmo.chart.finance.FinancialChart('#introChart'); chart.initialize({ itemsSource: app.chartData, bindingX: 'date', axisY: { axisLine: false, position: 'Right' }, series: [ { name: 'Open', binding: 'open' }, { name: 'Close', binding: 'close' } ] });
/* 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.

<div id="tpChart"></div> <select id="tpMenu"> <option value="4">Area</option> <option selected value="2">Line</option> <option value="0">Column</option> <option value="5">Candlestick</option> <option value="6">HighLowOpenClose</option> <option value="7">HeikinAshi</option> <option value="8">LineBreak</option> <option value="9">Renko</option> <option value="10">Kagi</option> <option value="11">ColumnVolume</option> <option value="12">EquiVolume</option> <option value="13">CandleVolume</option> <option value="14">ArmsCandleVolume</option> </select>
// create controls var chart = new wijmo.chart.finance.FinancialChart('#tpChart'), bindingYs = { 0: 'close', 2: 'close', 4: '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' }; chart.initialize({ header: 'Facebook, Inc. (FB)', itemsSource: app.chartData, bindingX: 'date', series: [{ binding: 'close' }], symbolSize: 4, 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 (menu.value) { 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; } } }); // create menu var menu = new wijmo.input.Menu('#tpMenu'); menu.itemClicked.addHandler(function (sender) { var arg = wijmo.changeType(sender.selectedValue, wijmo.DataType.Number); // check if the conversion was successful if (wijmo.isNumber(arg)) { // update the value chart.chartType = arg; chart.series[0].binding = bindingYs[arg]; switch (arg) { case wijmo.chart.finance.FinancialChartType.LineBreak: chart.options = { lineBreak: { newLineBreaks: 3 } }; break; case wijmo.chart.finance.FinancialChartType.Renko: chart.options = { renko: { boxSize: 2, rangeMode: 'Fixed', fields: 'Close' } }; break; case wijmo.chart.finance.FinancialChartType.Kagi: chart.options = { kagi: { reversalAmount: 1, rangeMode: 'Fixed', fields: 'Close' } }; break; default: break; } } updateMenuHeader(); }); // update menu header to show current chart type function updateMenuHeader() { menu.header = '<b>Chart Type:</b> ' + menu.text; } updateMenuHeader();

Result (live):

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.

<div id="mkChart"></div>
var pt = new wijmo.Point(), markcontents, pOffset; // create controls var chart = new wijmo.chart.finance.FinancialChart('#mkChart'), midMarker = new wijmo.chart.LineMarker(chart, { lines: wijmo.chart.LineMarkerLines.Both, interaction: wijmo.chart.LineMarkerInteraction.Move, alignment: wijmo.chart.LineMarkerAlignment.Top | wijmo.chart.LineMarkerAlignment.Left, content: function () { markcontents = getMarkerContents(new wijmo.Point(pt.x, pt.y)); return markcontents ? markcontents.content : ''; } }), hMarker = new wijmo.chart.LineMarker(chart, { lines: wijmo.chart.LineMarkerLines.None, interaction: wijmo.chart.LineMarkerInteraction.Move, horizontalPosition: 1, content: function () { return markcontents && markcontents.y ? markcontents.y.toString() : ''; } }), vMarker = new wijmo.chart.LineMarker(chart, { lines: wijmo.chart.LineMarkerLines.None, interaction: wijmo.chart.LineMarkerInteraction.Move, verticalPosition: 1, content: function () { return markcontents && markcontents.x ? markcontents.x.toString() : ''; } }); chart.initialize({ chartType: wijmo.chart.finance.FinancialChartType.Candlestick, itemsSource: app.chartData, bindingX: 'date', series: [{ binding: 'high,low,open,close' }], tooltip: { content: '' }, axisY: { position: wijmo.chart.Position.Right }, header: 'Facebook, Inc. (FB)', symbolSize: 4 }); chart.rendered.addHandler(function () { var chartHostEle = chart.hostElement, pa = chartHostEle.querySelector('.wj-plot-area'); pOffset = wijmo.getElementRect(pa); }); chart.hostElement.onmouseenter = function (e) { markershowing(lineMarkers, 'visible'); } if ('ontouchstart' in window) { chart.hostElement.ontouchstart = function (e) { markershowing(lineMarkers, 'visible'); } } chart.hostElement.onmouseleave = function (e) { markershowing(lineMarkers, 'hidden'); } // linemarker control var lineMarkers = chart.hostElement.querySelectorAll('.wj-chart-linemarker-container'); markershowing(lineMarkers, 'hidden'); midMarker.positionChanged.addHandler(function (s, e) { pt = e; }); function markershowing(lineMarkers, visible) { for (var i = 0; i < lineMarkers.length; i++) { lineMarkers[i].style.visibility = visible; } } function getMarkerContents(pt) { var newHitPoint = new wijmo.Point(pt.x, NaN), ht, xContent, yContent, axisYMax, axisYMin, content = ''; if (!chart || chart.series.length < 1) { return; } axisYMax = chart.axisY.actualMax; axisYMin = chart.axisY.actualMin; //calculate the y value if (pOffset === undefined) { yContent = 0; } else { yContent = axisYMax - ((pt.y - pOffset.top) / pOffset.height) * (axisYMax - axisYMin); yContent = yContent.toFixed(2); } ht = chart.series[0].hitTest(newHitPoint); if (ht.x && ht.y !== null) { xContent = ht.x; } 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.

<div id="stChart" style="border-bottom: 0 none; margin-bottom: 0px;"></div> <div id="rsChart" style="height:90px"></div>
// create chart controls var stChart = new wijmo.chart.finance.FinancialChart('#stChart'), rsChart = new wijmo.chart.finance.FinancialChart('#rsChart'); stChart.initialize({ chartType: wijmo.chart.finance.FinancialChartType.Candlestick, itemsSource: app.chartData, series: [{ binding: 'high,low,open,close' }], header: 'Facebook, Inc. (FB)', symbolSize: 4, bindingX: 'date', axisX: { labels: false, axisLine: false }, legend: {position: wijmo.chart.Position.None}, plotMargin:'60 30 0 50', 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'); }} }); rsChart.initialize({ chartType: wijmo.chart.finance.FinancialChartType.Line, itemsSource: app.chartData, bindingX: 'date', series: [{ binding: 'close' }], axisY: { labels: false, majorGrid: false }, tooltip: {content: ''}, plotMargin:'0 30 NaN 50' }); //create range selector var rs = new wijmo.chart.interaction.RangeSelector(rsChart); rs.seamless = true; rs.rangeChanged.addHandler(function (sender,e) { 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.
<div id="tlChart"></div> <dl class="dl-horizontal"> <dt>Period</dt> <dd> <input id="period" type="text" /> </dd> <dt>Type</dt> <dd> <select id="maMenu"> <option value="0">Simple</option> <option value="1">Weighted</option> <option value="2">Exponential</option> <option value="3">Triangular</option> </select> </dd> </dl>
// create chart controls var tlChart = new wijmo.chart.finance.FinancialChart('#tlChart'); tlChart.initialize({ header: 'Facebook, Inc. (FB)', itemsSource: app.chartData, bindingX: 'date', chartType: wijmo.chart.finance.FinancialChartType.Line, axisY: { position: wijmo.chart.Position.Right }, legend: { position: wijmo.chart.Position.Top }, series: [{ name: 'Close', binding: 'close' }] }); // add trend line var movingAverage = new wijmo.chart.analytics.MovingAverage(); movingAverage.itemsSource = app.chartData; movingAverage.binding = 'close'; movingAverage.name = wijmo.chart.analytics.MovingAverageType[0] + ' Moving Average'; movingAverage.period = 2; movingAverage.type = wijmo.chart.analytics.MovingAverageType.Simple; tlChart.series.push(movingAverage); // create number control var period = new wijmo.input.InputNumber('#period', { step: 1, format: 'n0', value: 2, min: 2, max: 200 }); period.valueChanged.addHandler(function () { if (period.value < period.min || period.value > period.max) { return; } tlChart.series[1].period = period.value; }); // create menu control var menu = new wijmo.input.Menu('#maMenu'); menu.itemClicked.addHandler(function (sender) { var arg = wijmo.changeType(sender.selectedValue, wijmo.DataType.Number); // check if the conversion was successful if (wijmo.isNumber(arg)) { tlChart.series[1].type = arg; } updateMenuHeader(); }); // update menu header to show current selection mode function updateMenuHeader() { menu.header = '<b>Moving Average Type:</b> ' + menu.text; } updateMenuHeader();

Result (live):

Period
Type

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.

<div id="anChart"></div>
// create chart controls var anChart = new wijmo.chart.finance.FinancialChart('#anChart'); anChart.initialize({ header: 'Facebook, Inc. (FB)', itemsSource: app.chartData, bindingX: 'date', chartType: wijmo.chart.finance.FinancialChartType.Line, series: [ { name: 'Close', binding: 'close' } ] }); // add annotation var al = new wijmo.chart.annotation.AnnotationLayer(anChart), pos = wijmo.chart.annotation.AnnotationPosition.Center, offset = { x: 0, y: -15 }, style = { 'fill': '#cccccc', 'stroke': '#888888', 'fill-opacity': 1, 'stroke-width': 1, 'stroke-opacity': 1 }; // rectangle annotation var rect = new wijmo.chart.annotation.Rectangle({ width: 40, height: 30, pointIndex: 16,//1/28/15 tooltip: 'FACEBOOK INC Files SEC form 8-K, Results of Operations and Financial Condition', offset: offset, seriesIndex: 0, position: wijmo.chart.annotation.AnnotationPosition.Center, attachment: wijmo.chart.annotation.AnnotationAttachment.DataIndex, style: style, content: 'E' }); al.items.push(rect); // ellipse annotation var ellip = new wijmo.chart.annotation.Ellipse({ width: 40, height: 30, pointIndex: 17, //01/29/15 offset: offset, seriesIndex: 0, position: wijmo.chart.annotation.AnnotationPosition.Center, attachment: wijmo.chart.annotation.AnnotationAttachment.DataIndex, style: style, content: 'E', tooltip: 'FACEBOOK INC Files SEC form 10-K, Annual Report' }); al.items.push(ellip); // circle annotation var circle = new wijmo.chart.annotation.Circle({ radius: 20, pointIndex: 49, //03/17/15 tooltip: 'Coverage initiated on Facebook by Brean Capital', offset: offset, seriesIndex: 0, style: style, position: wijmo.chart.annotation.AnnotationPosition.Center, attachment: wijmo.chart.annotation.AnnotationAttachment.DataIndex, content: 'E' }); al.items.push(circle); // square annotation var square = new wijmo.chart.annotation.Square({ length: 30, pointIndex: 75, //04/22/15 tooltip: 'FACEBOOK INC Files SEC form 8-K, Results of Operations and Financial Condition', offset: offset, seriesIndex: 0, style: style, position: wijmo.chart.annotation.AnnotationPosition.Center, attachment: wijmo.chart.annotation.AnnotationAttachment.DataIndex, content: 'E' }); al.items.push(square);

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.

<div id="animationChart"></div> <dl class="dl-horizontal"> <dt>Chart Type</dt> <dd> <select id="animationChartType"> <option value="4">Area</option> <option selected value="2">Line</option> <option value="0">Column</option> <option value="5">Candlestick</option> <option value="6">HighLowOpenClose</option> </select> </dd> <dt>Easing</dt> <dd> <select id="easing"> <option value="Linear">Linear</option> <option selected value="Swing">Swing</option> <option value="EaseInQuad">EaseInQuad</option> <option value="EaseInCubic">EaseInCubic</option> <option value="EaseInQuart">EaseInQuart</option> <option value="EaseInQuint">EaseInQuint</option> <option value="EaseInSine">EaseInSine</option> <option value="EaseInExpo">EaseInExpo</option> <option value="EaseInCirc">EaseInCirc</option> <option value="EaseInBack">EaseInBack</option> <option value="EaseInBounce">EaseInBounce</option> <option value="EaseInElastic">EaseInElastic</option> </select> </dd> <dt>Duration</dt> <dd> <input id="duration" type="text" /> </dd> </dl>
// create controls var chart = new wijmo.chart.finance.FinancialChart('#animationChart'), bindingYs = { 0: 'close', 2: 'close', 4: 'close', 5: 'high,low,open,close', 6: 'high,low,open,close' }, animation; chart.initialize({ header: 'Facebook, Inc. (FB)', itemsSource: app.chartData, bindingX: 'date', series: [{ binding: 'close' }], symbolSize: 4, footer: 'Click on chart to refresh', 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 (menu.value) { case wijmo.chart.finance.FinancialChartType.Line: case wijmo.chart.finance.FinancialChartType.Column: toolTipStr = dateStr + closeStr; break; default: toolTipStr = dateStr + hlocStr; break; } return toolTipStr; } } }); chart.hostElement.addEventListener('click', function () { if (animation) { chart.refresh(true); } }); //create ChartAnimation animation = new wijmo.chart.animation.ChartAnimation(chart); // create chartType var chartType = new wijmo.input.Menu('#animationChartType'); chartType.itemClicked.addHandler(function (sender) { var arg = wijmo.changeType(sender.selectedValue, wijmo.DataType.Number); // check if the conversion was successful if (wijmo.isNumber(arg)) { // update the value chart.chartType = arg; chart.series[0].binding = bindingYs[arg]; } updateAnimationTypeHeader(); }); // update menu header to show current chart type function updateAnimationTypeHeader() { chartType.header = '<b>Chart Type:</b> ' + menu.text; } updateAnimationTypeHeader(); // create easing var easing = new wijmo.input.Menu('#easing'); easing.itemClicked.addHandler(function (sender) { //var arg = wijmo.changeType(sender.selectedValue, wijmo.DataType.Number); var arg = sender.selectedValue; if (arg && arg.length && animation && chart) { animation.easing = wijmo.chart.animation.Easing[arg]; chart.refresh(true); } updateEasingHeader(); }); // update menu header to show current chart type function updateEasingHeader() { easing.header = '<b>Easing:</b> ' + easing.text; } updateEasingHeader(); //create duration var duration = new wijmo.input.InputNumber('#duration', { step: 200, format: 'n0', value: 400, min: 200, max: 5000 }); duration.valueChanged.addHandler(function (ctrl) { if (animation && chart && ctrl.value >= ctrl.min && ctrl.value <= ctrl.max) { animation.duration = ctrl.value; chart.refresh(true); } });

Result (live):

Chart Type
Easing
Duration