diff --git a/README.md b/README.md index d7d1db4..3a8ef39 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,166 @@ -# How-to-synchronize-trackball-in-.NET-MAUI-SfCartesianChart -Learn how to synchronize the TrackBall feature in SfCartesianChart instances in .NET MAUI, allowing coordinated trackball interaction across charts for a consistent, interactive experience. +# How to synchronize trackball in .NET MAUI SfCartesianChart + +In this article, we described how to synchronize the trackball in multiple cartesian charts. + +The [Trackball](https://help.syncfusion.com/maui/cartesian-charts/trackball) feature in [Syncfusion MAUI Cartesian Chart](https://help.syncfusion.com/maui/cartesian-charts/getting-started) is an interactive functionality that allows users to track and display data points on a chart as they hover over on different areas of the chart. It provides real-time feedback by showing a marker or tooltip with relevant data, such as the value of a specific point on the chart. This enhances the user experience by providing detailed information about specific data points. + +**Importance of Synchronizing Trackball:** + +• **Consistency**: Ensures that all charts display data for the same point in time or category, making comparisons easier. + +• **Interactivity**: Enhances the user experience by allowing synchronized interactions across multiple charts. + + +**Steps to achieve Synchronized Trackball in .NET MAUI SfCartesianChart** + +**Step 1: Set Up Multiple Charts** + +Determine the number of charts you need to create to effectively visualize your data. Initialize a grid with the desired number of rows and columns. +Let’s configure the Syncfusion .NET MAUI SfCartesian Chart using this [getting started documentation](https://help.syncfusion.com/maui/cartesian-charts/getting-started) in each grid cells. Assign a unique x: Name to each of the charts. Refer to the following code example to create multiple charts in your application. + +[XAML] + ```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ``` + + +**Step 2: Initialize TrackballBehavior** + +Initialize TrackballBehavior for each chart and specify a unique x: Name for each of the [ChartTrackballBehavior](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.ChartTrackballBehavior.html). Refer to the following code to initialize TrackballBehavior. + + [XAML] + ```xml + + + + + + ``` +Similarly, you have to mention for other charts also. + +**Step 3: Handle the TrackballCreated events** + +Handling the TrackballCreated events is crucial for synchronizing the trackball across multiple SfCartesianChart controls. + +[TrackballCreated Event](https://help.syncfusion.com/cr/maui/Syncfusion.Maui.Charts.SfCartesianChart.html#Syncfusion_Maui_Charts_SfCartesianChart_TrackballCreated): This event is triggered when the trackball is created or updated. By handling this event, you can synchronize the trackball position across multiple charts. In your XAML, ensure that the TrackballCreated event is wired up for each chart. + + [XAML] + ```xml + + . + . + . + + ``` + + +Similarly, you have to specify event for other charts also. + In your code-behind file (e.g., MainPage.xaml.cs), implement the event handlers to synchronize the trackball positions. + +[C#] + ```csharp +public partial class MainPage : ContentPage +{ + public MainPage() + { + InitializeComponent(); + } + + private void HandleTrackballCreated(object sender, TrackballEventArgs e, SfCartesianChart primaryChart, ChartTrackballBehavior trackBall1, ChartTrackballBehavior trackBall2) + { + var pointsInfo = e.TrackballPointsInfo; + if (pointsInfo.Count > 0) + { + var item = (DataModel)pointsInfo[0].DataItem; + + // Convert chart point to screen point + float xPoint = primaryChart.ValueToPoint(primaryChart.XAxes[0], item.Date.ToOADate()); + float yPoint = primaryChart.ValueToPoint(primaryChart.YAxes[0], item.Value); + + // Show the trackball markers on the other charts + trackBall1.Show(xPoint, yPoint); + trackBall2.Show(xPoint, yPoint); + } + } + + private void firstChart_TrackballCreated(object sender, TrackballEventArgs e) + { + HandleTrackballCreated(sender, e, firstChart, trackBall2, trackBall3); + } + + private void secondChart_TrackballCreated(object sender, TrackballEventArgs e) + { + HandleTrackballCreated(sender, e, secondChart, trackBall1, trackBall3); + } + + private void thirdChart_TrackballCreated(object sender, TrackballEventArgs e) + { + HandleTrackballCreated(sender, e, thirdChart, trackBall1, trackBall2); + } +} + ``` + +In the above code, we have used the [ValueToPoint](https://help.syncfusion.com/maui/cartesian-charts/transform-axis-value-to-pixel-value-and-vice-versa) method to convert the data point value to the screen point, and the **ToOADate** method is used to convert the DateTime value to a double value here. Then we have to specify those points in the ChartTrackballBehavior class show method to show synchronized trackball for all charts. + +The following demo illustrates multiple charts in .NET MAUI with synchronized trackball, showing how the trackball positions move together across all charts when interacting with any one chart, following the implemented synchronization steps. + +**Output:** + + ![ trackball synchronization](https://support.syncfusion.com/kb/agent/attachment/article/18647/inline?token=eyJhbGciOiJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzA0L3htbGRzaWctbW9yZSNobWFjLXNoYTI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjM0MzQyIiwib3JnaWQiOiIzIiwiaXNzIjoic3VwcG9ydC5zeW5jZnVzaW9uLmNvbSJ9.SlnHed6aMQ8riGFUC2tKxYKLejojSUzYboX56xNEgxA) + +**Troubleshooting:** + +**Path too long exception** + +If you are facing a path too long exception when building this example project, close Visual Studio and rename the repository to a shorter name before building the project. + +For more details, refer to the KB on [How to synchronize trackball in .NET MAUI SfCartesianChart ?](https://support.syncfusion.com/kb/article/18647/how-to-synchronize-trackball-in-net-maui-sfcartesianchart-) diff --git a/TrackBallSample/TrackBallSample.sln b/TrackBallSample/TrackBallSample.sln new file mode 100644 index 0000000..d1c384c --- /dev/null +++ b/TrackBallSample/TrackBallSample.sln @@ -0,0 +1,24 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.12.35506.116 d17.12 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TrackBallSample", "TrackBallSample\TrackBallSample.csproj", "{30C2C141-0A42-4C2C-B854-39BA299F63FC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {30C2C141-0A42-4C2C-B854-39BA299F63FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {30C2C141-0A42-4C2C-B854-39BA299F63FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {30C2C141-0A42-4C2C-B854-39BA299F63FC}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {30C2C141-0A42-4C2C-B854-39BA299F63FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {30C2C141-0A42-4C2C-B854-39BA299F63FC}.Release|Any CPU.Build.0 = Release|Any CPU + {30C2C141-0A42-4C2C-B854-39BA299F63FC}.Release|Any CPU.Deploy.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/TrackBallSample/TrackBallSample/App.xaml b/TrackBallSample/TrackBallSample/App.xaml new file mode 100644 index 0000000..8a942f2 --- /dev/null +++ b/TrackBallSample/TrackBallSample/App.xaml @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/TrackBallSample/TrackBallSample/App.xaml.cs b/TrackBallSample/TrackBallSample/App.xaml.cs new file mode 100644 index 0000000..8358b4a --- /dev/null +++ b/TrackBallSample/TrackBallSample/App.xaml.cs @@ -0,0 +1,12 @@ +namespace TrackBallSample +{ + public partial class App : Application + { + public App() + { + InitializeComponent(); + + MainPage = new AppShell(); + } + } +} diff --git a/TrackBallSample/TrackBallSample/AppShell.xaml b/TrackBallSample/TrackBallSample/AppShell.xaml new file mode 100644 index 0000000..63d0bbc --- /dev/null +++ b/TrackBallSample/TrackBallSample/AppShell.xaml @@ -0,0 +1,14 @@ + + + + + + diff --git a/TrackBallSample/TrackBallSample/AppShell.xaml.cs b/TrackBallSample/TrackBallSample/AppShell.xaml.cs new file mode 100644 index 0000000..fa42a77 --- /dev/null +++ b/TrackBallSample/TrackBallSample/AppShell.xaml.cs @@ -0,0 +1,10 @@ +namespace TrackBallSample +{ + public partial class AppShell : Shell + { + public AppShell() + { + InitializeComponent(); + } + } +} diff --git a/TrackBallSample/TrackBallSample/MainPage.xaml b/TrackBallSample/TrackBallSample/MainPage.xaml new file mode 100644 index 0000000..2a63d5b --- /dev/null +++ b/TrackBallSample/TrackBallSample/MainPage.xaml @@ -0,0 +1,202 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 6 + 3 + 3 + 3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TrackBallSample/TrackBallSample/MainPage.xaml.cs b/TrackBallSample/TrackBallSample/MainPage.xaml.cs new file mode 100644 index 0000000..d96a7f9 --- /dev/null +++ b/TrackBallSample/TrackBallSample/MainPage.xaml.cs @@ -0,0 +1,45 @@ +using Syncfusion.Maui.Charts; +using TrackBallSample.Model; + +namespace TrackBallSample +{ + public partial class MainPage : ContentPage + { + public MainPage() + { + InitializeComponent(); + } + + private void HandleTrackballCreated(object sender, TrackballEventArgs e, SfCartesianChart primaryChart, ChartTrackballBehavior trackBall1, ChartTrackballBehavior trackBall2) + { + var pointsInfo = e.TrackballPointsInfo; + if (pointsInfo.Count > 0) + { + var item = (DataModel)pointsInfo[0].DataItem; + + // Convert chart point to screen point + float xPoint = primaryChart.ValueToPoint(primaryChart.XAxes[0], item.Date.ToOADate()); + float yPoint = primaryChart.ValueToPoint(primaryChart.YAxes[0], item.Value); + + // Show the trackball markers on the other charts + trackBall1.Show(xPoint, yPoint); + trackBall2.Show(xPoint, yPoint); + } + } + + private void firstChart_TrackballCreated(object sender, TrackballEventArgs e) + { + HandleTrackballCreated(sender, e, firstChart, trackBall2, trackBall3); + } + + private void secondChart_TrackballCreated(object sender, TrackballEventArgs e) + { + HandleTrackballCreated(sender, e, secondChart, trackBall1, trackBall3); + } + + private void thirdChart_TrackballCreated(object sender, TrackballEventArgs e) + { + HandleTrackballCreated(sender, e, thirdChart, trackBall1, trackBall2); + } + } +} \ No newline at end of file diff --git a/TrackBallSample/TrackBallSample/MauiProgram.cs b/TrackBallSample/TrackBallSample/MauiProgram.cs new file mode 100644 index 0000000..35fa13e --- /dev/null +++ b/TrackBallSample/TrackBallSample/MauiProgram.cs @@ -0,0 +1,26 @@ +using Microsoft.Extensions.Logging; +using Syncfusion.Maui.Core.Hosting; +namespace TrackBallSample +{ + public static class MauiProgram + { + public static MauiApp CreateMauiApp() + { + var builder = MauiApp.CreateBuilder(); + builder + .UseMauiApp() + .ConfigureSyncfusionCore() + .ConfigureFonts(fonts => + { + fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); + fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); + }); + +#if DEBUG + builder.Logging.AddDebug(); +#endif + + return builder.Build(); + } + } +} diff --git a/TrackBallSample/TrackBallSample/Model/DataModel.cs b/TrackBallSample/TrackBallSample/Model/DataModel.cs new file mode 100644 index 0000000..2766dcc --- /dev/null +++ b/TrackBallSample/TrackBallSample/Model/DataModel.cs @@ -0,0 +1,9 @@ + +namespace TrackBallSample.Model +{ + public class DataModel(DateTime date, double value) + { + public DateTime Date { get; set; } = date; + public double Value { get; set; } = value; + } +} diff --git a/TrackBallSample/TrackBallSample/Platforms/Android/AndroidManifest.xml b/TrackBallSample/TrackBallSample/Platforms/Android/AndroidManifest.xml new file mode 100644 index 0000000..e9937ad --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/Android/AndroidManifest.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/TrackBallSample/TrackBallSample/Platforms/Android/MainActivity.cs b/TrackBallSample/TrackBallSample/Platforms/Android/MainActivity.cs new file mode 100644 index 0000000..1d3b248 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/Android/MainActivity.cs @@ -0,0 +1,11 @@ +using Android.App; +using Android.Content.PM; +using Android.OS; + +namespace TrackBallSample +{ + [Activity(Theme = "@style/Maui.SplashTheme", MainLauncher = true, LaunchMode = LaunchMode.SingleTop, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize | ConfigChanges.Density)] + public class MainActivity : MauiAppCompatActivity + { + } +} diff --git a/TrackBallSample/TrackBallSample/Platforms/Android/MainApplication.cs b/TrackBallSample/TrackBallSample/Platforms/Android/MainApplication.cs new file mode 100644 index 0000000..184174b --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/Android/MainApplication.cs @@ -0,0 +1,16 @@ +using Android.App; +using Android.Runtime; + +namespace TrackBallSample +{ + [Application] + public class MainApplication : MauiApplication + { + public MainApplication(IntPtr handle, JniHandleOwnership ownership) + : base(handle, ownership) + { + } + + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); + } +} diff --git a/TrackBallSample/TrackBallSample/Platforms/Android/Resources/values/colors.xml b/TrackBallSample/TrackBallSample/Platforms/Android/Resources/values/colors.xml new file mode 100644 index 0000000..c04d749 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/Android/Resources/values/colors.xml @@ -0,0 +1,6 @@ + + + #512BD4 + #2B0B98 + #2B0B98 + \ No newline at end of file diff --git a/TrackBallSample/TrackBallSample/Platforms/MacCatalyst/AppDelegate.cs b/TrackBallSample/TrackBallSample/Platforms/MacCatalyst/AppDelegate.cs new file mode 100644 index 0000000..fc48eb1 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/MacCatalyst/AppDelegate.cs @@ -0,0 +1,10 @@ +using Foundation; + +namespace TrackBallSample +{ + [Register("AppDelegate")] + public class AppDelegate : MauiUIApplicationDelegate + { + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); + } +} diff --git a/TrackBallSample/TrackBallSample/Platforms/MacCatalyst/Entitlements.plist b/TrackBallSample/TrackBallSample/Platforms/MacCatalyst/Entitlements.plist new file mode 100644 index 0000000..de4adc9 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/MacCatalyst/Entitlements.plist @@ -0,0 +1,14 @@ + + + + + + + com.apple.security.app-sandbox + + + com.apple.security.network.client + + + + diff --git a/TrackBallSample/TrackBallSample/Platforms/MacCatalyst/Info.plist b/TrackBallSample/TrackBallSample/Platforms/MacCatalyst/Info.plist new file mode 100644 index 0000000..7268977 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/MacCatalyst/Info.plist @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + UIDeviceFamily + + 2 + + UIRequiredDeviceCapabilities + + arm64 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + XSAppIconAssets + Assets.xcassets/appicon.appiconset + + diff --git a/TrackBallSample/TrackBallSample/Platforms/MacCatalyst/Program.cs b/TrackBallSample/TrackBallSample/Platforms/MacCatalyst/Program.cs new file mode 100644 index 0000000..2b69554 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/MacCatalyst/Program.cs @@ -0,0 +1,16 @@ +using ObjCRuntime; +using UIKit; + +namespace TrackBallSample +{ + public class Program + { + // This is the main entry point of the application. + static void Main(string[] args) + { + // if you want to use a different Application Delegate class from "AppDelegate" + // you can specify it here. + UIApplication.Main(args, null, typeof(AppDelegate)); + } + } +} diff --git a/TrackBallSample/TrackBallSample/Platforms/Tizen/Main.cs b/TrackBallSample/TrackBallSample/Platforms/Tizen/Main.cs new file mode 100644 index 0000000..80ef7d9 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/Tizen/Main.cs @@ -0,0 +1,17 @@ +using System; +using Microsoft.Maui; +using Microsoft.Maui.Hosting; + +namespace TrackBallSample +{ + internal class Program : MauiApplication + { + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); + + static void Main(string[] args) + { + var app = new Program(); + app.Run(args); + } + } +} diff --git a/TrackBallSample/TrackBallSample/Platforms/Tizen/tizen-manifest.xml b/TrackBallSample/TrackBallSample/Platforms/Tizen/tizen-manifest.xml new file mode 100644 index 0000000..51f041d --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/Tizen/tizen-manifest.xml @@ -0,0 +1,15 @@ + + + + + + maui-appicon-placeholder + + + + + http://tizen.org/privilege/internet + + + + \ No newline at end of file diff --git a/TrackBallSample/TrackBallSample/Platforms/Windows/App.xaml b/TrackBallSample/TrackBallSample/Platforms/Windows/App.xaml new file mode 100644 index 0000000..65edc76 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/Windows/App.xaml @@ -0,0 +1,8 @@ + + + diff --git a/TrackBallSample/TrackBallSample/Platforms/Windows/App.xaml.cs b/TrackBallSample/TrackBallSample/Platforms/Windows/App.xaml.cs new file mode 100644 index 0000000..db69b24 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/Windows/App.xaml.cs @@ -0,0 +1,25 @@ +using Microsoft.UI.Xaml; + +// To learn more about WinUI, the WinUI project structure, +// and more about our project templates, see: http://aka.ms/winui-project-info. + +namespace TrackBallSample.WinUI +{ + /// + /// Provides application-specific behavior to supplement the default Application class. + /// + public partial class App : MauiWinUIApplication + { + /// + /// Initializes the singleton application object. This is the first line of authored code + /// executed, and as such is the logical equivalent of main() or WinMain(). + /// + public App() + { + this.InitializeComponent(); + } + + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); + } + +} diff --git a/TrackBallSample/TrackBallSample/Platforms/Windows/Package.appxmanifest b/TrackBallSample/TrackBallSample/Platforms/Windows/Package.appxmanifest new file mode 100644 index 0000000..222375c --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/Windows/Package.appxmanifest @@ -0,0 +1,46 @@ + + + + + + + + + $placeholder$ + User Name + $placeholder$.png + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TrackBallSample/TrackBallSample/Platforms/Windows/app.manifest b/TrackBallSample/TrackBallSample/Platforms/Windows/app.manifest new file mode 100644 index 0000000..59006ab --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/Windows/app.manifest @@ -0,0 +1,15 @@ + + + + + + + + true/PM + PerMonitorV2, PerMonitor + + + diff --git a/TrackBallSample/TrackBallSample/Platforms/iOS/AppDelegate.cs b/TrackBallSample/TrackBallSample/Platforms/iOS/AppDelegate.cs new file mode 100644 index 0000000..fc48eb1 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/iOS/AppDelegate.cs @@ -0,0 +1,10 @@ +using Foundation; + +namespace TrackBallSample +{ + [Register("AppDelegate")] + public class AppDelegate : MauiUIApplicationDelegate + { + protected override MauiApp CreateMauiApp() => MauiProgram.CreateMauiApp(); + } +} diff --git a/TrackBallSample/TrackBallSample/Platforms/iOS/Info.plist b/TrackBallSample/TrackBallSample/Platforms/iOS/Info.plist new file mode 100644 index 0000000..0004a4f --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/iOS/Info.plist @@ -0,0 +1,32 @@ + + + + + LSRequiresIPhoneOS + + UIDeviceFamily + + 1 + 2 + + UIRequiredDeviceCapabilities + + arm64 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + XSAppIconAssets + Assets.xcassets/appicon.appiconset + + diff --git a/TrackBallSample/TrackBallSample/Platforms/iOS/Program.cs b/TrackBallSample/TrackBallSample/Platforms/iOS/Program.cs new file mode 100644 index 0000000..2b69554 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/iOS/Program.cs @@ -0,0 +1,16 @@ +using ObjCRuntime; +using UIKit; + +namespace TrackBallSample +{ + public class Program + { + // This is the main entry point of the application. + static void Main(string[] args) + { + // if you want to use a different Application Delegate class from "AppDelegate" + // you can specify it here. + UIApplication.Main(args, null, typeof(AppDelegate)); + } + } +} diff --git a/TrackBallSample/TrackBallSample/Platforms/iOS/Resources/PrivacyInfo.xcprivacy b/TrackBallSample/TrackBallSample/Platforms/iOS/Resources/PrivacyInfo.xcprivacy new file mode 100644 index 0000000..24ab3b4 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Platforms/iOS/Resources/PrivacyInfo.xcprivacy @@ -0,0 +1,51 @@ + + + + + + NSPrivacyAccessedAPITypes + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategorySystemBootTime + NSPrivacyAccessedAPITypeReasons + + 35F9.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryDiskSpace + NSPrivacyAccessedAPITypeReasons + + E174.1 + + + + + + diff --git a/TrackBallSample/TrackBallSample/Properties/launchSettings.json b/TrackBallSample/TrackBallSample/Properties/launchSettings.json new file mode 100644 index 0000000..edf8aad --- /dev/null +++ b/TrackBallSample/TrackBallSample/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "Windows Machine": { + "commandName": "MsixPackage", + "nativeDebugging": false + } + } +} \ No newline at end of file diff --git a/TrackBallSample/TrackBallSample/Resources/AppIcon/appicon.svg b/TrackBallSample/TrackBallSample/Resources/AppIcon/appicon.svg new file mode 100644 index 0000000..9d63b65 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Resources/AppIcon/appicon.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/TrackBallSample/TrackBallSample/Resources/AppIcon/appiconfg.svg b/TrackBallSample/TrackBallSample/Resources/AppIcon/appiconfg.svg new file mode 100644 index 0000000..21dfb25 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Resources/AppIcon/appiconfg.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/TrackBallSample/TrackBallSample/Resources/Fonts/OpenSans-Regular.ttf b/TrackBallSample/TrackBallSample/Resources/Fonts/OpenSans-Regular.ttf new file mode 100644 index 0000000..36eb5ce Binary files /dev/null and b/TrackBallSample/TrackBallSample/Resources/Fonts/OpenSans-Regular.ttf differ diff --git a/TrackBallSample/TrackBallSample/Resources/Fonts/OpenSans-Semibold.ttf b/TrackBallSample/TrackBallSample/Resources/Fonts/OpenSans-Semibold.ttf new file mode 100644 index 0000000..d1f015f Binary files /dev/null and b/TrackBallSample/TrackBallSample/Resources/Fonts/OpenSans-Semibold.ttf differ diff --git a/TrackBallSample/TrackBallSample/Resources/Images/dotnet_bot.png b/TrackBallSample/TrackBallSample/Resources/Images/dotnet_bot.png new file mode 100644 index 0000000..f93ce02 Binary files /dev/null and b/TrackBallSample/TrackBallSample/Resources/Images/dotnet_bot.png differ diff --git a/TrackBallSample/TrackBallSample/Resources/Raw/AboutAssets.txt b/TrackBallSample/TrackBallSample/Resources/Raw/AboutAssets.txt new file mode 100644 index 0000000..89dc758 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Resources/Raw/AboutAssets.txt @@ -0,0 +1,15 @@ +Any raw assets you want to be deployed with your application can be placed in +this directory (and child directories). Deployment of the asset to your application +is automatically handled by the following `MauiAsset` Build Action within your `.csproj`. + + + +These files will be deployed with your package and will be accessible using Essentials: + + async Task LoadMauiAsset() + { + using var stream = await FileSystem.OpenAppPackageFileAsync("AboutAssets.txt"); + using var reader = new StreamReader(stream); + + var contents = reader.ReadToEnd(); + } diff --git a/TrackBallSample/TrackBallSample/Resources/Splash/splash.svg b/TrackBallSample/TrackBallSample/Resources/Splash/splash.svg new file mode 100644 index 0000000..21dfb25 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Resources/Splash/splash.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/TrackBallSample/TrackBallSample/Resources/Styles/Colors.xaml b/TrackBallSample/TrackBallSample/Resources/Styles/Colors.xaml new file mode 100644 index 0000000..30307a5 --- /dev/null +++ b/TrackBallSample/TrackBallSample/Resources/Styles/Colors.xaml @@ -0,0 +1,45 @@ + + + + + + + #512BD4 + #ac99ea + #242424 + #DFD8F7 + #9880e5 + #2B0B98 + + White + Black + #D600AA + #190649 + #1f1f1f + + #E1E1E1 + #C8C8C8 + #ACACAC + #919191 + #6E6E6E + #404040 + #212121 + #141414 + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/TrackBallSample/TrackBallSample/Resources/Styles/Styles.xaml b/TrackBallSample/TrackBallSample/Resources/Styles/Styles.xaml new file mode 100644 index 0000000..6641e3a --- /dev/null +++ b/TrackBallSample/TrackBallSample/Resources/Styles/Styles.xaml @@ -0,0 +1,427 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TrackBallSample/TrackBallSample/TrackBallSample.csproj b/TrackBallSample/TrackBallSample/TrackBallSample.csproj new file mode 100644 index 0000000..fc429e2 --- /dev/null +++ b/TrackBallSample/TrackBallSample/TrackBallSample.csproj @@ -0,0 +1,66 @@ + + + + net8.0-android;net8.0-ios;net8.0-maccatalyst + $(TargetFrameworks);net8.0-windows10.0.19041.0 + + + + + + + Exe + TrackBallSample + true + true + enable + enable + + + TrackBallSample + + + com.companyname.trackballsample + + + 1.0 + 1 + + 11.0 + 13.1 + 21.0 + 10.0.17763.0 + 10.0.17763.0 + 6.5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/TrackBallSample/TrackBallSample/TrackBallSample.sln b/TrackBallSample/TrackBallSample/TrackBallSample.sln new file mode 100644 index 0000000..be2ccc4 --- /dev/null +++ b/TrackBallSample/TrackBallSample/TrackBallSample.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.5.002.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TrackBallSample", "TrackBallSample.csproj", "{4FE6CE80-D2B9-4720-BB03-63EC550C7C2F}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4FE6CE80-D2B9-4720-BB03-63EC550C7C2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4FE6CE80-D2B9-4720-BB03-63EC550C7C2F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4FE6CE80-D2B9-4720-BB03-63EC550C7C2F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4FE6CE80-D2B9-4720-BB03-63EC550C7C2F}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {9A3AEA51-C84F-43A3-B135-BD105DA724A9} + EndGlobalSection +EndGlobal diff --git a/TrackBallSample/TrackBallSample/ViewModel/ViewModel.cs b/TrackBallSample/TrackBallSample/ViewModel/ViewModel.cs new file mode 100644 index 0000000..32c29d0 --- /dev/null +++ b/TrackBallSample/TrackBallSample/ViewModel/ViewModel.cs @@ -0,0 +1,48 @@ +using System.Collections.ObjectModel; +using TrackBallSample.Model; + +namespace TrackBallSample.ViewModel +{ + public class ViewModel + { + public int DataCount = 25; + private readonly Random randomNumber; + public ObservableCollection DataCollection1 { get; set; } + public ObservableCollection DataCollection2 { get; set; } + public ObservableCollection DataCollection3 { get; set; } + + public ViewModel() + { + randomNumber = new Random(); + DataCollection1 = GenerateData(); + DataCollection2 = GenerateData(); + DataCollection3 = GenerateData(); + + } + + public ObservableCollection GenerateData() + { + ObservableCollection datas = new ObservableCollection(); + DateTime date = new DateTime(2020, 1, 1); + double value = 100; + + for (int i = 0; i < this.DataCount; i++) + { + datas.Add(new DataModel(date, Math.Round(value, 2))); + date = date.Add(TimeSpan.FromDays(1)); + + if (randomNumber.NextDouble() > .5) + { + value += randomNumber.NextDouble(); + } + else + { + value -= randomNumber.NextDouble(); + } + } + + return datas; + } + } + +}