Skip to content

Commit a51a03e

Browse files
Merge pull request #1 from SyncfusionExamples/Chart-sample
948085 - Prepared sample and read me file for MAUI Chart control
2 parents f52b7e0 + e9b1807 commit a51a03e

39 files changed

+1412
-0
lines changed

ChartSample/ChartSample.sln

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.14.36212.18 d17.14
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChartSample", "ChartSample\ChartSample.csproj", "{3AC44380-7435-40D5-A2C7-621738BD7D71}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{3AC44380-7435-40D5-A2C7-621738BD7D71}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{3AC44380-7435-40D5-A2C7-621738BD7D71}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{3AC44380-7435-40D5-A2C7-621738BD7D71}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{3AC44380-7435-40D5-A2C7-621738BD7D71}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
GlobalSection(ExtensibilityGlobals) = postSolution
23+
SolutionGuid = {BB271940-53D8-4167-B040-4503C0C40C88}
24+
EndGlobalSection
25+
EndGlobal

ChartSample/ChartSample/App.xaml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version = "1.0" encoding = "UTF-8" ?>
2+
<Application xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
4+
xmlns:local="clr-namespace:ChartSample"
5+
x:Class="ChartSample.App">
6+
<Application.Resources>
7+
<ResourceDictionary>
8+
<ResourceDictionary.MergedDictionaries>
9+
<ResourceDictionary Source="Resources/Styles/Colors.xaml" />
10+
<ResourceDictionary Source="Resources/Styles/Styles.xaml" />
11+
</ResourceDictionary.MergedDictionaries>
12+
</ResourceDictionary>
13+
</Application.Resources>
14+
</Application>

ChartSample/ChartSample/App.xaml.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
namespace ChartSample
2+
{
3+
public partial class App : Application
4+
{
5+
public App()
6+
{
7+
InitializeComponent();
8+
}
9+
10+
protected override Window CreateWindow(IActivationState? activationState)
11+
{
12+
return new Window(new AppShell());
13+
}
14+
}
15+
}

