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)