FinancialChart 101

入门

在AngularJS应用中开始使用FinancialChart的步骤:

  1. 添加对AngularJS,Wijmo和Wijmo的AngularJS指令的引用。
  2. 在应用模块中包含Wijmo5指令:
    var app = angular.module('app', ['wj']);
  3. 添加一个控制器来提供数据和逻辑。
  4. 向当前页面添加FinancialChart并将它绑定到数据。
  5. 添加一些CSS来自定义图表的外观。
<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>
// 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):

图表类型

FinancialChart控件支持各种类型图表的自定义。

下面的样例演示当你更改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

标记器

FinancialChart的标记由反映当前数据点值的内容的文本区域和一个可选的位于绘图区域的垂直线或水平线(或者二者都有以达到交叉效果)组成。

在下面的样例中,当鼠标悬停在绘图区时,水平线和垂直线都会显示。准线位置的数据值会在x或y轴附近显示。

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

范围选择器

范围选择器允许用户选择展示在FinancialChart的数据范围。

在下面的样例中,FinancialChart控件的min和max值会随着Ranger 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):

趋势线

趋势线是用来代表数据的趋势并且检查可预测的问题。

下面的样例表示根据过去价格的移动平均趋势。用户可以更改移动平均线的periodtype

  1. period: 移动平均线的计算时间段。
  2. type: 移动平均线的计算类型,包括Simple, Weighted, ExponentialTriangular类型。
<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 id="inputPeriod" class="period" value="chartProps.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.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'; });

Result (live):

Period
Type
Simple Weighted Exponential Triangular

事件注释

注释是用来标记可以附加到FinancialChart指定数据点的重要新闻或事件。 用户可以悬停到事件上方来展示所有的注释文本。

Circle, Ellipse, Image, Line, Polygon, Rectangle, SquareText注释可以用来标记事件。

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

动画

FinancialChart控件可以在wijmo.chart.animation扩展中演示动画。

下面的样例演示如何在FinancialChart控件上播放动画。

单击图表会刷新并演示动画。

<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 value="chartProps.duration" 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