ChartSample/ChartSample/AppShell.xaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<Shell
3+
x:Class="ChartSample.AppShell"
4+
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
5+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
6+
xmlns:local="clr-namespace:ChartSample"
7+
Title="ChartSample">
8+
9+
<ShellContent
10+
ContentTemplate="{DataTemplate local:MainPage}"
11+
Route="MainPage" />
12+
13+
</Shell>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace ChartSample
2+
{
3+
public partial class AppShell : Shell
4+
{
5+
public AppShell()
6+
{
7+
InitializeComponent();
8+
}
9+
}
10+
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
using Azure;
2+
using Azure.AI.OpenAI;
3+
using Microsoft.Extensions.AI;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Collections.ObjectModel;
7+
using System.Globalization;
8+
using System.Linq;
9+
using System.Text;
10+
using System.Threading.Tasks;
11+
12+
namespace ChartSample
13+
{
14+
internal class AzureOpenAIService
15+
{
16+
const string endpoint = "";
17+
const string deploymentName = "";
18+
string key = "";
19+
internal IChatClient? Client { get; set; }
20+
internal string? ChatHistory { get; set; }
21+
public AzureOpenAIService()
22+
{
23+
GetAzureOpenAI();
24+
}
25+
26+
private void GetAzureOpenAI()
27+
{
28+
try
29+
{
30+
var client = new AzureOpenAIClient(new Uri(endpoint), new AzureKeyCredential(key)).AsChatClient(modelId: deploymentName);
31+
Client = client;
32+
}
33+
catch (Exception)
34+
{
35+
}
36+
}
37+
38+
public async Task<ObservableCollection<Model>> GetCleanedData(ObservableCollection<Model> rawData)
39+
{
40+
ObservableCollection<Model> collection = new ObservableCollection<Model>();
41+
42+
var prompt = $"Clean the following e-commerce website traffic data, resolve outliers and fill missing values:\n{string.Join("\n", rawData.Select(d => $"{d.DateTime:yyyy-MM-dd-HH-m-ss}: {d.Visitors}"))} and the output cleaned data should be in the yyyy-MM-dd-HH-m-ss:Value, not required explanations";
43+
44+
try
45+
{
46+
if(Client != null)
47+
{
48+
ChatHistory = prompt;
49+
var response = await Client.CompleteAsync(ChatHistory);
50+
return CleanedData(response.ToString(), collection);
51+
}
52+
}
53+
catch (Exception)
54+
{
55+
return await Task.FromResult(GetDummyData(collection));
56+
}
57+
58+
return collection;
59+
}
60+
61+
private ObservableCollection<Model> CleanedData(string json, ObservableCollection<Model> collection)
62+
{
63+
if(string.IsNullOrEmpty(json))
64+
{
65+
return new ObservableCollection<Model>();
66+
}
67+
68+
var lines = json.Split('\n');
69+
foreach (var line in lines)
70+
{
71+
if(string.IsNullOrWhiteSpace(line))
72+
{
73+
continue;
74+
}
75+
76+
var parts = line.Split(':');
77+
if(parts.Length == 2)
78+
{
79+
var date = DateTime.ParseExact(parts[0].Trim(), "yyyy-MM-dd-HH-m-ss", CultureInfo.InvariantCulture);
80+
var high = double.Parse(parts[1].Trim());
81+
collection.Add(new Model { DateTime = date, Visitors = high });
82+
}
83+
}
84+
85+
return collection;
86+
}
87+
88+
private ObservableCollection<Model> GetDummyData(ObservableCollection<Model> collection)
89+
{
90+
return new ObservableCollection<Model>()
91+
{
92+
new Model { DateTime = new DateTime(2024, 07, 01, 00, 00, 00), Visitors = 150 },
93+
new Model { DateTime = new DateTime(2024, 07, 01, 01, 00, 00), Visitors = 160 },
94+
new Model { DateTime = new DateTime(2024, 07, 01, 02, 00, 00), Visitors = 155 },
95+
new Model { DateTime = new DateTime(2024, 07, 01, 03, 00, 00), Visitors = 162 },
96+
new Model { DateTime = new DateTime(2024, 07, 01, 04, 00, 00), Visitors = 170 },
97+
new Model { DateTime = new DateTime(2024, 07, 01, 05, 00, 00), Visitors = 175 },
98+
new Model { DateTime = new DateTime(2024, 07, 01, 06, 00, 00), Visitors = 145 },
99+
new Model { DateTime = new DateTime(2024, 07, 01, 07, 00, 00), Visitors = 180 },
100+
new Model { DateTime = new DateTime(2024, 07, 01, 08, 00, 00), Visitors = 190 },
101+
new Model { DateTime = new DateTime(2024, 07, 01, 09, 00, 00), Visitors = 185 },
102+
new Model { DateTime = new DateTime(2024, 07, 01, 10, 00, 00), Visitors = 200 },
103+
new Model { DateTime = new DateTime(2024, 07, 01, 11, 00, 00), Visitors = 207 }, // Missing data
104+
new Model { DateTime = new DateTime(2024, 07, 01, 12, 00, 00), Visitors = 220 },
105+
new Model { DateTime = new DateTime(2024, 07, 01, 13, 00, 00), Visitors = 230 },
106+
new Model { DateTime = new DateTime(2024, 07, 01, 14, 00, 00), Visitors = 237 }, // Missing data
107+
new Model { DateTime = new DateTime(2024, 07, 01, 15, 00, 00), Visitors = 250 },
108+
new Model { DateTime = new DateTime(2024, 07, 01, 16, 00, 00), Visitors = 260 },
109+
new Model { DateTime = new DateTime(2024, 07, 01, 17, 00, 00), Visitors = 270 },
110+
new Model { DateTime = new DateTime(2024, 07, 01, 18, 00, 00), Visitors = 277 }, // Missing data
111+
new Model { DateTime = new DateTime(2024, 07, 01, 19, 00, 00), Visitors = 280 },
112+
new Model { DateTime = new DateTime(2024, 07, 01, 20, 00, 00), Visitors = 290 },
113+
new Model { DateTime = new DateTime(2024, 07, 01, 21, 00, 00), Visitors = 300 },
114+
new Model { DateTime = new DateTime(2024, 07, 01, 22, 00, 00), Visitors = 307 }, // Missing data
115+
new Model { DateTime = new DateTime(2024, 07, 01, 23, 00, 00), Visitors = 320 },
116+
};
117+
}
118+
}
119+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<TargetFrameworks>net9.0-android;net9.0-ios;net9.0-maccatalyst</TargetFrameworks>
5+
<TargetFrameworks Condition="$([MSBuild]::IsOSPlatform('windows'))">$(TargetFrameworks);net9.0-windows10.0.19041.0</TargetFrameworks>
6+
<!-- Uncomment to also build the tizen app. You will need to install tizen by following this: https://github.com/Samsung/Tizen.NET -->
7+
<!-- <TargetFrameworks>$(TargetFrameworks);net9.0-tizen</TargetFrameworks> -->
8+
9+
<!-- Note for MacCatalyst:
10+
The default runtime is maccatalyst-x64, except in Release config, in which case the default is maccatalyst-x64;maccatalyst-arm64.
11+
When specifying both architectures, use the plural <RuntimeIdentifiers> instead of the singular <RuntimeIdentifier>.
12+
The Mac App Store will NOT accept apps with ONLY maccatalyst-arm64 indicated;
13+
either BOTH runtimes must be indicated or ONLY macatalyst-x64. -->
14+
<!-- For example: <RuntimeIdentifiers>maccatalyst-x64;maccatalyst-arm64</RuntimeIdentifiers> -->
15+
16+
<OutputType>Exe</OutputType>
17+
<RootNamespace>ChartSample</RootNamespace>
18+
<UseMaui>true</UseMaui>
19+
<SingleProject>true</SingleProject>
20+
<ImplicitUsings>enable</ImplicitUsings>
21+
<Nullable>enable</Nullable>
22+
23+
<!-- Display name -->
24+
<ApplicationTitle>ChartSample</ApplicationTitle>
25+
26+
<!-- App Identifier -->
27+
<ApplicationId>com.companyname.chartsample</ApplicationId>
28+
29+
<!-- Versions -->
30+
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion>
31+
<ApplicationVersion>1</ApplicationVersion>
32+
33+
<!-- To develop, package, and publish an app to the Microsoft Store, see: https://aka.ms/MauiTemplateUnpackaged -->
34+
<WindowsPackageType>None</WindowsPackageType>
35+
36+
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'ios'">15.0</SupportedOSPlatformVersion>
37+
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'maccatalyst'">15.0</SupportedOSPlatformVersion>
38+
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">21.0</SupportedOSPlatformVersion>
39+
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</SupportedOSPlatformVersion>
40+
<TargetPlatformMinVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'windows'">10.0.17763.0</TargetPlatformMinVersion>
41+
<SupportedOSPlatformVersion Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'tizen'">6.5</SupportedOSPlatformVersion>
42+
</PropertyGroup>
43+
44+
<ItemGroup>
45+
<!-- App Icon -->
46+
<MauiIcon Include="Resources\AppIcon\appicon.svg" ForegroundFile="Resources\AppIcon\appiconfg.svg" Color="#512BD4" />
47+
48+
<!-- Splash Screen -->
49+
<MauiSplashScreen Include="Resources\Splash\splash.svg" Color="#512BD4" BaseSize="128,128" />
50+
51+
<!-- Images -->
52+
<MauiImage Include="Resources\Images\*" />
53+
<MauiImage Update="Resources\Images\dotnet_bot.png" Resize="True" BaseSize="300,185" />
54+
55+
<!-- Custom Fonts -->
56+
<MauiFont Include="Resources\Fonts\*" />
57+
58+
<!-- Raw Assets (also remove the "Resources\Raw" prefix) -->
59+
<MauiAsset Include="Resources\Raw\**" LogicalName="%(RecursiveDir)%(Filename)%(Extension)" />
60+
</ItemGroup>
61+
62+
<ItemGroup>
63+
<PackageReference Include="Microsoft.Maui.Controls" Version="$(MauiVersion)" />
64+
<PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="9.0.0" />
65+
<PackageReference Include="Syncfusion.Maui.Charts" Version="*" />
66+
<PackageReference Include="Syncfusion.Maui.Core" Version="*" />
67+
<PackageReference Include="Azure.AI.OpenAI" Version="2.0.0" />
68+
<PackageReference Include="Azure.Identity" Version="1.13.1" />
69+
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" Version="9.0.1-preview.1.24570.5" />
70+
</ItemGroup>
71+
72+
</Project>

ChartSample/ChartSample/MainPage.xaml

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?xml version="1.0" encoding="utf-8" ?>
2+
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
4+
xmlns:chart="clr-namespace:Syncfusion.Maui.Charts;assembly=Syncfusion.Maui.Charts"
5+
xmlns:core="clr-namespace:Syncfusion.Maui.Core;assembly=Syncfusion.Maui.Core"
6+
xmlns:local="clr-namespace:ChartSample"
7+
x:Class="ChartSample.MainPage">
8+
9+
<ContentPage.BindingContext>
10+
<local:ViewModel x:Name="viewModel"/>
11+
</ContentPage.BindingContext>
12+
13+
<Grid>
14+
<Grid.RowDefinitions>
15+
<RowDefinition Height="*"/>
16+
<RowDefinition Height="Auto"/>
17+
</Grid.RowDefinitions>
18+
19+
<chart:SfCartesianChart Grid.Row="0" x:Name="Chart" Margin="5" PaletteBrushes="{Binding PaletteBrushes}">
20+
21+
<chart:SfCartesianChart.Title>
22+
<StackLayout Orientation="Vertical">
23+
<Label Text="E-Commerce Website Traffic Data" FontSize="18" FontAttributes="Bold" HorizontalTextAlignment="Center" />
24+
<Label Text="AI-powered data cleaning and preprocessing every hour, tracking hourly website visitors" LineBreakMode="WordWrap" HorizontalTextAlignment="Center" FontSize="14"/>
25+
</StackLayout>
26+
</chart:SfCartesianChart.Title>
27+
28+
<chart:SfCartesianChart.XAxes>
29+
<chart:DateTimeAxis ShowMajorGridLines="False" EdgeLabelsDrawingMode="Shift">
30+
<chart:DateTimeAxis.LabelStyle>
31+
<chart:ChartAxisLabelStyle LabelFormat="hh tt"/>
32+
</chart:DateTimeAxis.LabelStyle>
33+
</chart:DateTimeAxis>
34+
</chart:SfCartesianChart.XAxes>
35+
36+
<chart:SfCartesianChart.YAxes>
37+
<chart:NumericalAxis ShowMajorGridLines="False" Minimum="140" Interval="30" Maximum="320" EdgeLabelsDrawingMode="Center">
38+
</chart:NumericalAxis>
39+
</chart:SfCartesianChart.YAxes>
40+
41+
<chart:LineSeries x:Name="CleanedDataseries" ItemsSource="{Binding CleanedData}"
42+
XBindingPath="DateTime" YBindingPath="Visitors"
43+
StrokeWidth="2"/>
44+
45+
<chart:LineSeries x:Name="RawDataSeries" ItemsSource="{Binding RawData}"
46+
XBindingPath="DateTime" YBindingPath="Visitors"
47+
StrokeWidth="2"/>
48+
49+
</chart:SfCartesianChart>
50+
51+
<core:SfBusyIndicator Grid.Row="0" IsVisible="{Binding IsBusy}"
52+
IsRunning="{Binding IsBusy}" AnimationType="DoubleCircle"/>
53+
54+
</Grid>
55+
56+
</ContentPage>

0 commit comments

Comments
 (0)