Skip to content

Commit 5c912ce

Browse files
committed
Added the sample
1 parent 122ed5b commit 5c912ce

File tree

10 files changed

+373
-0
lines changed

10 files changed

+373
-0
lines changed
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.11.35327.3
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SfChartMultipleTrackball", "SfChartMultipleTrackball\SfChartMultipleTrackball.csproj", "{E5B30519-D065-42FC-B89A-B435C07011D9}"
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+
{E5B30519-D065-42FC-B89A-B435C07011D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{E5B30519-D065-42FC-B89A-B435C07011D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{E5B30519-D065-42FC-B89A-B435C07011D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{E5B30519-D065-42FC-B89A-B435C07011D9}.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 = {0CA07FB0-0F65-49F3-AFCC-11C28CE1D119}
24+
EndGlobalSection
25+
EndGlobal
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<Application x:Class="SfChartMultipleTrackball.App"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:local="clr-namespace:SfChartMultipleTrackball"
5+
StartupUri="MainWindow.xaml">
6+
<Application.Resources>
7+
8+
</Application.Resources>
9+
</Application>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Configuration;
2+
using System.Data;
3+
using System.Windows;
4+
5+
namespace SfChartMultipleTrackball
6+
{
7+
/// <summary>
8+
/// Interaction logic for App.xaml
9+
/// </summary>
10+
public partial class App : Application
11+
{
12+
}
13+
14+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
using System.Windows;
2+
3+
[assembly: ThemeInfo(
4+
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
5+
//(used if a resource is not found in the page,
6+
// or application resource dictionaries)
7+
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
8+
//(used if a resource is not found in the page,
9+
// app, or any theme specific resource dictionaries)
10+
)]
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<Window x:Class="SfChartMultipleTrackball.MainWindow"
2+
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3+
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4+
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5+
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
6+
xmlns:local="clr-namespace:SfChartMultipleTrackball"
7+
mc:Ignorable="d"
8+
Title="MainWindow" Height="450" Width="800"
9+
xmlns:chart="clr-namespace:Syncfusion.UI.Xaml.Charts;assembly=Syncfusion.SfChart.WPF">
10+
11+
<Grid>
12+
13+
<chart:SfChart x:Name="chart" Header="Server CPU load by Day">
14+
15+
<chart:SfChart.PrimaryAxis>
16+
<chart:CategoryAxis ShowTrackBallInfo="True"/>
17+
</chart:SfChart.PrimaryAxis>
18+
19+
<chart:SfChart.SecondaryAxis>
20+
<chart:NumericalAxis ShowTrackBallInfo="True" Minimum="0" Maximum="100"/>
21+
</chart:SfChart.SecondaryAxis>
22+
23+
<chart:SfChart.Resources>
24+
<Style TargetType="chart:ChartTrackBallControl" x:Key="trackballStyle1">
25+
<Setter Property="Background" Value="GreenYellow"/>
26+
<Setter Property="Height" Value="10"/>
27+
<Setter Property="Width" Value="10"/>
28+
</Style>
29+
<Style TargetType="Line" x:Key="lineStyle1">
30+
<Setter Property="Stroke" Value="Black"/>
31+
<Setter Property="StrokeThickness" Value="1.5"/>
32+
</Style>
33+
34+
<Style TargetType="chart:ChartTrackBallControl" x:Key="trackballStyle2">
35+
<Setter Property="Background" Value="Orange"/>
36+
<Setter Property="Height" Value="10"/>
37+
<Setter Property="Width" Value="10"/>
38+
</Style>
39+
<Style TargetType="Line" x:Key="lineStyle2">
40+
<Setter Property="Stroke" Value="Black"/>
41+
<Setter Property="StrokeThickness" Value="1.5"/>
42+
</Style>
43+
</chart:SfChart.Resources>
44+
45+
<chart:SfChart.Behaviors>
46+
<local:ChartTrackBallBehaviorExt x:Name="trackball1" ChartTrackBallStyle="{StaticResource trackballStyle1}" UseSeriesPalette="True" LineStyle="{StaticResource lineStyle1}"/>
47+
<local:ChartTrackBallBehaviorExt x:Name="trackball2" ChartTrackBallStyle="{StaticResource trackballStyle2}" UseSeriesPalette="True" LineStyle="{StaticResource lineStyle2}"/>
48+
</chart:SfChart.Behaviors>
49+
50+
<chart:LineSeries ItemsSource="{Binding Data}" XBindingPath="Day" YBindingPath="CPULoad" StrokeThickness="3" Interior="OrangeRed">
51+
<chart:LineSeries.AdornmentsInfo>
52+
<chart:ChartAdornmentInfo Symbol="Ellipse" SymbolInterior="White" SymbolStroke="OrangeRed"/>
53+
</chart:LineSeries.AdornmentsInfo>
54+
</chart:LineSeries>
55+
56+
</chart:SfChart>
57+
58+
</Grid>
59+
60+
<Window.DataContext>
61+
<local:ViewModel/>
62+
</Window.DataContext>
63+
64+
</Window>
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
using Syncfusion.UI.Xaml.Charts;
2+
using System.Reflection;
3+
using System.Windows;
4+
using System.Windows.Input;
5+
6+
namespace SfChartMultipleTrackball
7+
{
8+
/// <summary>
9+
/// Interaction logic for MainWindow.xaml
10+
/// </summary>
11+
public partial class MainWindow : Window
12+
{
13+
public MainWindow()
14+
{
15+
InitializeComponent();
16+
trackball1.SfChart = this.chart;
17+
trackball2.SfChart = this.chart;
18+
}
19+
20+
protected override void OnContentRendered(EventArgs e)
21+
{
22+
base.OnContentRendered(e);
23+
24+
// Run the ShowTrackball method asynchronously
25+
Task.Run(async () =>
26+
{
27+
await ShowTrackball();
28+
});
29+
}
30+
31+
async Task ShowTrackball()
32+
{
33+
// Wait for 1 second before executing the rest of the method
34+
await Task.Delay(1000);
35+
Application.Current.Dispatcher.Invoke(() =>
36+
{
37+
// Calculated positions for the first trackball
38+
float xPosition = (float)chart.ValueToPoint(chart.PrimaryAxis, 1);
39+
float yPosition = (float)chart.ValueToPoint(chart.SecondaryAxis, 169);
40+
41+
// Calculated positions for the second trackball
42+
float xPosition1 = (float)chart.ValueToPoint(chart.PrimaryAxis, 6);
43+
float yPosition1 = (float)chart.ValueToPoint(chart.SecondaryAxis, 170);
44+
45+
// Display the first trackball
46+
trackball1.Display(xPosition, yPosition);
47+
48+
// Display the second trackball
49+
trackball2.Display(xPosition1, yPosition1);
50+
});
51+
}
52+
}
53+
54+
public class Model
55+
{
56+
public string Day { get; set; }
57+
public double CPULoad { get; set; }
58+
}
59+
60+
public class ViewModel
61+
{
62+
public List<Model> Data { get; set; }
63+
64+
public ViewModel()
65+
{
66+
Data = new List<Model>
67+
{
68+
new Model { Day = "Monday", CPULoad = 35 },
69+
new Model { Day = "Tuesday", CPULoad = 42 },
70+
new Model { Day = "Wednesday", CPULoad = 18 },
71+
new Model { Day = "Thursday", CPULoad = 30 },
72+
new Model { Day = "Friday", CPULoad = 64 },
73+
new Model { Day = "Saturday", CPULoad = 22 },
74+
new Model { Day = "Sunday", CPULoad = 10 }
75+
};
76+
}
77+
}
78+
79+
public class ChartTrackBallBehaviorExt : ChartTrackBallBehavior
80+
{
81+
private bool isTrackballActive = false;
82+
83+
public SfChart SfChart { get; set; }
84+
85+
public double X { get; set; }
86+
public double Y { get; set; }
87+
88+
protected override void OnMouseEnter(MouseEventArgs e)
89+
{
90+
// Get the position of the mouse pointer
91+
var touchPoint = e.GetPosition(null);
92+
93+
// Find the nearest trackball to the mouse pointer
94+
var trackball = FindNearestTrackball(touchPoint);
95+
96+
// Activate the trackball if it is the nearest one
97+
if (trackball == this)
98+
{
99+
isTrackballActive = true;
100+
base.OnMouseEnter(e);
101+
}
102+
}
103+
104+
protected override void OnMouseMove(MouseEventArgs e)
105+
{
106+
// Check if the trackball is activated
107+
if (isTrackballActive)
108+
{
109+
// Get the position of the mouse pointer
110+
var touchPoint = e.GetPosition(null);
111+
112+
// Display the trackball at the current mouse position
113+
Display((float)touchPoint.X, (float)touchPoint.Y);
114+
base.OnMouseMove(e);
115+
}
116+
}
117+
118+
protected override void OnMouseLeave(MouseEventArgs e)
119+
{
120+
// Deactivate the trackball
121+
isTrackballActive = false;
122+
}
123+
124+
private ChartTrackBallBehavior FindNearestTrackball(Point touchPoint)
125+
{
126+
ChartTrackBallBehavior nearestTrackball = null;
127+
double minDistance = double.MaxValue;
128+
129+
// Iterate through all trackball behaviors to find the nearest one
130+
foreach (var trackballBehaviour in SfChart.Behaviors)
131+
{
132+
if (trackballBehaviour is ChartTrackBallBehaviorExt trackball)
133+
{
134+
// Calculate the distance between the trackball and the touch point
135+
double distance = Math.Sqrt(Math.Pow(trackball.X - touchPoint.X, 2) + Math.Pow(trackball.Y - touchPoint.Y, 2));
136+
137+
// Update the nearest trackball if the current one is closer
138+
if (distance < minDistance)
139+
{
140+
minDistance = distance;
141+
nearestTrackball = trackball;
142+
}
143+
}
144+
}
145+
146+
return nearestTrackball;
147+
}
148+
149+
public void Display(float x, float y)
150+
{
151+
X = x; Y = y;
152+
IsActivated = true;
153+
var point = new Point(x, y);
154+
155+
// Set the internal property for the current point
156+
SetInternalProperty(typeof(ChartTrackBallBehavior), this, point, "CurrentPoint");
157+
158+
// Trigger the pointer position changed event
159+
base.OnPointerPositionChanged();
160+
161+
// Activate the trackball
162+
InvokeInternalMethod(typeof(ChartTrackBallBehavior), this, "Activate", IsActivated);
163+
}
164+
165+
// Sets an internal property of an object using reflection.
166+
internal static void SetInternalProperty(Type type, object obj, object value, string propertyName)
167+
{
168+
var properties = type.GetRuntimeProperties();
169+
170+
foreach (var item in properties)
171+
{
172+
if (item.Name == propertyName)
173+
{
174+
item.SetValue(obj, value);
175+
break;
176+
}
177+
}
178+
}
179+
180+
// Invokes an internal method of an object using reflection.
181+
internal static object? InvokeInternalMethod(Type type, object obj, string methodName, params object[] args)
182+
{
183+
var method = type.GetTypeInfo().GetDeclaredMethod(methodName);
184+
return method?.Invoke(obj, args);
185+
}
186+
}
187+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using System.Text;
5+
using System.Threading.Tasks;
6+
7+
namespace SfChartMultipleTrackball
8+
{
9+
public class Model
10+
{
11+
public string? Day { get; set; }
12+
public double CPULoad { get; set; }
13+
}
14+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>WinExe</OutputType>
5+
<TargetFramework>net8.0-windows</TargetFramework>
6+
<Nullable>enable</Nullable>
7+
<ImplicitUsings>enable</ImplicitUsings>
8+
<UseWPF>true</UseWPF>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<PackageReference Include="Syncfusion.SfChart.WPF" Version="*" />
13+
</ItemGroup>
14+
15+
</Project>
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+
<Project ToolsVersion="Current" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
3+
<PropertyGroup />
4+
<ItemGroup>
5+
<ApplicationDefinition Update="App.xaml">
6+
<SubType>Designer</SubType>
7+
</ApplicationDefinition>
8+
</ItemGroup>
9+
<ItemGroup>
10+
<Page Update="MainWindow.xaml">
11+
<SubType>Designer</SubType>
12+
</Page>
13+
</ItemGroup>
14+
</Project>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
namespace SfChartMultipleTrackball
2+
{
3+
public class ViewModel
4+
{
5+
public List<Model> Data { get; set; }
6+
7+
public ViewModel()
8+
{
9+
Data = new List<Model>
10+
{
11+
new Model { Day = "Monday", CPULoad = 35 },
12+
new Model { Day = "Tuesday", CPULoad = 42 },
13+
new Model { Day = "Wednesday", CPULoad = 18 },
14+
new Model { Day = "Thursday", CPULoad = 30 },
15+
new Model { Day = "Friday", CPULoad = 64 },
16+
new Model { Day = "Saturday", CPULoad = 22 },
17+
new Model { Day = "Sunday", CPULoad = 10 }
18+
};
19+
}
20+
}
21+
}

0 commit comments

Comments
 (0)