ASP.NET MVC FinancialChart 101

This page shows how to get started with ASP.NET MVC's FinancialChart control.

Getting Started

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

  1. Create a new MVC project using the C1 ASP.NET MVC application template.
  2. Add controller and corresponding view to the project.
  3. Initialize the FinancialChart control in view using razor syntax.
  4. (Optional) Add some CSS to customize the FinancialChart control's appearance.
<!DOCTYPE html> <html> <head> </head> <body> <!-- this is the FlexChart --> @(Html.C1().FinancialChart().Id("introChart").Bind(Model.SharesData) .BindingX("date").AxisY(ay=>ay.AxisLine(false).Position(C1.Web.Mvc.Chart.Position.Right)) .Series(sers => { sers.Add().Name("Open").Binding("open"); sers.Add().Name("Close").Binding("close"); }) ) </body> </html>
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using FinancialChart101.Models; namespace FinancialChart101.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(new FinancialChartModel()); } } }
/* 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.

@(Html.C1().FinancialChart().Id("tpChart").Bind(Model.SharesData) .BindingX("date").AxisY(ay => ay.AxisLine(false).Position(C1.Web.Mvc.Chart.Position.Right)) .Header(Model.Header).SymbolSize(4).Tooltip(t => t.Content("tpChart_tooltipContent")) .Series(sers => { sers.Add().Name("Close").Binding("close"); }) ) Chart Type: @(Html.C1().ComboBox().Id("tpCombo").DisplayMemberPath("text").SelectedValuePath("value") .IsEditable(false).OnClientSelectedIndexChanged("tpCombo_SelectedIndexChanged"))
$(document).ready(function () { //Chart Types tpChart = wijmo.Control.getControl("#tpChart"); tpCombo = wijmo.Control.getControl("#tpCombo"); tpCombo.itemsSource = chartTypesList; }); //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' } , chartTypesList = [{ "value": "2", "text": "Line" } , { "value": "0", "text": "Column" } , { "value": "5", "text": "Candlestick" } , { "value": "6", "text": "HighLowOpenClose" } , { "value": "7", "text": "HeikinAshi" } , { "value": "8", "text": "LineBreak" } , { "value": "9", "text": "Renko" } , { "value": "10", "text": "Kagi" } , { "value": "11", "text": "ColumnVolume" } , { "value": "12", "text": "EquiVolume" } , { "value": "13", "text": "CandleVolume" } , { "value": "14", "text": "ArmsCandleVolume" }] , tpChart = null , tpCombo = null; function tpChart_tooltipContent(ht) { var dateStr = 'Date: ' + wijmo.Globalize.format(ht.item.date,'MM/dd/yyyy') + '
', 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 (tpCombo.selectedItem.text) { case 'Line': case 'Column': toolTipStr = dateStr + closeStr; break; case 'ColumnVolume': toolTipStr = dateStr + closeStr + '
' + volStr; break; case 'EquiVolume': case 'CandleVolume': case 'ArmsCandleVolume': toolTipStr = dateStr + hlocStr + volStr; break; default: toolTipStr = dateStr + hlocStr; break; } return toolTipStr; }; //var menu = new wijmo.input.Menu('#tpMenu'); function tpCombo_SelectedIndexChanged(sender) { var arg = wijmo.changeType(sender.selectedValue, wijmo.DataType.Number); // check if the conversion was successful if (wijmo.isNumber(arg) && tpChart && tpChart.series) { // update the value tpChart.chartType = arg; tpChart.series[0].binding = bindingYs[arg]; switch (sender.selectedItem.text) { case 'LineBreak': tpChart.options = { lineBreak: { newLineBreaks: 3 } }; break; case 'Renko': tpChart.options = { renko: { boxSize: 2, rangeMode: 'Fixed', fields: 'Close' } }; break; case 'Kagi': tpChart.options = { kagi: { reversalAmount: 1, rangeMode: 'Fixed', fields: 'Close' } }; break; default: break; } } };
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using FinancialChart101.Models; namespace FinancialChart101.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(new FinancialChartModel()); } } }

Result (live):

Chart Type:

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.

@(Html.C1().FinancialChart().Id("mkChart").Bind(Model.SharesData) .BindingX("date").AxisX(ax=>ax.Format("MM/dd/yyyy")) .AxisY(ay => ay.Position(C1.Web.Mvc.Chart.Position.Right)) .Header(Model.Header).SymbolSize(4).Tooltip(t => t.Content("")) .Series(sers => { sers.Add().Binding("high,low,open,close"); }) .AddLineMarker(lm => lm .Alignment(C1.Web.Mvc.Chart.LineMarkerAlignment.Auto) .Lines(C1.Web.Mvc.Chart.LineMarkerLines.Both) .DragContent(true) .Interaction(C1.Web.Mvc.Chart.LineMarkerInteraction.Move).Content("lineMarkerContent")) )
function lineMarkerContent(ht, pt) { var item = ht.series.collectionView.items[ht.pointIndex]; if (item) { return 'Date: ' + wijmo.Globalize.format(ht.x, 'MMM-dd') + '
' + 'High: ' + item.high.toFixed() + '
' + 'Low: ' + item.low.toFixed() + '
' + 'Open: ' + item.open.toFixed() + '
' + 'Close: ' + item.close.toFixed(); } };
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using FinancialChart101.Models; namespace FinancialChart101.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(new FinancialChartModel()); } } }

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.

@(Html.C1().FinancialChart().Id("stChart").Bind(Model.SharesData).CssStyle("border-bottom", "0") .CssStyle("margin-bottom", "0").ChartType(C1.Web.Mvc.Finance.ChartType.Candlestick) .BindingX("date").AxisX(ax => ax.Format("MM/dd/yyyy").Labels(false).AxisLine(false)) .Legend(C1.Web.Mvc.Chart.Position.None).PlotMargin("60 30 0 50") .AxisY(ay => ay.Position(C1.Web.Mvc.Chart.Position.Right)) .Header(Model.Header).SymbolSize(4).Tooltip(t => t.Content("stChart_tooltipContent")) .Series(sers => { sers.Add().Binding("high,low,open,close"); }) ) @(Html.C1().FinancialChart().Id("rsChart").Bind(Model.SharesData).Height(90) .ChartType(C1.Web.Mvc.Finance.ChartType.Line) .BindingX("date").PlotMargin("0 30 NaN 50") .AxisX(ax => ax.Format("MM/dd/yyyy")).AxisY(ay => ay.Labels(false).MajorGrid(false)) .Tooltip(t => t.Content("")) .AddRangeSelector(rs => rs.Id("RangeSelector").OnClientRangeChanged("rsChart_OnClientRangeChanged")) .Series(sers => { sers.Add().Binding("close"); }) )
$(document).ready(function () { //Range Selector stChart = wijmo.Control.getControl("#stChart"); rsChart = wijmo.Control.getControl("#rsChart"); }); function stChart_tooltipContent(ht) { var toolTipStr = 'Date: ' + wijmo.Globalize.format(ht.item.date, 'MM/dd/yyyy') + '
' + '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') + '
'; return toolTipStr; }; function rsChart_OnClientRangeChanged(sender, e) { if (stChart && rsChart) { var lineMarker = c1.getExtender(rsChart, 'RangeSelector'); if(lineMarker) { stChart.axisX.min = lineMarker.min; stChart.axisX.max = lineMarker.max; stChart.invalidate(); } } }; //declare variables var stChart = null , rsChart = null;
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using FinancialChart101.Models; namespace FinancialChart101.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(new FinancialChartModel()); } } }

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 using following client side properties.

  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.
@(Html.C1().FinancialChart().Id("tlChart").Bind(Model.SharesData).ChartType(C1.Web.Mvc.Finance.ChartType.Line) .BindingX("date").AxisX(ax => ax.Format("MM/dd/yyyy")) .Legend(C1.Web.Mvc.Chart.Position.Top).AxisY(ay => ay.Position(C1.Web.Mvc.Chart.Position.Right)) .Header(Model.Header) .Series(sers => { sers.Add().Binding("close").Name("Close"); sers.AddMovingAverage().Binding("close").Name("Simple Moving Average"); }) ) <dl class="dl-horizontal"> <dt>Period</dt> <dd> @Html.C1().InputNumber().Id("inPeriod").Min(Model.PeriodMin).Max(Model.PeriodMax).Step(Model.PeriodStep).Value(Model.PeriodValue) </dd> <dt>Moving Average Type</dt> <dd> @(Html.C1().ComboBox().Id("cmbMAType").Bind(Model.Settings["Type"]) .IsEditable(false).SelectedIndex(0).OnClientSelectedIndexChanged("cmbMAType_SelectedIndexChanged") ) </dd> </dl>
$(document).ready(function () { tlChart = wijmo.Control.getControl('#tlChart'); inPeriod = wijmo.Control.getControl('#inPeriod'); cmbMAType = wijmo.Control.getControl('#cmbMAType'); inPeriod.valueChanged.addHandler(function () { if (inPeriod.value < inPeriod.min || inPeriod.value > inPeriod.max) { return; } tlChart.series[1].period = inPeriod.value; }); }); var tlChart = null , movingAverage = null , inPeriod = null , cmbMAType = null; function cmbMAType_SelectedIndexChanged(sender) { var arg = sender.selectedValue; if (tlChart && tlChart.series && tlChart.series.length > 0 && tlChart.series[1]) { tlChart.series[1].type = wijmo.chart.analytics.MovingAverageType[arg]; // update name for legend item tlChart.series[1].name = sender.text + ' Moving Average'; tlChart.invalidate(); } };
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using FinancialChart101.Models; namespace FinancialChart101.Controllers { public class HomeController : Controller { public ActionResult Index() { FinancialChartModel Model = new FinancialChartModel(); Model.Settings = CreateSettings(); return View(Model); } private IDictionary CreateSettings() { var settings = new Dictionary { {"Type", new object[]{"Simple","Exponential","Triangular","Weighted"}} }; return settings; } } }

Result (live):

Period
Moving Average 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.

@(Html.C1().FinancialChart().Id("anChart").Bind(Model.SharesData).ChartType(C1.Web.Mvc.Finance.ChartType.Line) .BindingX("date").AxisX(ax => ax.Format("MM/dd/yyyy")) .Header(Model.Header) .Series(sers => { sers.Add().Binding("close").Name("Close"); }) .AddAnnotationLayer(layer=> { layer.AddRectangle(rect => rect.Width(40).Height(30).PointIndex(16) .Tooltip("FACEBOOK INC Files SEC form 8-K, Results of Operations and Financial Condition") .Offset(new System.Drawing.PointF(0, -15)).SeriesIndex(0).Position(AnnotationPosition.Center).Attachment(AnnotationAttachment.DataIndex) .Style(style => style.Fill("#cccccc").Stroke("#888888").FillOpacity(1).StrokeWidth(1).StrokeOpacity(1)) .Content("E") ); layer.AddEllipse(ellip => ellip.Width(40).Height(30).PointIndex(17) .Tooltip("FACEBOOK INC Files SEC form 10-K, Annual Report") .Offset(new System.Drawing.PointF(0, -15)).SeriesIndex(0).Position(AnnotationPosition.Center).Attachment(AnnotationAttachment.DataIndex) .Style(style => style.Fill("#cccccc").Stroke("#888888").FillOpacity(1).StrokeWidth(1).StrokeOpacity(1)) .Content("E") ); layer.AddCircle(circle => circle.Radius(20).PointIndex(49) .Tooltip("Coverage initiated on Facebook by Brean Capital") .Offset(new System.Drawing.PointF(0, -15)).SeriesIndex(0).Position(AnnotationPosition.Center).Attachment(AnnotationAttachment.DataIndex) .Style(style => style.Fill("#cccccc").Stroke("#888888").FillOpacity(1).StrokeWidth(1).StrokeOpacity(1)) .Content("E") ); layer.AddSquare(square => square.Length(30).PointIndex(75) .Tooltip("FACEBOOK INC Files SEC form 8-K, Results of Operations and Financial Condition") .Offset(new System.Drawing.PointF(0, -15)).SeriesIndex(0).Position(AnnotationPosition.Center).Attachment(AnnotationAttachment.DataIndex) .Style(style => style.Fill("#cccccc").Stroke("#888888").FillOpacity(1).StrokeWidth(1).StrokeOpacity(1)) .Content("E") ); } ) )
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using FinancialChart101.Models; namespace FinancialChart101.Controllers { public class HomeController : Controller { public ActionResult Index() { return View(new FinancialChartModel()); } } }

Result (live):