How to create the neumorphic ui chart using .NET MAUI Chart (SfCartesianChart)?
This article delves into the creation of visually stunning Neumorphism UI charts using Syncfusion® .NET MAUI Column Chart. Follow this step-by-step tutorial that utilizes a custom class inheriting from IDrawable and Graphics view. This approach ensures a seamless integration of design and data representation within your application.
Step 1: Implementing SfShadowDrawer Class
The SfShadowDrawer
class is a base class that implements the IDrawable
interface. It serves as a foundation for creating drawable elements with shadow effects. This class provides properties and methods to control shadow properties, such as offset, blur, color, and opacity.
Step 2: Implement a Method to Draw and Apply Shadow
Implement the Draw
method for the IDrawable
interface in the custom SfShadowDrawer class. This method is responsible for drawing the shadow by applying the shadow effect and filling the rounded rectangle. Applies the shadow effect to the canvas based on the provided parameters.
[SfShadowDrawer]
public void Draw(ICanvas canvas, RectF dirtyRect)
{
double radius = CornerRadius > dirtyRect.Width / 2 ? dirtyRect.Width / 2 : CornerRadius;
canvas.SaveState();
canvas.ClipPath(GetDrawPath(dirtyRect, (float)radius));
DrawShadow(canvas, dirtyRect);
canvas.RestoreState();
}
internal void ApplyShadow(ICanvas canvas, RectF dirtyRect, SizeF offset, Color shadowColor, float opacity, double cornerRadius)
{
canvas.SaveState();
canvas.FillColor = BackgroundColor;
canvas.SetShadow(offset, Blur, shadowColor.WithAlpha(opacity));
canvas.FillRoundedRectangle(dirtyRect, cornerRadius);
canvas.RestoreState();
}
Step 3: Implementing SfNeumorphismDrawer Class
The SfNeumorphismDrawer
class is a custom drawable class that extends SfShadowDrawer
. It is specifically designed for creating a neumorphic (soft shadow) effect in user interfaces. This class provides properties and methods to control various aspects of the neumorphic shadow, such as color, offset, and opacity.
It overrides the DrawShadow
method from the base class SfShadowDrawer
to implement the neumorphic shadow drawing logic. The shadow is drawn based on the pressed state, adjusting the offset and shadow positions accordingly.
[SfNeumorphismDrawer]
protected override void DrawShadow(ICanvas canvas, RectF dirtyRect)
{
if (IsPressedState)
{
double radius = CornerRadius > dirtyRect.Width / 2 ? dirtyRect.Width / 2 : CornerRadius;
if (dirtyRect.Width / 3 < radius)
{
ApplyShadow(canvas, new RectF(dirtyRect.Left, dirtyRect.Top, -dirtyRect.Width, dirtyRect.Height), Offset, ShadowColor, Opacity, radius);
ApplyShadow(canvas, new RectF(dirtyRect.Right, dirtyRect.Top, dirtyRect.Width, dirtyRect.Height), LightOffSet, lightShadowColor, LightOpacity, radius);
}
else
{
ApplyShadow(canvas, new RectF(dirtyRect.Left, dirtyRect.Top, -dirtyRect.Width, dirtyRect.Height), Offset, ShadowColor, Opacity, radius);
ApplyShadow(canvas, new RectF(dirtyRect.Left - 10, dirtyRect.Top, dirtyRect.Width + 10, -dirtyRect.Height), Offset, ShadowColor, Opacity, radius);
ApplyShadow(canvas, new RectF(dirtyRect.Right, dirtyRect.Top, dirtyRect.Width, dirtyRect.Height), LightOffSet, lightShadowColor, LightOpacity, radius);
ApplyShadow(canvas, new RectF(dirtyRect.Left, dirtyRect.Bottom, dirtyRect.Width, dirtyRect.Height), LightOffSet, lightShadowColor, LightOpacity, radius);
}
}
else
{
var paddingRect = new RectF() { Left = dirtyRect.Left + Padding, Top = dirtyRect.Top + Padding, Right = dirtyRect.Right - Padding, Bottom = dirtyRect.Bottom - Padding };
double radius = CornerRadius > paddingRect.Width / 2 ? paddingRect.Width / 2 : CornerRadius;
ApplyShadow(canvas, paddingRect, Offset, ShadowColor, Opacity, radius);
ApplyShadow(canvas, paddingRect, LightOffSet, lightShadowColor, LightOpacity, radius);
}
}
Step 4: Implementing a SfNeumorphismView Class
The SfNeumorphismView
class extends ContentView
and provides a container for displaying a neumorphic (soft shadow) effect. It includes a Grid
and a GraphicsView
for rendering the neumorphic shadow based on the provided SfNeumorphismDrawer
. Additionally, it exposes properties and methods to manage the drawable content and handle property changes.
[SfNeumorphismView]
public SfNeumorphismView()
{
Drawable = new SfNeumorphismDrawer();
grid = new Grid();
grid.Margin = new Thickness(0);
graphicsView = new GraphicsView();
graphicsView.Margin = new Thickness(0);
graphicsView.BackgroundColor = Colors.Transparent;
graphicsView.SetBinding(GraphicsView.DrawableProperty, new Binding() { Path = nameof(Drawable), Source = this });
grid.Children.Add(graphicsView);
base.Content = grid;
}
Step 5: Implementing the SfNeumorphismColumnSeries and SfNeumorphismColumnSegment Classes
The SfNeumorphismColumnSeries
class is a custom implementation of the ColumnSeries
in Syncfusion.Maui.Charts library. It introduces a neumorphic (soft shadow) effect to column series by associating an SfNeumorphismDrawer
with each column segment.
This class overrides the CreateSegment
method to create a custom SfNeumorphismColumnSegment
instead of the default ColumnSegment
. Associates the Drawable
property with the newly created segment.
[SfNeumorphismColumnSeries]
public class SfNeumorphismColumnSeries : ColumnSeries
{
protected override ChartSegment CreateSegment()
{
return new SfNeumorphismColumnSegment(Drawable);
}
}
The SfNeumorphismColumnSegment
class is a custom implementation of the ColumnSegment
in Syncfusion.Maui.Charts library. It enhances the default column segment by incorporating a neumorphic shadow effect using the associated SfNeumorphismDrawer
.
It overrides the base method to implement custom drawing logic. Draws the neumorphic shadow using the SfNeumorphismDrawer
associated with the segment.
[SfNeumorphismColumnSegment]
public class SfNeumorphismColumnSegment : ColumnSegment
{
protected override void Draw(ICanvas canvas)
{
if (Series is ColumnSeries series && series.ActualYAxis is NumericalAxis yAxis)
{
var top = yAxis.ValueToPoint(Convert.ToDouble(yAxis.Maximum ?? double.NaN));
var trackRect = new RectF() { Left = Left, Top = top, Right = Right, Bottom = Bottom };
Drawable.Draw(canvas, trackRect);
}
}
}
Step 6: Define and Apply styles for the Neumorphic Drawer
Defines styles for neumorphic drawers with varying configurations, such as outer view, normal, and pressed states. These styles are then referenced throughout the UI for consistent appearance.
[XAML]
<ContentPage.Resources>
<control:SfNeumorphismDrawer BackgroundColor="#F5F5F5" Padding="20" LightOpacity="0.8" CornerRadius="20" x:Key="outerViewDrawable">
</control:SfNeumorphismDrawer>
<control:SfNeumorphismDrawer BackgroundColor="#F5F5F5" Padding="8" LightOpacity="1" Offset="3,3" LightOffSet="-4,-4" CornerRadius="{OnPlatform Android='8',iOS='8',WinUI='10',MacCatalyst='10'}" x:Key="drawable"/>
<control:SfNeumorphismDrawer Blur="40" IsPressedState="True" Opacity="0.3" LightOpacity="1" CornerRadius="20" BackgroundColor="#F5F5F5" x:Key="pressedDrawable" />
</ContentPage.Resources>
[XAML]
<control:SfNeumorphismView Drawable="{StaticResource outerViewDrawable}">
<chart:SfCartesianChart>
<chart:SfCartesianChart.Series>
<control:SfNeumorphismColumnSeries Drawable="{StaticResource pressedDrawable}">
</control:SfNeumorphismColumnSeries>
</chart:SfCartesianChart.Series>
</chart:SfCartesianChart>
</control:SfNeumorphismView>
After applying the styles for the content and the series, the chart will look like below.
Here applied the ItemsSource to the series and Title for the chart.
[XAML]
<control:SfNeumorphismView Drawable="{StaticResource outerViewDrawable}">
<chart:SfCartesianChart>
<chart:SfCartesianChart.Title>
<HorizontalStackLayout HorizontalOptions="Start">
</control:SfNeumorphismView>
<VerticalStackLayout Margin="10,0,0,0">
<Label Text="Year 2020"/>
<Label Text="Yearly spending"/>
</VerticalStackLayout>
</HorizontalStackLayout>
</chart:SfCartesianChart.Title>
<chart:SfCartesianChart.Series>
<control:SfNeumorphismColumnSeries Drawable="{StaticResource pressedDrawable}" ItemsSource="{Binding NeumorphismColumnData}" XBindingPath="Month" YBindingPath="Value">
</control:SfNeumorphismColumnSeries>
</chart:SfCartesianChart.Series>
</chart:SfCartesianChart>
</control:SfNeumorphismView>
Applied the styles for the Title.
[XAML]
<control:SfNeumorphismView Drawable="{StaticResource outerViewDrawable}">
<chart:SfCartesianChart>
<chart:SfCartesianChart.Title>
<HorizontalStackLayout HorizontalOptions="Start">
<control:SfNeumorphismView
HeightRequest="{OnPlatform Android='50',iOS='50',Default='65'}"
WidthRequest="{OnPlatform Android='50',iOS='50',Default='65'}"
HorizontalOptions="Start"
Drawable="{StaticResource drawable}">
<Path Data="M6.5 0A1.5 1.5 0 0 0 5 1.5v1A1.5 1.5 0 0 0 6.5 4h3A1.5 1.5 0 0 0 11 2.5v-1A1.5 1.5 0 0 0 9.5
0h-3Zm3 1a.5.5 0 0 1 .5.5v1a.5.5 0 0 1-.5.5h-3a.5.5 0 0 1-.5-.5v-1a.5.5 0 0 1 .5-.5h3Z M4 1.5H3a2 2
0 0 0-2 2V14a2 2 0 0 0 2 2h10a2 2 0 0 0 2-2V3.5a2 2 0 0 0-2-2h-1v1A2.5 2.5 0 0 1 9.5 5h-3A2.5 2.5 0
0 1 4 2.5v-1ZM10 8a1 1 0 1 1 2 0v5a1 1 0 1 1-2 0V8Zm-6 4a1 1 0 1 1 2 0v1a1 1 0 1 1-2 0v-1Zm4-3a1 1 0 0 1 1 1v3a1 1 0 1 1-2 0v-3a1 1 0 0 1 1-1Z"
Fill="#6e8aa6" Aspect="Fill"
HorizontalOptions="Center" VerticalOptions="Center"
HeightRequest="{OnPlatform Android='20',iOS='20', Default='30'}"
WidthRequest="{OnPlatform Android='20',iOS='20',Default='30'}" />
</control:SfNeumorphismView>
<VerticalStackLayout Margin="10,0,0,0">
<Label Text="Year 2020" FontSize="{OnPlatform Android='12',iOS='12',WinUI='15',MacCatalyst='15'}"
FontFamily="Times" FontAttributes="Bold" TextColor="#8b9eb0" Margin="{OnPlatform Android='0,10,0,3',iOS='0,10,0,3',WinUI='0,15,0,3',MacCatalyst='0,15,0,3'}"/>
<Label Text="Yearly spending" FontFamily="Times" FontSize="{OnPlatform Android='9',iOS='9',WinUI='12',MacCatalyst='12'}" TextColor="#8b9eb0"/>
</VerticalStackLayout>
</HorizontalStackLayout>
</chart:SfCartesianChart.Title>
</chart:SfCartesianChart>
</control:SfNeumorphismView>
Here is the final output of the Syncfusion® .NET MAUI Neumorphic Column Chart.
Download the complete sample from GitHub.
Conclusion
I hope you enjoyed learning how to create the visually stunning neumorphic UI chart using Syncfusion® .NET MAUI Chart(SfCartesianChart).
You can refer to our .NET MAUI Chart feature tour page to learn about its other groundbreaking feature representations. Explore our .NET MAUI Chart documentation to understand how to present and manipulate data.
For current customers, check out our .NET MAUI from the License and Downloads page. If you are new to Syncfusion®, try our 30-day free trial to check out our .NET MAUI Chart and other .NET MAUI components.
Please let us know in the comments section if you have any queries or require clarification. You can also contact us through our support forums, Direct-Trac, or feedback portal. We are always happy to assist you!