Mini Kabibi Habibi
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.Globalization
Imports System.Windows
Imports System.Xml.Linq
Imports DevExpress.Xpf.Charts
Imports DevExpress.Xpf.Gauges
Imports DevExpress.Xpf.Map
Namespace MapDemo
Partial Public Class SalesDashboard
Inherits MapDemoModule
Private dataGenerator As SalesDataGenerator
Public Sub New()
InitializeComponent()
dataGenerator = New SalesDataGenerator(chart, circularGauge)
infoGrid.DataContext = dataGenerator
scale.EndValue = dataGenerator.MaxSalesLevel + 10000
scale.StartValue = dataGenerator.MinSalesLevel - 10000
End Sub
End Class
Public Class ProductGroupInfo
Inherits DependencyObject
Public Shared ReadOnly NameProperty As DependencyProperty = DependencyProperty.Register("Name", GetType(String), GetType(ProductGroupInfo), New PropertyMetadata(""))
Public Shared ReadOnly ValueProperty As DependencyProperty = DependencyProperty.Register("Value", GetType(Double), GetType(ProductGroupInfo), New PropertyMetadata(0.0))
Public Property Name() As String
Get
Return CType(GetValue(NameProperty), String)
End Get
Set(ByVal value As String)
SetValue(NameProperty, value)
End Set
End Property
Public Property Value() As Double
Get
Return CDbl(GetValue(ValueProperty))
End Get
Set(ByVal value As Double)
SetValue(ValueProperty, value)
End Set
End Property
Public Sub New(ByVal value As Double, ByVal productName As String)
Me.Value = value
Name = productName
End Sub
End Class
Public Class ShopInfo
Inherits DependencyObject
Public Shared ReadOnly NameProperty As DependencyProperty = DependencyProperty.Register("Name", GetType(String), GetType(ShopInfo), New PropertyMetadata(""))
Public Shared ReadOnly PhoneProperty As DependencyProperty = DependencyProperty.Register("Phone", GetType(String), GetType(ShopInfo), New PropertyMetadata(""))
Public Shared ReadOnly FaxProperty As DependencyProperty = DependencyProperty.Register("Fax", GetType(String), GetType(ShopInfo), New PropertyMetadata(""))
Public Shared ReadOnly AddressProperty As DependencyProperty = DependencyProperty.Register("Address", GetType(String), GetType(ShopInfo), New PropertyMetadata(""))
Public Shared ReadOnly SalesProperty As DependencyProperty = DependencyProperty.Register("Sales", GetType(Double), GetType(ShopInfo), New PropertyMetadata(0.0))
Public Shared ReadOnly ShopLocationProperty As DependencyProperty = DependencyProperty.Register("ShopLocation", GetType(GeoPoint), GetType(ShopInfo), New PropertyMetadata(New GeoPoint()))
Public Property Name() As String
Get
Return CStr(GetValue(NameProperty))
End Get
Set(ByVal value As String)
SetValue(NameProperty, value)
End Set
End Property
Public Property Phone() As String
Get
Return CStr(GetValue(PhoneProperty))
End Get
Set(ByVal value As String)
SetValue(PhoneProperty, value)
End Set
End Property
Public Property Fax() As String
Get
Return CStr(GetValue(FaxProperty))
End Get
Set(ByVal value As String)
SetValue(FaxProperty, value)
End Set
End Property
Public Property Address() As String
Get
Return CStr(GetValue(AddressProperty))
End Get
Set(ByVal value As String)
SetValue(AddressProperty, value)
End Set
End Property
Public Property Sales() As Double
Get
Return CDbl(GetValue(SalesProperty))
End Get
Set(ByVal value As Double)
SetValue(SalesProperty, value)
End Set
End Property
Public Property ShopLocation() As GeoPoint
Get
Return CType(GetValue(ShopLocationProperty), GeoPoint)
End Get
Set(ByVal value As GeoPoint)
SetValue(ShopLocationProperty, value)
End Set
End Property
Private Shared Function ConvertShopNameToFilePath(ByVal ShopName As String) As String
Dim result As String = ShopName.Replace(" ", "")
result = "../Images/Shops/" & result.Replace("-", "") & ".png"
Return result
End Function
Private statistics As New Dictionary(Of String, Double)()
Private ReadOnly imagePath_Renamed As String
Public Sub New(ByVal Name As String, ByVal Address As String, ByVal Phone As String, ByVal Fax As String)
Me.Name = Name
Me.Address = Address
Me.Phone = Phone
Me.Fax = Fax
Me.imagePath_Renamed = ConvertShopNameToFilePath(Name)
End Sub
Public ReadOnly Property ImagePath() As String
Get
Return imagePath_Renamed
End Get
End Property
Public Sub AddProductGroup(ByVal groupName As String, ByVal sales As Double)
If statistics.ContainsKey(groupName) Then
statistics(groupName) = sales
Else
statistics.Add(groupName, sales)
End If
Me.Sales += sales
End Sub
Public Function GetSalesByProductGroup(ByVal groupName As String) As Double
Return If(statistics.ContainsKey(groupName), statistics(groupName), 0.0)
End Function
End Class
Public Class SalesDataGenerator
Inherits DependencyObject
Public Shared ReadOnly ShopsProperty As DependencyProperty = DependencyProperty.Register("Shops", GetType(ObservableCollection(Of ShopInfo)), GetType(SalesDataGenerator), New PropertyMetadata(Nothing))
Public Shared ReadOnly ActualStatisticsProperty As DependencyProperty = DependencyProperty.Register("ActualStatistics", GetType(ObservableCollection(Of ProductGroupInfo)), GetType(SalesDataGenerator), New PropertyMetadata(Nothing))
Public Shared ReadOnly SalesDescriptionProperty As DependencyProperty = DependencyProperty.Register("SalesDescription", GetType(String), GetType(SalesDataGenerator), New PropertyMetadata(String.Empty))
Public Shared ReadOnly SelectedShopProperty As DependencyProperty = DependencyProperty.Register("SelectedShop", GetType(ShopInfo), GetType(SalesDataGenerator), New PropertyMetadata(Nothing, New PropertyChangedCallback(AddressOf SelectedShopPropertyChanged)))
Public Shared ReadOnly MaxSalesLevelProperty As DependencyProperty = DependencyProperty.Register("MaxSalesLevel", GetType(Double), GetType(SalesDataGenerator), New PropertyMetadata(0.0))
Public Shared ReadOnly MinSalesLevelProperty As DependencyProperty = DependencyProperty.Register("MinSalesLevel", GetType(Double), GetType(SalesDataGenerator), New PropertyMetadata(0.0))
Public ReadOnly Property ActualStatistics() As ObservableCollection(Of ProductGroupInfo)
Get
Return CType(GetValue(ActualStatisticsProperty), ObservableCollection(Of ProductGroupInfo))
End Get
End Property
Public ReadOnly Property Shops() As ObservableCollection(Of ShopInfo)
Get
Return CType(GetValue(ShopsProperty), ObservableCollection(Of ShopInfo))
End Get
End Property
Public Property SalesDescription() As String
Get
Return CStr(GetValue(SalesDescriptionProperty))
End Get
Set(ByVal value As String)
SetValue(SalesDescriptionProperty, value)
End Set
End Property
Public Property SelectedShop() As ShopInfo
Get
Return CType(GetValue(SelectedShopProperty), ShopInfo)
End Get
Set(ByVal value As ShopInfo)
SetValue(SelectedShopProperty, value)
End Set
End Property
Public Property MinSalesLevel() As Double
Get
Return CDbl(GetValue(MinSalesLevelProperty))
End Get
Set(ByVal value As Double)
SetValue(MinSalesLevelProperty, value)
End Set
End Property
Public Property MaxSalesLevel() As Double
Get
Return CDbl(GetValue(MaxSalesLevelProperty))
End Get
Set(ByVal value As Double)
SetValue(MaxSalesLevelProperty, value)
End Set
End Property
Private Shared Sub SelectedShopPropertyChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
Dim dataGenerator As SalesDataGenerator = TryCast(d, SalesDataGenerator)
Dim shop As ShopInfo = TryCast(e.NewValue, ShopInfo)
If dataGenerator IsNot Nothing Then
If shop IsNot Nothing Then
dataGenerator.UpdateStatistics(shop)
Else
dataGenerator.UpdateTotalStatistics()
End If
End If
End Sub
Private ReadOnly chart As ChartControl
Private ReadOnly gaugeControl As CircularGaugeControl
Public Sub New(ByVal chart As ChartControl, ByVal gaugeControl As CircularGaugeControl)
Me.chart = chart
Me.SetValue(ShopsProperty, New ObservableCollection(Of ShopInfo)())
Me.SetValue(ActualStatisticsProperty, New ObservableCollection(Of ProductGroupInfo)())
Me.gaugeControl = gaugeControl
LoadDataFromXML()
UpdateMinMaxSales()
SelectedShop = Shops(0)
UpdateStatistics(SelectedShop)
UpdateTotalStatistics()
End Sub
Private Sub LoadDataFromXML()
Dim productGroupNames As New List(Of String)()
Dim document As XDocument = DataLoader.LoadXmlFromResources("/Data/Sales.xml")
If document IsNot Nothing Then
For Each element As XElement In document.Element("Sales").Elements()
Dim shopName As String = element.Element("ShopName").Value
Dim shopAddress As String = element.Element("ShopAddr").Value
Dim shopPhone As String = element.Element("ShopPhone").Value
Dim shopFax As String = element.Element("ShopFax").Value
Dim info As New ShopInfo(shopName, shopAddress, shopPhone, shopFax)
For Each statElement As XElement In element.Element("ShopStatistics").Elements()
Dim groupName As String = statElement.Element("ProductsGroupName").Value
If (Not productGroupNames.Contains(groupName)) Then
productGroupNames.Add(groupName)
End If
Dim sales As Double = Convert.ToDouble(statElement.Element("ProductGroupSales").Value, CultureInfo.InvariantCulture)
info.AddProductGroup(groupName, sales)
Next statElement
Dim geoPoint As New GeoPoint(Convert.ToDouble(element.Element("Latitude").Value, CultureInfo.InvariantCulture), Convert.ToDouble(element.Element("Longitude").Value, CultureInfo.InvariantCulture))
info.ShopLocation = geoPoint
Shops.Add(info)
Next element
End If
For Each groupName As String In productGroupNames
ActualStatistics.Add(New ProductGroupInfo(0.0, groupName))
Next groupName
UpdateTotalStatistics()
End Sub
Private Sub UpdateStatistics(ByVal info As ShopInfo)
For Each productGroupInfo As ProductGroupInfo In ActualStatistics
productGroupInfo.Value = info.GetSalesByProductGroup(productGroupInfo.Name)
Next productGroupInfo
SalesDescription = "Last Month Sales: " & info.Name
chart.UpdateData()
chart.Animate()
gaugeControl.Visibility = Visibility.Visible
End Sub
Private Sub UpdateMinMaxSales()
Dim minSales As Double = Shops(0).Sales
Dim maxSales As Double = Shops(0).Sales
For Each info As ShopInfo In Shops
If info.Sales > maxSales Then
maxSales = info.Sales
End If
If info.Sales < minSales Then
minSales = info.Sales
End If
Next info
MinSalesLevel = minSales
MaxSalesLevel = maxSales
End Sub
Public Sub UpdateTotalStatistics()
For Each info As ProductGroupInfo In ActualStatistics
info.Value = 0.0
For Each shopInfo As ShopInfo In Shops
info.Value += shopInfo.GetSalesByProductGroup(info.Name)
Next shopInfo
Next info
gaugeControl.Visibility = Visibility.Collapsed
SalesDescription = "Last Month Sales: All Shops"
chart.UpdateData()
chart.Animate()
End Sub
End Class
End Namespace