Add economic indicatros
This commit is contained in:
71
MarketDataLib/MarketDataModel/EconomicIndicator.cs
Normal file
71
MarketDataLib/MarketDataModel/EconomicIndicator.cs
Normal file
@@ -0,0 +1,71 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MarketData.MarketDataModel
|
||||
{
|
||||
public class EconomicIndicators : List<EconomicIndicator>
|
||||
{
|
||||
public EconomicIndicators()
|
||||
{
|
||||
}
|
||||
|
||||
public EconomicIndicators(List<EconomicIndicator> economicIndicators)
|
||||
{
|
||||
foreach(EconomicIndicator economicIndicator in economicIndicators)
|
||||
{
|
||||
Add(economicIndicator);
|
||||
}
|
||||
}
|
||||
|
||||
public List<Int32> GetYears()
|
||||
{
|
||||
if(0==Count)return null;
|
||||
List<Int32> years = (from EconomicIndicator economicIndicator in this select economicIndicator.Year).Distinct().ToList();
|
||||
years.Sort();
|
||||
return years;
|
||||
}
|
||||
|
||||
public Dictionary<String,EconomicIndicators> GetDictionary()
|
||||
{
|
||||
Dictionary<String,EconomicIndicators> dictionary=new Dictionary<String,EconomicIndicators>();
|
||||
if(0==Count)return null;
|
||||
for (int index = 0; index < Count; index++)
|
||||
{
|
||||
EconomicIndicator economicIndicator=this[index];
|
||||
if(!dictionary.ContainsKey(economicIndicator.CountryCode))
|
||||
{
|
||||
List<EconomicIndicator> list=new List<EconomicIndicator>();
|
||||
dictionary.Add(economicIndicator.CountryCode,new EconomicIndicators());
|
||||
}
|
||||
EconomicIndicators economicIndicators=dictionary[economicIndicator.CountryCode];
|
||||
economicIndicators.Add(economicIndicator);
|
||||
}
|
||||
List<String> keys=new List<String>(dictionary.Keys);
|
||||
foreach(String key in keys)
|
||||
{
|
||||
dictionary[key].Sort(new EconomicIndicatorByYear());
|
||||
}
|
||||
return dictionary;
|
||||
}
|
||||
}
|
||||
|
||||
public class EconomicIndicatorByYear : IComparer<EconomicIndicator>
|
||||
{
|
||||
public int Compare(EconomicIndicator p1,EconomicIndicator p2)
|
||||
{
|
||||
return p1.Year.CompareTo(p2.Year);
|
||||
}
|
||||
}
|
||||
|
||||
public class EconomicIndicator
|
||||
{
|
||||
public String Source{get;set;}
|
||||
public String CountryName{get;set;}
|
||||
public String CountryCode{get;set;}
|
||||
public String IndicatorName{get;set;}
|
||||
public String IndicatorCode{get;set;}
|
||||
public double IndicatorValue{get;set;}
|
||||
public int Year{get;set;}
|
||||
}
|
||||
}
|
||||
133
Navigator/Renderers/EconomicIndicatorsRenderer.cs
Normal file
133
Navigator/Renderers/EconomicIndicatorsRenderer.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
using DataDisplay.Common;
|
||||
using DataDisplay.DataSource;
|
||||
using DataDisplay.Graph;
|
||||
using DataDisplay.Renderers;
|
||||
using MarketData.Utils;
|
||||
using SkiaSharp;
|
||||
using System;
|
||||
|
||||
namespace Navigator.Renderers
|
||||
{
|
||||
public class EconomicIndicatorsRenderer : IRenderer
|
||||
{
|
||||
private SKPaint paintSeries=new SKPaint{Style=SKPaintStyle.StrokeAndFill,Color=new SKColor((uint)SKColors.Black),StrokeWidth=5f};
|
||||
private LineGraph economicIndicatorsLineGraph;
|
||||
|
||||
public event EventHandler RefreshRequested;
|
||||
|
||||
public void Refresh()
|
||||
{
|
||||
RefreshRequested?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public double XDataExtent{get;set;}
|
||||
public double XDataExtentMin{get;set;}
|
||||
public double XRange{get{return XDataExtent-XDataExtentMin;}}
|
||||
public double YDataExtent{get;set;}
|
||||
public double YDataExtentMin{get;set;}
|
||||
public double YRange{get{return YDataExtent-YDataExtentMin;}}
|
||||
|
||||
public CompositeDataSource EconomicIndicatorElements
|
||||
{
|
||||
set
|
||||
{
|
||||
if(null==economicIndicatorsLineGraph)economicIndicatorsLineGraph=new LineGraph(paintSeries,value);
|
||||
else economicIndicatorsLineGraph.SetDataSource(value);
|
||||
}
|
||||
}
|
||||
public bool AnyData()
|
||||
{
|
||||
if(null==economicIndicatorsLineGraph)return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetColorRed()
|
||||
{
|
||||
if(!AnyData())return;
|
||||
paintSeries.Color=new SKColor((uint)SKColors.Red);
|
||||
}
|
||||
|
||||
public void SetColorGreen()
|
||||
{
|
||||
if(!AnyData())return;
|
||||
paintSeries.Color=new SKColor((uint)SKColors.Green);
|
||||
}
|
||||
|
||||
public void SetColorBlack()
|
||||
{
|
||||
if(!AnyData())return;
|
||||
paintSeries.Color=new SKColor((uint)SKColors.Black);
|
||||
}
|
||||
|
||||
// ************************************************************************************************************************************
|
||||
// ********************************************************* R E N D E R E R *********************************************************
|
||||
// ************************************************************************************************************************************
|
||||
public void PaintSurface(SKSurface surface,SKImageInfo imageInfo)
|
||||
{
|
||||
SKCanvas canvas = surface.Canvas;
|
||||
canvas.Clear();
|
||||
if(!AnyData())return;
|
||||
|
||||
int width=imageInfo.Width;
|
||||
int height=imageInfo.Height;
|
||||
|
||||
XDataExtent=GetXDataExtent();
|
||||
YDataExtent=GetYDataExtent();
|
||||
XDataExtentMin=GetXDataExtentMin();
|
||||
YDataExtentMin=GetYDataExtentMin();
|
||||
|
||||
PointMapping pointMapping=new PointMapping(width,height,XDataExtent,XDataExtentMin,YDataExtent,YDataExtentMin,80,50);
|
||||
|
||||
GridLines gridLines=new GridLines(10,10);
|
||||
gridLines.AssignXDataType=GetXDataType;
|
||||
gridLines.AssignGetYDataType=GetYDataType;
|
||||
gridLines.AssignYDataFormatter=YDataFormatter;
|
||||
gridLines.Render(canvas,pointMapping);
|
||||
|
||||
if(null!=economicIndicatorsLineGraph)economicIndicatorsLineGraph.Render(canvas,pointMapping);
|
||||
}
|
||||
|
||||
private double GetXDataExtent()
|
||||
{
|
||||
if(null==economicIndicatorsLineGraph)return 0.00;
|
||||
return economicIndicatorsLineGraph.GetXExtent();
|
||||
}
|
||||
|
||||
private double GetYDataExtent()
|
||||
{
|
||||
if(null==economicIndicatorsLineGraph)return 0.00;
|
||||
double maxDataExtent=economicIndicatorsLineGraph.GetYExtent();
|
||||
return maxDataExtent;
|
||||
}
|
||||
|
||||
// custom grid label formatter for the data along the left side of the chart. We know a-priori that this is of type double.
|
||||
private String YDataFormatter(Object data)
|
||||
{
|
||||
Type dataType=data.GetType();
|
||||
String strValue=Utility.FormatNumberConstrain((double)data);
|
||||
return strValue;
|
||||
}
|
||||
|
||||
private double GetXDataExtentMin()
|
||||
{
|
||||
if(null==economicIndicatorsLineGraph)return 0.00;
|
||||
return economicIndicatorsLineGraph.GetXExtentMin();
|
||||
}
|
||||
|
||||
private double GetYDataExtentMin()
|
||||
{
|
||||
if(null==economicIndicatorsLineGraph)return 0.00;
|
||||
return economicIndicatorsLineGraph.GetYExtentMin();
|
||||
}
|
||||
|
||||
private Type GetXDataType()
|
||||
{
|
||||
return typeof(DateTime);
|
||||
}
|
||||
|
||||
private Type GetYDataType()
|
||||
{
|
||||
return typeof(double);
|
||||
}
|
||||
}
|
||||
}
|
||||
128
Navigator/ViewModels/EconomicIndicatorsViewModel.cs
Normal file
128
Navigator/ViewModels/EconomicIndicatorsViewModel.cs
Normal file
@@ -0,0 +1,128 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using MarketData.MarketDataModel;
|
||||
using MarketData.Service;
|
||||
using Navigator.Core;
|
||||
using DataDisplay.Renderers;
|
||||
using Navigator.MarketDataModel;
|
||||
using Navigator.Renderers;
|
||||
|
||||
namespace Navigator.ViewModels
|
||||
{
|
||||
public class EconomicIndicatorsViewModel : WorkspaceViewModel
|
||||
{
|
||||
private RelayCommand refreshCommand;
|
||||
private bool isRefreshing = false;
|
||||
private EconomicIndicatorsRenderer economicIndicatorsRenderer=new EconomicIndicatorsRenderer();
|
||||
private String selectedCode;
|
||||
private EconomicIndicators economicIndicators = default;
|
||||
private String chartTitle;
|
||||
private ObservableCollection<String> codeCollection;
|
||||
private bool showActivity = true;
|
||||
|
||||
public EconomicIndicatorsViewModel()
|
||||
{
|
||||
Title = "Consumer Price Index";
|
||||
Initialize();
|
||||
PropertyChanged += OnViewModelPropertyChanged;
|
||||
}
|
||||
private void OnViewModelPropertyChanged(object sender,PropertyChangedEventArgs eventArgs)
|
||||
{
|
||||
if (eventArgs.PropertyName.Equals("SelectedCode"))
|
||||
{
|
||||
if (null == selectedCode) return;
|
||||
HandleSelectedCodeRequest();
|
||||
}
|
||||
}
|
||||
private void Initialize()
|
||||
{
|
||||
Task workerTask=Task.Factory.StartNew(()=>
|
||||
{
|
||||
IEnumerable<String> codes=null;
|
||||
ServiceResult serviceResult=MarketDataServiceClient.GetInstance().GetDistinctEconomicIndicatorCodes();
|
||||
if(serviceResult.Success)codes=(List<String>)serviceResult.ContextSpecificResult;
|
||||
CodeCollection=new ObservableCollection<string>(codes);
|
||||
});
|
||||
workerTask.ContinueWith((continuation)=>
|
||||
{
|
||||
});
|
||||
}
|
||||
|
||||
public void HandleSelectedCodeRequest()
|
||||
{
|
||||
ServiceResult serviceResult = null;
|
||||
IsBusy=true;
|
||||
ShowActivity=!IsRefreshing;
|
||||
Task workerTask = Task.Factory.StartNew(() =>
|
||||
{
|
||||
serviceResult = MarketDataServiceClient.GetInstance().GetGetEconomicIndicators(selectedCode);
|
||||
if (serviceResult.Success)
|
||||
{
|
||||
ChartTitle = selectedCode;
|
||||
economicIndicators = new EconomicIndicators((List<EconomicIndicator>)serviceResult.ContextSpecificResult);
|
||||
if(null!=economicIndicators && economicIndicators.Count>0)
|
||||
{
|
||||
economicIndicatorsRenderer.EconomicIndicatorElements=EconomicIndicatorsModel.Elements(economicIndicators);
|
||||
economicIndicatorsRenderer.SetColorBlack();
|
||||
economicIndicatorsRenderer.Refresh();
|
||||
}
|
||||
}
|
||||
});
|
||||
workerTask.ContinueWith((TaskContinuationOptions) =>
|
||||
{
|
||||
IsBusy=false;
|
||||
IsRefreshing=false;
|
||||
ShowActivity=!IsRefreshing;
|
||||
});
|
||||
}
|
||||
public ObservableCollection<String> CodeCollection
|
||||
{
|
||||
get { return codeCollection; }
|
||||
set { SetProperty(ref codeCollection, value); }
|
||||
}
|
||||
public IRenderer Renderer
|
||||
{
|
||||
get{return economicIndicatorsRenderer;}
|
||||
}
|
||||
|
||||
public String SelectedCode
|
||||
{
|
||||
get { return selectedCode; }
|
||||
set { SetProperty(ref selectedCode, value); }
|
||||
}
|
||||
public String ChartTitle
|
||||
{
|
||||
get { return chartTitle; }
|
||||
set { SetProperty(ref chartTitle, value); }
|
||||
}
|
||||
public bool IsRefreshing
|
||||
{
|
||||
get{return isRefreshing;}
|
||||
set{SetProperty(ref isRefreshing,value);}
|
||||
}
|
||||
public bool ShowActivity
|
||||
{
|
||||
get {return showActivity;}
|
||||
set {SetProperty(ref showActivity,value);}
|
||||
}
|
||||
public ICommand RefreshCommand
|
||||
{
|
||||
get
|
||||
{
|
||||
if(null==refreshCommand)
|
||||
{
|
||||
refreshCommand=new RelayCommand(param=>
|
||||
{
|
||||
HandleSelectedCodeRequest();
|
||||
},param=>{return !IsRefreshing;});
|
||||
}
|
||||
return refreshCommand;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
80
Navigator/Views/EconomicIndicatorsPage.xaml
Normal file
80
Navigator/Views/EconomicIndicatorsPage.xaml
Normal file
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
|
||||
xmlns:dd="clr-namespace:DataDisplay.Controls;assembly=DataDisplay"
|
||||
xmlns:vm="clr-namespace:Navigator.ViewModels"
|
||||
ControlTemplate="{StaticResource ActivityIndicatorTemplate}"
|
||||
x:Class="Navigator.Views.EconomicIndicatorsPage">
|
||||
|
||||
<ContentPage.BindingContext>
|
||||
<vm:EconomicIndicatorsViewModel />
|
||||
</ContentPage.BindingContext>
|
||||
|
||||
|
||||
<ContentPage.Resources>
|
||||
<ResourceDictionary>
|
||||
<Style x:Key="FrameCardViewStyle" TargetType="Frame">
|
||||
<Setter Property="CornerRadius" Value="5" />
|
||||
<Setter Property="Margin" Value="5" />
|
||||
<Setter Property="Padding" Value="5" />
|
||||
<Setter Property="HorizontalOptions" Value="FillAndExpand" />
|
||||
<Setter Property="OutlineColor" Value="LightGray" />
|
||||
<Setter Property="BorderColor" Value="LightGray" />
|
||||
<Setter Property="HasShadow" Value="True" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="CenteredLabelStyle" TargetType="Label">
|
||||
<Setter Property="FontSize" Value="12"/>
|
||||
<Setter Property="FontAttributes" Value="Bold" />
|
||||
<Setter Property="TextColor" Value="Black" />
|
||||
<Setter Property="HorizontalTextAlignment" Value="Center" />
|
||||
</Style>
|
||||
</ResourceDictionary>
|
||||
</ContentPage.Resources>
|
||||
|
||||
<ContentPage.Content>
|
||||
<Grid BackgroundColor="White" Margin="2">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="30*" />
|
||||
<RowDefinition Height="70*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<Frame Grid.Row="0" Style="{StaticResource FrameCardViewStyle}">
|
||||
<StackLayout Orientation="Horizontal">
|
||||
<StackLayout Orientation="Vertical" >
|
||||
<Label Text="Code" HorizontalTextAlignment="Left" FontSize="15">
|
||||
</Label>
|
||||
<ListView x:Name="listView" SeparatorVisibility="Default" ItemsSource="{Binding CodeCollection,Mode=TwoWay}" SelectedItem="{Binding SelectedCode,Mode=TwoWay}" >
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextCell Text="{Binding .}"/>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</StackLayout>
|
||||
</StackLayout>
|
||||
</Frame>
|
||||
|
||||
<Frame Grid.Row="1" Style="{StaticResource FrameCardViewStyle}">
|
||||
<Grid Margin="1">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="4*" />
|
||||
<RowDefinition Height="4*" />
|
||||
<RowDefinition Height="80*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Label Grid.Row="1" Text="{Binding ChartTitle}" Style="{StaticResource CenteredLabelStyle}"></Label>
|
||||
<RefreshView Grid.Row="2" IsRefreshing="{Binding IsRefreshing, Mode=TwoWay}" Command="{Binding RefreshCommand}">
|
||||
<ScrollView>
|
||||
<dd:CanvasView x:Name="EconomicIndicatorsCanvas" Renderer="{Binding Renderer}"/>
|
||||
</ScrollView>
|
||||
</RefreshView>
|
||||
</Grid>
|
||||
</Frame>
|
||||
</Grid>
|
||||
</ContentPage.Content>
|
||||
|
||||
</ContentPage>
|
||||
20
Navigator/Views/EconomicIndicatorsPage.xaml.cs
Normal file
20
Navigator/Views/EconomicIndicatorsPage.xaml.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using Xamarin.Forms;
|
||||
using Xamarin.Forms.Xaml;
|
||||
|
||||
namespace Navigator.Views
|
||||
{
|
||||
[XamlCompilation(XamlCompilationOptions.Compile)]
|
||||
public partial class EconomicIndicatorsPage : ContentPage
|
||||
{
|
||||
public EconomicIndicatorsPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user