- Home
- Forum
- Xamarin.Forms
- Violin Plot using SfChart
Violin Plot using SfChart
I have a requirement to plot a chart as shown in the attachment. I saw a Syncfusion kb for Violin Plot for WPF. May I know how to achieve the attached design (Violin Plot) in Xamarin Forms using SfChart?
Attachment: felt_valued_rating__01.png_e3df2ba5.zip
SIGN IN To post a reply.
4 Replies
YP
Yuvaraj Palanisamy
Syncfusion Team
August 27, 2021 03:44 PM UTC
Hi Joseph Cellucci,
Greetings from Syncfusion.
This is a general update to let you know that our support team has taken out your query and they are starting to work on it. We will share the possible workaround solution on or before 31st August 2021.We appreciate your patience until then.
Regards,
Yuvaraj.
YP
Yuvaraj Palanisamy
Syncfusion Team
September 1, 2021 02:15 PM UTC
Hi Joesph Cellucci,
Thanks for your patience.
We have achieved your requirement “Violin chart in Xamarin.Forms” by workaround with the help of CustomRenderer in the platform specific project. Please find the code example below.
CodeSnippet:
|
<local:ChartExt ">
<chart:BoxAndWhiskerSeries ItemsSource="{Binding BoxWhiskerData}"
XBindingPath="Department" ShowOutlier="False"
YBindingPath="Age" Width="0.2"
BoxPlotMode="Normal"/>
</local:ChartExt> |
Android project [CustomRenderer.cs]
|
public class CustomChart : SfChartExt
{
public CustomChart(Android.Content.Context context) : base(context)
{
}
protected override Com.Syncfusion.Charts.ChartSeries CreateNativeChartSeries(Syncfusion.SfChart.XForms.ChartSeries formSeries)
{
if (formSeries is Syncfusion.SfChart.XForms.BoxAndWhiskerSeries)
{
return new CustomBoxAndWhiskerSeries();
}
return base.CreateNativeChartSeries(formSeries);
}
}
public class CustomBoxAndWhiskerSeries : Native.BoxAndWhiskerSeries
{
protected override Native.ChartSegment CreateSegment()
{
CustomBoxAndWhiskerSegment segment = new CustomBoxAndWhiskerSegment();
SetInternalProperty(typeof(Native.BoxAndWhiskerSegment), segment, "Series", this);
return segment;
}
}
public class CustomBoxAndWhiskerSegment : Native.BoxAndWhiskerSegment
{
Paint paint = new Paint();
public override void OnDraw(Canvas canvas)
{
base.OnDraw(canvas);
BoxAndWhiskerSegment baseSegment = this as BoxAndWhiskerSegment;
float Left = (float)GetInternalProperty("Left", baseSegment);
float Right = (float)GetInternalProperty("Right", baseSegment);
float Top = (float)GetInternalProperty("Top", baseSegment);
float Bottom = (float)GetInternalProperty("Bottom", baseSegment);
PointF Center = (PointF)GetInternalProperty("AveragePoint", baseSegment);
PointF minimumPoint = (PointF)GetInternalProperty("MinimumPoint", baseSegment);
PointF medianPoint = (PointF)GetInternalProperty("MedianPoint", baseSegment);
PointF maximumPoint = (PointF)GetInternalProperty("MaximumPoint", baseSegment);
var tlPoint = new PointF((int)Left, (int)Top);
var brPoint = new PointF((int)Right, (int)Bottom);
var centre = tlPoint.X + (brPoint.X - tlPoint.X) / 2;
var rect = new Rect((float)(centre - 2.5), tlPoint.Y, (float)(centre + 2.5), brPoint.Y);
var centerLinePosition = rect.Left + rect.Width() / 2;
float extensionValue = 25;
paint.StrokeWidth = 2;
paint.Color = Android.Graphics.Color.Blue;
paint.SetStyle(Paint.Style.Stroke);
Path path = new Path();
path.MoveTo(centerLinePosition, minimumPoint.Y + (extensionValue * 2));
path.QuadTo( tlPoint.X + (centerLinePosition - tlPoint.X) / 2 - extensionValue, brPoint.Y + (minimumPoint.Y - brPoint.Y) / 2, tlPoint.X - (extensionValue * 2), brPoint.Y);
path.QuadTo(tlPoint.X , tlPoint.Y + (brPoint.Y - tlPoint.Y) / 2, tlPoint.X - (extensionValue * 2), tlPoint.Y);
path.QuadTo(centerLinePosition - (centerLinePosition - tlPoint.X)/2 - extensionValue, maximumPoint.Y + (tlPoint.Y - maximumPoint.Y)/2, centerLinePosition, maximumPoint.Y - (extensionValue * 2));
path.QuadTo(centerLinePosition + (brPoint.X - centerLinePosition) / 2 + extensionValue, maximumPoint.Y + (tlPoint.Y - maximumPoint.Y) / 2, brPoint.X + (extensionValue * 2), tlPoint.Y );
path.QuadTo(centerLinePosition + (centerLinePosition - tlPoint.X) / 2, tlPoint.Y + (brPoint.Y - tlPoint.Y) / 2, brPoint.X + (extensionValue * 2), brPoint.Y);
path.QuadTo(brPoint.X + (centerLinePosition - tlPoint.X) / 2 + extensionValue, brPoint.Y, centerLinePosition, minimumPoint.Y + (extensionValue * 2));
canvas.DrawPath(path, paint);
}
public static object GetInternalProperty(string property, object src)
{
return src.GetType().GetProperty(property, System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).
GetValue(src);
}
}
|
Also, we have attached the sample for your reference. Please find the sampel from the below link.
Output:
Regards,
Yuvaraj.Hi,
I have tried using the provided code to obtain violin plot. I have attached a zip file containing the actual violin plot and the violin plot obtained using code. I have modified the code provided (solution attached) with values used for plotting the actual violin plot. Please take a look at the Actual Violin plot attached and revert if it is achievable.
Attachment: ViolinChart_4a66d89f.zip
YP
Yuvaraj Palanisamy
Syncfusion Team
September 3, 2021 05:18 PM UTC
Hi Joseph Cellucci,
We have provided the solution with custom drawing in each platform specific based on the BoxAndWhiskerSeries datapoint. You can customize the drawing based on your requirement in the OnDraw method of CustomSegment class as we provided the workaround sample in the kast update.
Also, you can achieve this by custom view with the help of DataMarker LabelTemplate support in Xamarin.Forms SfChart and you can customize the each datapoint by using DataMarkerLabelCreated event of ChartSeries.
Also, could you please share us the datapoint plots about the custom drawing in your use case scenario which will be helpful to serve you better solution.
For more details, please refer the below link.
Regards,
Yuvaraj.
SIGN IN To post a reply.
- 4 Replies
- 2 Participants
-
JC Joseph Cellucci
- Aug 26, 2021 08:02 AM UTC
- Sep 3, 2021 05:18 PM UTC