标签:dma series eal asp 记录组 next fill completed split
雷达图逻辑同玫瑰图差不多,不同的地方在于绘制雷达网络,也就是蜘蛛网这样的底图。
界面代码
后台代码
public partial class RadarControl : UserControl
{
public RadarControl()
{
InitializeComponent();
}
#region 属性
///
/// 数值区域填充色
///
public Brush AreaBrush
{
get { return (Brush)GetValue(AreaBrushProperty); }
set { SetValue(AreaBrushProperty, value); }
}
public static readonly DependencyProperty AreaBrushProperty = DependencyProperty.Register("AreaBrush", typeof(Brush),
typeof(RadarControl), new PropertyMetadata(Brushes.Black));
///
/// 数值区域点填充色
///
public Brush AreaPointBrush
{
get { return (Brush)GetValue(AreaPointBrushProperty); }
set { SetValue(AreaPointBrushProperty, value); }
}
public static readonly DependencyProperty AreaPointBrushProperty = DependencyProperty.Register("AreaPointBrush", typeof(Brush),
typeof(RadarControl), new PropertyMetadata(Brushes.Black));
///
/// 雷达网格线填充充色
///
public Brush RadarNetBrush
{
get { return (Brush)GetValue(RadarNetBrushProperty); }
set { SetValue(RadarNetBrushProperty, value); }
}
public static readonly DependencyProperty RadarNetBrushProperty = DependencyProperty.Register("RadarNetBrush", typeof(Brush),
typeof(RadarControl), new PropertyMetadata(Brushes.Black));
///
/// 雷达网格线宽度
///
public double RadarNetThickness
{
get { return (double)GetValue(RadarNetThicknessProperty); }
set { SetValue(RadarNetThicknessProperty, value); }
}
public static readonly DependencyProperty RadarNetThicknessProperty = DependencyProperty.Register("RadarNetThickness", typeof(double),
typeof(RadarControl), new PropertyMetadata(1.0));
///
/// 数值点高宽度,0为不显示
///
public double AreaPointSize
{
get { return (double)GetValue(AreaPointSizeProperty); }
set { SetValue(AreaPointSizeProperty, value); }
}
public static readonly DependencyProperty AreaPointSizeProperty = DependencyProperty.Register("AreaPointSize", typeof(double),
typeof(RadarControl), new PropertyMetadata(10.0));
///
/// 纬线数量
///
public int LatitudeCount
{
get { return (int)GetValue(LatitudeCountProperty); }
set { SetValue(LatitudeCountProperty, value); }
}
public static readonly DependencyProperty LatitudeCountProperty = DependencyProperty.Register("LatitudeCount", typeof(int),
typeof(RadarControl), new PropertyMetadata(5));
///
/// 网格图停靠间距
///
public int RadarNetMargin
{
get { return (int)GetValue(RadarNetMarginProperty); }
set { SetValue(RadarNetMarginProperty, value); }
}
public static readonly DependencyProperty RadarNetMarginProperty = DependencyProperty.Register("RadarNetMargin", typeof(int),
typeof(RadarControl), new PropertyMetadata(50));
///
/// 显示值标注
///
public bool ShowValuesLabel
{
get { return (bool)GetValue(ShowValuesLabelProperty); }
set { SetValue(ShowValuesLabelProperty, value); }
}
public static readonly DependencyProperty ShowValuesLabelProperty = DependencyProperty.Register("ShowValuesLabel", typeof(bool),
typeof(RadarControl), new PropertyMetadata(true));
///
/// 显示组标签
///
public bool ShowGroupsLabel
{
get { return (bool)GetValue(ShowGroupsLabelProperty); }
set { SetValue(ShowGroupsLabelProperty, value); }
}
public static readonly DependencyProperty ShowGroupsLabelProperty = DependencyProperty.Register("ShowGroupsLabel", typeof(bool),
typeof(RadarControl), new PropertyMetadata(true));
///
/// 是否为多重绘图模式(默认否)
///
public bool MoreGraphics
{
get { return (bool)GetValue(MoreGraphicsProperty); }
set { SetValue(MoreGraphicsProperty, value); }
}
public static readonly DependencyProperty MoreGraphicsProperty = DependencyProperty.Register("MoreGraphics", typeof(bool),
typeof(RadarControl), new PropertyMetadata(false));
///
/// 分隔角度
///
private double Angle
{
get
{
int count = MoreGraphics ? MoreDatas[0].Count : Datas.Count;
double angle = 360 / count;
return angle;
}
}
///
/// 数据
///
public List Datas
{
get { return (List)GetValue(DatasProperty); }
set { SetValue(DatasProperty, value); }
}
public static readonly DependencyProperty DatasProperty = DependencyProperty.Register("Datas", typeof(List),
typeof(RadarControl), new PropertyMetadata(new List()));
///
/// 多元数据
///
public List[] MoreDatas
{
get { return (List[])GetValue(MoreDatasProperty); }
set { SetValue(MoreDatasProperty, value); }
}
public static readonly DependencyProperty MoreDatasProperty = DependencyProperty.Register("MoreDatas", typeof(List[]),
typeof(RadarControl), new PropertyMetadata(new List[2]));
///
/// 多元数据画笔
///
public List RadarNetBrushes
{
get { return (List)GetValue(RadarNetBrushesProperty); }
set { SetValue(RadarNetBrushesProperty, value); }
}
public static readonly DependencyProperty RadarNetBrushesProperty = DependencyProperty.Register("RadarNetBrushes", typeof(List),
typeof(RadarControl), new PropertyMetadata(new List()));
///
/// 当前绘制大区域
///
private double MaxSize
{
get
{
var par = this.Parent as FrameworkElement;
return par.ActualHeight > par.ActualWidth ? par.ActualWidth : par.ActualHeight;
}
}
#endregion 属性
private void RadarControl_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (!MoreGraphics)
InitalData();
else
InitalMoreData();
}
///
/// 设置标注
///
///
///
///
private void SetLabel(RadarObj obj, Point location, bool isGroupLabel)
{
//计算偏移量
bool x = true;
bool y = true;
if (location.X -5 && location.X -5 && location.Y
/// 设置数据显示
///
private void InitalData()
{
CanvasPanel.Children.Clear();
if (Datas != null && Datas.Count > 0)
{
this.CanvasPanel.Width = this.CanvasPanel.Height = 0;
//计算比例尺
var scale = ((MaxSize / 2) - RadarNetMargin) / Datas.Max(i => i.DataValue);
//计算实际半径
for (int i = 0; i i.DataRaidus);
//计算纬线间距半径
double length = maxData / LatitudeCount;
for (int index = 1; index ellipselst = new List();
Dictionary valuesLabelLocations = new Dictionary();
Dictionary groupLabelLocations = new Dictionary();
//绘制数据多边形
for (int Index = 0; Index maxRadius)
{
Radius = maxRadius;
}
Point pt = new Point(Radius * Math.Cos(angle), Radius * Math.Sin(angle));
polygonArea.Points.Add(pt);
valuesLabelLocations.Add(Datas[Index], new Point((Radius) * Math.Cos(angle), (Radius) * Math.Sin(angle)));//记录点位标注标识
//设置数值点,如果数值点尺寸大于0则绘制
if (AreaPointSize > 0)
{
var ellipse = new Ellipse() { Width = AreaPointSize, Height = AreaPointSize, Fill = AreaPointBrush };
//var ellipse = new Ellipse() { Width = AreaPointSize, Height = AreaPointSize, Fill = Datas[Index].Fill }; AreaPointBrush
Canvas.SetLeft(ellipse, pt.X - (AreaPointSize / 2));
Canvas.SetTop(ellipse, pt.Y - (AreaPointSize / 2));
ellipselst.Add(ellipse);
}
Point ptMax = new Point(maxRadius * Math.Cos(angle), maxRadius * Math.Sin(angle));
//记录组点位标注标识
groupLabelLocations.Add(Datas[Index], new Point((maxRadius + 20) * Math.Cos(angle), (maxRadius + 20) * Math.Sin(angle)));
//绘制经线
Path pth = new Path() { Stroke = RadarNetBrush, StrokeThickness = RadarNetThickness };
// Path pth = new Path() { Stroke = Datas[Index].Stroke, StrokeThickness = RadarNetThickness };
pth.Data = (Geometry)new GeometryConverter().ConvertFromString(String.Format("M0,0 {0},{1}", ptMax.X.ToString(), ptMax.Y.ToString()));
CanvasPanel.Children.Add(pth);
}
CanvasPanel.Children.Add(polygonArea);
//绘点
foreach (var elc in ellipselst)
CanvasPanel.Children.Add(elc);
//标注值标签
if (ShowValuesLabel)
{
foreach (var item in valuesLabelLocations)
{
// SetLabel(item.Key, item.Value, false);
}
}
//标注组标签
if (ShowGroupsLabel)
{
foreach (var item in groupLabelLocations)
SetLabel(item.Key, item.Value, true);
}
this.SizeChanged -= RadarControl_SizeChanged;
this.SizeChanged += RadarControl_SizeChanged;
}
}
///
/// 设置数据显示
///
private void InitalMoreData()
{
CanvasPanel.Children.Clear();
if (this.MoreDatas != null && MoreDatas.Length > 0)
{
this.CanvasPanel.Width = this.CanvasPanel.Height = 0;
//计算比例尺
var max = 0.00;
foreach (var item in MoreDatas)
if (item.Max(i => i.DataValue) > max)
max = item.Max(i => i.DataValue);
var scale = ((MaxSize / 2) - RadarNetMargin) / max;
//计算实际半径
for (int index = 0; index i.DataRaidus) > maxData)
maxData = item.Max(i => i.DataRaidus);
//计算纬线间距半径
double length = maxData / LatitudeCount;
for (int index = 1; index polygonAreaList = new List();
for (int index = 0; index ellipselst = new List();
Dictionary valuesLabelLocations = new Dictionary();
Dictionary groupLabelLocations = new Dictionary();
//绘制数据多边形
for (int Index = 0; Index maxRadius)
{
Radius = maxRadius;
}
Point pt = new Point(Radius * Math.Cos(angle), Radius * Math.Sin(angle));
polygonAreaList[dataIndex].Points.Add(pt);
//valuesLabelLocations.Add(Datas[Index], new Point((Radius) * Math.Cos(angle), (Radius) * Math.Sin(angle)));//记录点位标注标识
//设置数值点,如果数值点尺寸大于0则绘制
if (AreaPointSize > 0)
{
var ellipse = new Ellipse() { Width = AreaPointSize / 2, Height = AreaPointSize / 2, Fill = new SolidColorBrush((Color)ColorConverter.ConvertFromString(ChartColorPool.ColorStrings[Index])) };
Canvas.SetLeft(ellipse, pt.X - (AreaPointSize / 4));
Canvas.SetTop(ellipse, pt.Y - (AreaPointSize / 4));
ellipselst.Add(ellipse);
}
}
Point ptMax = new Point(maxRadius * Math.Cos(angle), maxRadius * Math.Sin(angle));
//记录组点位标注标识
groupLabelLocations.Add(MoreDatas[0][Index], new Point((maxRadius + 20) * Math.Cos(angle), (maxRadius + 20) * Math.Sin(angle)));
//绘制经线 RadarNetBrush
Path pth = new Path() { Stroke = RadarNetBrush, StrokeThickness = RadarNetThickness };
pth.Data = (Geometry)new GeometryConverter().ConvertFromString(String.Format("M0,0 {0},{1}", ptMax.X.ToString(), ptMax.Y.ToString()));
CanvasPanel.Children.Add(pth);
}
foreach (var polygonArea in polygonAreaList)
CanvasPanel.Children.Add(polygonArea);
//绘点
foreach (var elc in ellipselst)
CanvasPanel.Children.Add(elc);
//标注组标签
if (ShowGroupsLabel)
{
foreach (var item in groupLabelLocations)
SetLabel(item.Key, item.Value, true);
}
this.SizeChanged -= RadarControl_SizeChanged;
this.SizeChanged += RadarControl_SizeChanged;
}
}
public void InitalControl()
{
}
///
/// 加载数据
///
///
public void SetData(object dataobj)
{
if (!MoreGraphics)
{
this.Datas = (dataobj) as List;
this.InitalData();
}
else
{
this.MoreDatas = (dataobj) as List[];
InitalMoreData();
}
}
private Brush _stroke = Brushes.Yellow;
///
/// Series stroke
///
public Brush Stroke
{
get
{
return _stroke;
}
set
{
_stroke = value;
}
}
private Brush _fill = Brushes.Yellow;
///
/// Series Fill
///
public Brush Fill
{
get
{
return _fill;
}
set
{
_fill = value;
}
}
}
调用方式:
private void RadarClick(object sender, RoutedEventArgs e)
{
RadarControl rdc = new RadarControl() { AreaBrush = Brushes.Black, RadarNetBrush = Brushes.Black, AreaPointBrush = Brushes.Orange, BorderBrush = Brushes.Gray };
this.GrdMain.Children.Clear();
this.GrdMain.Children.Add(rdc);
rdc.SetData(CrData());
}
private void RadarsClick(object sender, RoutedEventArgs e)
{
RadarControl rdc = new RadarControl() { MoreGraphics = true, AreaBrush = Brushes.Black, RadarNetBrush = Brushes.Black, AreaPointBrush = Brushes.Orange, BorderBrush = Brushes.Gray, RadarNetBrushes = new List { Brushes.LightSkyBlue, Brushes.Violet } };
this.GrdMain.Children.Clear();
this.GrdMain.Children.Add(rdc);
List[] lst = { CrData(), CrData() };
rdc.SetData(lst);
}
private List CrData()
{
List list = new List();
list.Add(new RadarObj() { Name="A", DataValue= rdm.Next(20,100) });
list.Add(new RadarObj() { Name = "B", DataValue = rdm.Next(20, 100) });
list.Add(new RadarObj() { Name = "C", DataValue = rdm.Next(20, 100) });
list.Add(new RadarObj() { Name = "D", DataValue = rdm.Next(20, 100) });
list.Add(new RadarObj() { Name = "E", DataValue = rdm.Next(20, 100) });
list.Add(new RadarObj() { Name = "F", DataValue = rdm.Next(20, 100) });
list.Add(new RadarObj() { Name = "F", DataValue = rdm.Next(20, 100) });
return list;
}
补充下之前漏掉的辅助类
1.动画辅助类
///
/// 动画帮助类
///
public class AnimationUtils
{
///
/// 渐影动画
///
/// 控件对象
/// 播放时间长度
/// 延迟播放时间
public static void CtrlDoubleAnimation(UIElement element, double mseconds, double mlateSeconds)
{
element.Visibility = Visibility.Collapsed;
DoubleAnimation doubleAnimation = new DoubleAnimation();
doubleAnimation.From = 0;
doubleAnimation.To = 1;
doubleAnimation.Duration = TimeSpan.FromMilliseconds(mseconds);
EventHandler handler;
doubleAnimation.Completed += handler = (s, e) =>{
element.Visibility = Visibility.Visible;
};
doubleAnimation.BeginTime = TimeSpan.FromMilliseconds(mlateSeconds);
element.BeginAnimation(UIElement.OpacityProperty, doubleAnimation);
}
///
/// 透明度动画
///
///
///
public static void FloatElement(UIElement elem, double to, double mseconds, double mlateSeconds)
{
lock (elem)
{
if (to == 1)
{
elem.Visibility = Visibility.Collapsed;
}
//else
//{
// elem.Visibility = Visibility.Visible;
//}
DoubleAnimation opacity = new DoubleAnimation()
{
To = to,
Duration = TimeSpan.FromMilliseconds(mseconds),
BeginTime = TimeSpan.FromMilliseconds(mlateSeconds)
};
EventHandler handler = null;
opacity.Completed += handler = (s, e) =>
{
opacity.Completed -= handler;
if (to == 1)
{
elem.Visibility = Visibility.Visible;
}
//else
//{
// elem.Visibility = Visibility.Visible;
//}
opacity = null;
};
elem.BeginAnimation(UIElement.OpacityProperty, opacity);
}
}
///
/// 支撑同时旋转和缩放的动画
///
/// 控件
/// 元素开始的大小
/// 元素到达的大小
/// 动画世界
/// 结束事件
public static void ScaleRotateEasingAnimationShow(UIElement element, double from, double to, double mseconds, double mlateSeconds, EventHandler completed)
{
//旋转
RotateTransform angle = new RotateTransform();
//缩放
ScaleTransform scale = new ScaleTransform();
TransformGroup group = new TransformGroup();
group.Children.Add(scale);
group.Children.Add(angle);
element.RenderTransform = group;
//定义圆心位置
element.RenderTransformOrigin = new Point(0.5, 0.5);
EasingFunctionBase easeFunction = new PowerEase()
{
EasingMode = EasingMode.EaseInOut,
Power = 2
};
// 动画参数
DoubleAnimation scaleAnimation = new DoubleAnimation()
{
From = from,
To = to,
EasingFunction = easeFunction,
Duration = TimeSpan.FromMilliseconds(mseconds),
BeginTime = TimeSpan.FromMilliseconds(mlateSeconds),
FillBehavior = FillBehavior.Stop
};
// 动画参数
DoubleAnimation angleAnimation = new DoubleAnimation()
{
From = 0,
To = 360,
EasingFunction = easeFunction,
Duration = TimeSpan.FromMilliseconds(mseconds),
BeginTime = TimeSpan.FromMilliseconds(mlateSeconds),
FillBehavior = FillBehavior.Stop,
};
//angleAnimation.Completed += completed;
// 执行动画
scale.BeginAnimation(ScaleTransform.ScaleXProperty, scaleAnimation);
scale.BeginAnimation(ScaleTransform.ScaleYProperty, scaleAnimation);
//angle.BeginAnimation(RotateTransform.AngleProperty, angleAnimation);
}
}
2.标注计算类
///
/// 计算指定字符串占用的高宽
///
public class ControlSizeUtils
{
private static Size MeasureTextSize(string text, Typeface typeface, double fontSize)
{
var ft = new FormattedText(text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, typeface, fontSize, Brushes.Black);
return new Size(ft.Width, ft.Height);
}
///
/// 衡量字符尺寸
///
///
public static Size GetTextAreaSize(string text, double fontsize)
{
FontFamily fontFamily; FontStyle fontStyle; FontWeight fontWeight; FontStretch fontStretch;
fontFamily = new FontFamily("微软雅黑"); fontStyle = FontStyles.Normal;
fontWeight = FontWeights.Normal;
fontStretch = FontStretches.Normal;
double fontSize = fontsize;
if (text == null)
return new Size(0, 0);
Typeface typeface = new Typeface(fontFamily, fontStyle, fontWeight, fontStretch);
GlyphTypeface gt;
if (!typeface.TryGetGlyphTypeface(out gt))
return MeasureTextSize(text, typeface, fontSize);
double totalWidth = 0;
double totalHeight = 0;
// 替换换行符
var array = text.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
foreach (var splitted in array)
{
double lineWidth = 0;
double lineHeight = 0;
// 计算每行的宽度和高度
for (int n = 0; n
3.笔刷集合
public static class ChartColorPool
{
public static List ColorStrings = new List() {
"#FF09F7D7",
"#FF97F18E",
"#FFF1ADAD",
"#FFF44336",
"#FFE91E63",
"#FF9C27B0",
"#FF673AB7",
"#FF3F51B5",
"#FF2196F3",
"#FF03A9F4",
"#FF00BCD4",
"#FF009688",
"#FF4CAF50",
"#FF8BC34A",
"#FFCDDC39",
"#FFFFEB3B",
"#FFFFC107",
"#FFFF9800",
"#FFFF5722",
"#FF795548",
"#FF9E9E9E",
"#FF607D8B",
"#32CD32",
"#FFFF00",
"#32CD32",
"#FFFF00",
"#21B6BA",
"#D84E67",
"#B44ED6",
"#0092FF",
"#E6FF0D",
"#21B962",
"#FF0000", //[32]Red-纯红
"#00BFFF" , //[33]DeepSkyBlue-深天蓝
"#0099D7",//浅蓝
"#FF9B4D", //橙色
"#00F8A4", //浅绿
"#FFEF53", //黄色
"#EB7274", //粉色
"#8B95AD", //浅灰
"#00DFDE", //浅蓝
"#C19EDC", //浅紫
"#62474C"//褐色
};
}
WPF 雷达图
标签:dma series eal asp 记录组 next fill completed split
原文地址:https://www.cnblogs.com/Funk/p/11405475.html