wpf-Custom radar Diagram (i)

Source: Internet
Author: User
Tags cos sin radar

1, create a UserControl, called "Radarchartcontrol"

Front desk:

<usercontrol x:class= "Wpfapplication4.radarchartcontrol"
Xmlns= "Http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x= "Http://schemas.microsoft.com/winfx/2006/xaml"
Xmlns:mc= "http://schemas.openxmlformats.org/markup-compatibility/2006"
Xmlns:d= "http://schemas.microsoft.com/expression/blend/2008"
Mc:ignorable= "D"
d:designheight= "d:designwidth=" loaded= "radarchartcontrol_onloaded" >
<canvas x:name= "Canvaspanel" horizontalalignment= "center" verticalalignment= "Center" >
</Canvas>
</UserControl>

Background:

<summary>
The interactive logic of Radarchartcontrol.xaml
</summary>
public partial class Radarchartcontrol:usercontrol
{
Public Radarchartcontrol ()
{
InitializeComponent ();
}
#region Properties
<summary>
Size size
Aspect the same size.
</summary>
Public double Size
{
get {return (double) GetValue (Sizeproperty);}
set {SetValue (Sizeproperty,value);}
}

public static readonly DependencyProperty Sizeproperty = Dependencyproperty.register ("Size", typeof (Double),
typeof (Radarchartcontrol), New PropertyMetadata (200.0));
<summary>
Title
</summary>
Public list<argumentmodel> Arguments
{
get {return (list<argumentmodel>) GetValue (argumentsproperty);}
set {SetValue (Argumentsproperty,value);}
}

public static readonly DependencyProperty Argumentsproperty = Dependencyproperty.register ("Arguments", typeof (List <ArgumentModel>),
typeof (Radarchartcontrol), New PropertyMetadata (New List<argumentmodel> ()));
<summary>
Data
</summary>
Public list<chartitem> Datas
{
get {return (list<chartitem>) GetValue (datasproperty);}
set {SetValue (Datasproperty, value);}
}

public static readonly DependencyProperty Datasproperty = Dependencyproperty.register ("Datas", typeof (list< chartitem>),
typeof (Radarchartcontrol), New PropertyMetadata (New List<chartitem> ()));
<summary>
Gets or sets the line color
</summary>
Public Brush BorderBrush
{
get {return (Brush) GetValue (borderbrushproperty);}
set {SetValue (Borderbrushproperty, value);}
}

public static readonly DependencyProperty Borderbrushproperty = Dependencyproperty.register ("BorderBrush", typeof ( Brush),
typeof (Radarchartcontrol), New PropertyMetadata (Brushes.royalblue));
<summary>
Connection point Size
</summary>
public int ellipsesize = 7;
<summary>
Control size
</summary>
Public double TotalSize
{
Get
{
Double size = size + 200;
return size;
}
}
<summary>
Panel
</summary>
Public Canvas chartcanvas=new canvas ();

Declaring and registering routed events
public static readonly RoutedEvent titleclickroutedevent =
Eventmanager.registerroutedevent ("Titleclick", Routingstrategy.bubble, typeof (Eventhandler<routedeventargs >), typeof (Radarchartcontrol));
CLR Event Wrapper
Public event Routedeventhandler Titleclick
{
Add {this. AddHandler (titleclickroutedevent, value); }
Remove {this. RemoveHandler (titleclickroutedevent, value); }
}
Fires a routed event, borrowing the Click event's Firing method
protected void OnClick (object sender, RoutedEventArgs e)
{
RoutedEventArgs args = new RoutedEventArgs (Titleclickroutedevent, E);
This. RaiseEvent (args);
}
#endregion

private void Radarchartcontrol_onloaded (object sender, RoutedEventArgs e)
{
if (! Checkdata ())
{
throw new Exception ("Radarchart data mismatch! reconfigure!");
}
Get maximum Value
int maxData = Datas.max (i = I.datalist.max (o = o.data));
Setting up panels and backgrounds
Setcanvasandbackground (MaxData);
Set data title
Setdatatitle (Datas);
Get Half Circle size
Double length = SIZE/2/maxData;
Connection point Radius
int ellipser = ELLIPSESIZE/2;
foreach (Var chartitem in Datas)
{
var color = Chartitem.color;

Two polygons, one setting background, one setting border
Polygon Polygonarea = new Polygon () {Fill = color, Opacity = 0.2, strokethickness = 0};
Polygon Polygonborder = new Polygon () {Fill = brushes.transparent, Stroke = color, strokethickness = 0.8};

int index = 0;
foreach (var data in chartitem.datalist)
{
Double currentangle = Angle * index + 90;
Double angle = (currentangle/360) * 2 * MATH.PI;
var r = data. Data * length;
Double x = size/2 + R * Math.Cos (angle);
Double y = size/2-R * Math.sin (angle);
Polygon Add node
var point = new Point ()
{
x = x,
y = y
};
POLYGONAREA.POINTS.ADD (point);
POLYGONBORDER.POINTS.ADD (point);
Set node style
var ellipse = new Ellipse () {Width = ellipsesize, Height = ellipsesize, Fill = color};
Canvas.setleft (ellipse, x-ellipser);
Canvas.settop (ellipse, y-ellipser);
CHARTCANVAS.CHILDREN.ADD (ellipse);

index++;
}
ChartCanvas.Children.Add (Polygonarea);
CHARTCANVAS.CHILDREN.ADD (Polygonborder);
}
//Set caption
Setarguments ();
}
//<summary>
//Set data title
//</summary>
//<param name= "Datas" ></PARAM>
private void Setdatatitle (list<chartitem> datas)
{
Radarcharttitlelist titlelist=new Radarcharttitlelist ();
Titlelist.itemsoure = datas;
Double angle = math.pi*0.25;
Double x = totalsize/2 + (TOTALSIZE/2) *math.sin (angle);
Canvas.setleft (titlelist,x);
Canvas.settop (titlelist, x);
CanvasPanel.Children.Add (titlelist);
}

<summary>
Set Title
</summary>
private void Setarguments ()
{
int index = 0;
foreach (var argument in Arguments)
{
var button = new Chartbutton ();
button. Content = argument. Name;
button. Icon = argument. Iconsource;
button. Mybutton.click + = OnClick;
Draw XY
Double currentangle = Angle * index + 90;
Double angle = (currentangle/360) * 2 * MATH.PI;
var r = TOTALSIZE/2;
Double x = R + R * Math.Cos (angle)-(button. WIDTH/2);
Double y = r-r * Math.sin (angle)-(button. HEIGHT/2);

Add a button height difference
y = y + math.sin (angle) * (button. WIDTH/2-button. HEIGHT/2);

Canvas.setleft (button, x);
Canvas.settop (button, y);

CANVASPANEL.CHILDREN.ADD (button);
index++;
}
}

<summary>
Check Data
</summary>
<returns></returns>
private bool Checkdata ()
{
if (datas==null)
{
return false;
}

foreach (var data in Datas)
{
BOOL result =! Datas.any (i = i.datalist.count! = data. Datalist.count);
if (!result)
{
return false;
}
}
return true;
}

<summary>
Setting up panels and backgrounds
</summary>
<param name= "Maxindex" ></param>
private void Setcanvasandbackground (int maxindex)
{
Canvaspanel.height = totalsize;
Canvaspanel.width = totalsize;

//panel
Chartcanvas.height = Size;
Chartcanvas.width = Size;
Double canvasx = (totalsize-size)/2;
Canvas.setleft (Chartcanvas, canvasx);
Canvas.settop (Chartcanvas, canvasx);
CanvasPanel.Children.Add (Chartcanvas);
//Circle and line
var color = borderbrush;
Double length = Size/2/maxindex;
for (int i = 0; i < Maxindex; i++) {
Double height = length*2* (i + 1);
Double left = size/2-Length * (i + 1);
var ellipse = new Ellipse () {Stroke = color, strokethickness = 0.5, height = height, Width = height};
Canvas.setleft (ellipse, left);
Canvas.settop (ellipse, left);

CHARTCANVAS.CHILDREN.ADD (ellipse);
}
Temporarily set: 4 headings, draw line
if (Arguments.count = = 4)
{
Vertical line
Path Verticalpath = new Path ()
{
Stroke = Color,
StrokeThickness = 0.2,
};
Add data
StreamGeometry geometry = new StreamGeometry ();
Geometry. FillRule = Fillrule.nonzero; Before the sound of F0 or F1, it's F1.
using (Streamgeometrycontext CTX = geometry. Open ())
{

CTx. BeginFigure (new Point (SIZE/2, 0), true, true);

CTx. LineTo (new Point (SIZE/2, Size), true, false);

}
Geometry. Freeze ();
Verticalpath.data = geometry;
CHARTCANVAS.CHILDREN.ADD (Verticalpath);
Horizontal line
Path Horizontalpath = new Path ()
{
Stroke = Color,
StrokeThickness = 0.2,
};
Add data
Geometry = new StreamGeometry ();
Geometry. FillRule = Fillrule.nonzero; Before the sound of F0 or F1, it's F1.
using (Streamgeometrycontext CTX = geometry. Open ())
{

CTx. BeginFigure (new Point (0,SIZE/2), true, true);

CTx. LineTo (new Point (SIZE,SIZE/2), true, false);

}
Geometry. Freeze ();
Horizontalpath.data = geometry;
CHARTCANVAS.CHILDREN.ADD (Horizontalpath);
}
}
<summary>
Separating angle
</summary>
Private Double Angle
{
Get
{
int count=arguments.count;
Double angle = 360/count;
return angle;
}
}
}
<summary>
Class title
</summary>
public class Argumentmodel
{
Public ImageSource Iconsource {get; set;}
public string Name {get; set;}
}
<summary>
Single set of data
</summary>
public class Chartitem
{
Public Brush Color {get; set;}
List<chartdata> datalist=new list<chartdata> ();

Public list<chartdata> DataList
{
get {return dataList;}
set {dataList = value;}
}

Public object Name {get; set;}
}
<summary>
Data
</summary>
public class ChartData
{
public string Name {get; set;}
public int Data {get; set;}
}

wpf-Custom radar Diagram (i)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.