How to Create a NASDAQ 100 Index Stock Chart in Blazor
ComponentOne Blazor provides FlexChart control to visualize data regardless of the domain you are working in. FlexChart is a fast, modern-looking, high-performance control that provides a powerful but easy API to visualize large sets of data to get your point across easily and configure different types of charts.
FlexChart provides a range of different chart types starting from basic bar or line charts to more complex chart types like candlestick and histogram and some specialized charts like treemaps. FlexChart takes care of underlying technicalities, which allows the developers to focus on critical application-specific tasks.
In this article, we will create a small dashboard that will display the historical data of Nasdaq 100 and its stocks. We will use different chart types to visualize the data and use line markers to show the prices.
We have fetched the last five years' stock price data for each stock in Nasdaq for this article. The result will look similar to the image below.
Creating Model and Helper Classes
Create Model Classes to Store Data
We will create multiple models and helper classes to help us fetch, store, and manipulate data for visualization. FlexChart will use these classes to display the data. Add a Models folder to your project and add a class file called Models inside the folder. In the Models.cs file, replace the code with the following:
public abstract class ModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
public class Quote
{
public DateTime Date { get; set; }
public double Open { get; set; }
public double Close { get; set; }
public double Volume { get; set; }
}
public class YearQuote
{
public int Year { get; set; }
public double Open { get; set; }
public double Close { get; set; }
public double Delta
{
get { return Close - Open; }
}
public double DeltaPct
{
get { return Delta / Open; }
}
public double DeltaPctAbs
{
get { return Math.Abs(DeltaPct); }
}
}
public class QuarterVolume : ModelBase
{
double volume;
public string Quarter { get; set; }
public double Volume
{
get { return volume; }
set
{
if (value != volume)
{
volume = value;
OnPropertyChanged("Volume");
}
}
}
public double Percent { get; set; }
}
public class DaysOutcome : ModelBase
{
int days;
double percent;
public string Outcome { get; set; }
public int Days
{
get { return days; }
set
{
if (value != days)
{
days = value;
OnPropertyChanged("Days");
}
}
}
public double Percent
{
get { return percent; }
set
{
if (value != percent)
{
percent = value;
OnPropertyChanged("Percent");
}
}
}
}
public class FluctuationData
{
public int Percent { get; set; }
public int Days { get; set; }
}
These classes will represent a single quote (or price) of the stock, its yearly performance, volume, and fluctuation in data. Now, we will add a class called DataView which will manipulate the stock data to provide yearly, monthly, and quarterly prices and profits, deltas, and fluctuation in a stock.
Since this class is vast, we are not adding the code in this article, but you can find the class in the sample at the end.
Another important class we will add is DataService class which will return the quote data of Nasdaq 100 since 1984. We already have the JSON data for Nasdaq so that this class will convert that JSON into a list of quote prices:
public List<Quote> GetQuotes()
{
return JsonSerializer.Deserialize<List<Quote>>(json);
}
The JSON variable contains the JSON data. We have used the Deserialize method of System.Text.Json.JsonSerializer class. This method will parse the data into the desired type, which is List Quote.
Adding various FlexChart
Add Required Packages
To use FlexChart in a Blazor application, the following NuGet packages are required:
- C1.Blazor.Core
- C1.Blazor.Chart
Once these packages are installed, we will need to add the required CSS and scripts. In the wwwroot/index.html file, add the following link and script element:
<link rel="stylesheet" href="/_content/C1.Blazor.Core/styles.css" />
<link rel="stylesheet" href="/_content/C1.Blazor.Chart/styles.css" />
<script src="/_content/C1.Blazor.Core/scripts.js"></script>
<script src="/_content/C1.Blazor.Chart/scripts.js"></script>
Add an Overview Chart
We will first add an overview chart that will display the yearly quote price of Nasdaq along with the change from the previous year. We will use a bubble chart for this:
<FlexChart Style="@style" Tooltip="Year: {Year}<br>Index Gain: {Delta:n1} {DeltaPct:p0}" HeaderContent="Yearly Performance" @ref="@chartBubble" ChartType="ChartType.Bubble"
SelectionMode="ChartSelectionMode.Point" AnimationSettings="AnimationSettings.All">
<SeriesCollection>
<Series BindingX="Delta" Binding="DeltaPct,DeltaPctAbs" SymbolSize="30"></Series>
</SeriesCollection>
<AxisCollection>
<Axis AxisType="AxisType.X" AxisLine="false" MajorGrid="true" Position="Position.Bottom" Title="Index Gain"></Axis>
<Axis AxisType="AxisType.Y" MajorGrid="true" AxisLine="true" Position="Position.Left" Format="0%" ></Axis>
</AxisCollection>
</FlexChart>
The ChartType of the chart is set to ChartType.Bubble. The chart binding is set to DeltaPct and DeltaPctAbs to visualize the price changes from the previous year.
Add a Profit and Loss Chart
To visualize the total yearly profit and loss, a Pie chart will be better. This pie chart will display total profit and total loss days from a selected year or range of data.
<FlexPie Style="@style" Palette="Palette.Custom" CustomPalette="@profitPalette" @ref="@chartProfit" Tooltip="{value} days" BindingName="Outcome" Binding="Days"
StartAngle="90" SelectionMode="ChartSelectionMode.Point" AnimationSettings="AnimationSettings.All" HeaderContent="Days By Gain/Loss" LegendPosition="Position.None">
<Label>
<PieDataLabel Position="PieLabelPosition.Center" Content="{name} {Percent:n0}%"></PieDataLabel>
</Label>
</FlexPie>
Add a Quarterly Volume Chart
We will add another chart that will display the volume by quarter. For this, too, we will use the FlexPie component.
<FlexPie Style="@style" @ref="@chartQuarter" Tooltip="{name} : {Percent:n0}%" BindingName="Quarter" Binding="Volume" InnerRadius="0.4" StartAngle="90"
SelectionMode="ChartSelectionMode.Point" AnimationSettings="AnimationSettings.All" HeaderContent="Quarters" LegendPosition="Position.None">
<Label>
<PieDataLabel Position="PieLabelPosition.Inside" Content="{name}"></PieDataLabel>
</Label>
</FlexPie>
Add a Monthly Volume Chart
As we have displayed the volume by each quarter, we will also show the volume by month. We will use the column chart for this:
<FlexChart Style="@style" SelectionMode="ChartSelectionMode.Point" AnimationSettings="AnimationSettings.All" HeaderContent="Monthly Volume" @ref="@monthsChart"
BindingX="Quarter" Binding="Volume">
<SeriesCollection>
<Series></Series>
</SeriesCollection>
<AxisCollection>
<Axis AxisType="AxisType.X" AxisLine="false" Position="Position.Bottom" MajorTickMarks="TickMark.None" LabelAngle="90"></Axis>
<Axis AxisType="AxisType.Y" MajorGrid="false" Labels="false" AxisLine="false"></Axis>
</AxisCollection>
</FlexChart>
Add a Weekly Profit/Loss Chart
We will add a chart that will display the weekly profit or loss according to the selected item from the profit/loss pie chart. For this, we will use the bar chart and bind the chart with each of the weekdays:
<FlexChart Style="@style" @ref="@chartDays" ChartType="ChartType.Bar" HeaderContent="Days Of Week" Tooltip="{value} days" BindingX="Outcome" Binding="Days"
SelectionMode="ChartSelectionMode.Point" AnimationSettings="AnimationSettings.All">
<SeriesCollection>
<Series></Series>
</SeriesCollection>
<AxisCollection>
<Axis AxisType="AxisType.X" Position="Position.Bottom" AxisLine="false"></Axis>
<Axis AxisType="AxisType.Y" AxisLine="false" Position="Position.Left" MajorGrid="false" Reversed="true"></Axis>
</AxisCollection>
</FlexChart>
Add a Fluctuation Data Chart
The fluctuation data represents how much a stock price changes in a day, week, or any given time range:
<FlexChart Style="@style" @ref="@chartFluctuation" Palette="Palette.Custom" CustomPalette="@fluctuationPalette" HeaderContent="Fluctuation" Tooltip="{value} days"
BindingX="Percent" Binding="Days" AnimationSettings="AnimationSettings.All">
<SeriesCollection>
<Series></Series>
</SeriesCollection>
<AxisCollection>
<Axis AxisType="AxisType.X" Position="Position.Bottom" Format="0\%" AxisLine="false"></Axis>
<Axis AxisType="AxisType.Y" MajorGrid="true" Position="Position.Left" Reversed="false"></Axis>
</AxisCollection>
</FlexChart>
Add a Total Quote Chart
So far, we have been adding profits or monthly charts. But, now we will add an overview chart that will display all the stock data from start to finish. This will help in recognizing the complete trend.
<FlexChart Palette="Palette.Custom" CustomPalette="@fluctuationPalette" Style="@smallStyle" HeaderContent="Monthly Index / Close" @ref="@chartSelection"
ChartType="ChartType.Area" Binding="Close" BindingX="Date">
<SeriesCollection>
<Series Binding="Close" BindingX="Date"></Series>
</SeriesCollection>
<MarkerCollection>
<LineMarker Content="{value:n0}" Interaction="LineMarkerInteraction.Move" Lines="LineMarkerLines.Vertical"></LineMarker>
</MarkerCollection>
</FlexChart>
For this chart, we have used LineMarker. This will move along with the mouse and will display the price at the current mouse position.
Add a Range Selector Chart
We will also add a time range selector for users who wish to see the data. We will use RangeSelector for this. RangeSelector will add a selector type element on the chart, which the users can drag to select a range of time:
<FlexChart Palette="Palette.Custom" CustomPalette="@fluctuationPalette" Style="@smallStyle" RangeSelector="@rangeSelector" @ref="@chartAll" ChartType="ChartType.Column"
BindingX="Date" Binding="Volume" ItemsSource="mquotes">
<SeriesCollection>
<Series Style="stroke-width: 1"></Series>
</SeriesCollection>
<AxisCollection>
<Axis AxisType="AxisType.X" Position="Position.Bottom" Max="mquotes.Last().Date.ToOADate()" Min="mquotes.First().Date.ToOADate()"></Axis>
<Axis AxisType="AxisType.Y" Labels="false" MajorGrid="false"></Axis>
</AxisCollection>
</FlexChart>
RangeSelector rangeSelector = new RangeSelector();
rangeSelector.ValueChanged += (s, e) =>
{
this.UpdateSelection(rangeSelector.LowerValue, rangeSelector.UpperValue, true);
};
Whenever the range is changed, we will update the data selected, which will update all the other charts. We will implement the UpdateSelection in later sections.
You will also notice that only this chart is bound to a data source, and all the other charts do not have any data source bound to them. The data source of the other charts will be set in the UpdateSelection method, according to the selected range.
Update Data Dynamically
Fetch the Data Using DataService
We will now fetch the data using the DataService class and create an instance of the DataView object, returning the data for each chart.
@inject DataService Svc
protected override void OnInitialized()
{
var quotes = Svc.GetQuotes();
dv = new DataView(quotes);
mquotes = dv.GetMonthlyQuotes();
this.StateHasChanged();
}
Update Data When the Range is Changed
We will use the RangeSelector to update the data for various charts. We have already implemented a way to update the selection, so let's move on to the UpdateSelection method.
The RangeSelector method will be used to update the data for various charts. We have already implemented a way to update the selection, but we can also update all the chart's data source according to the selected range.
This method will use the lower and upper values of the RangeSelector to fetch the data inside the range. The DataView class will return the months, fluctuations, volume, and other data, which can be set as the chart's data source.
Since this method is rather complex, it will not be expanded upon in this article. However, you can find it in the sample link at the end.
Update the Data When Chart Selection Changes
We will also need to update the range according to the selected values in various charts. For example, in the main overview bubble chart, if we choose a year, then the data should be updated only for that particular year.
We can quickly implement this by handling the selectionChanged event of each of the charts:
this.AddSelection(chartAll, chartBubble, chartSelection, chartProfit, chartQuarter, chartFluctuation, chartDays, monthsChart);
void AddSelection(params FlexChartBase[] charts)
{
foreach (var chart in charts)
{
chart.SelectionChanged += (s, e) =>
{
this.UpdateSelection(rangeSelector.LowerValue, rangeSelector.UpperValue);
};
}
}
Select a different data point in the chart, and other charts will be updated accordingly.
This article demonstrates how we use FlexChart to display stocks data, but that is just the tip of the iceberg. For more detailed information about different chart types and features of FlexChart, follow the links below:
You can find the sample used in this article here:
https://bitbucket.org/ashwin2409/dashboardnasdaq