WPF 雷达图
Posted funk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF 雷达图相关的知识,希望对你有一定的参考价值。
雷达图逻辑同玫瑰图差不多,不同的地方在于绘制雷达网络,也就是蜘蛛网这样的底图。
界面代码
<UserControl x:Class="Painter.RadarControl" 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" xmlns:local="clr-namespace:Painter" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> <Canvas x:Name="CanvasPanel" HorizontalAlignment="Center" VerticalAlignment="Center" Background="Gray"> </Canvas> </Grid> </UserControl>
后台代码
public partial class RadarControl : UserControl public RadarControl() InitializeComponent(); #region 属性 /// <summary> /// 数值区域填充色 /// </summary> 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)); /// <summary> /// 数值区域点填充色 /// </summary> 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)); /// <summary> /// 雷达网格线填充充色 /// </summary> 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)); /// <summary> /// 雷达网格线宽度 /// </summary> 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)); /// <summary> /// 数值点高宽度,0为不显示 /// </summary> 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)); /// <summary> /// 纬线数量 /// </summary> 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)); /// <summary> /// 网格图停靠间距 /// </summary> 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)); /// <summary> /// 显示值标注 /// </summary> 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)); /// <summary> /// 显示组标签 /// </summary> 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)); /// <summary> /// 是否为多重绘图模式(默认否) /// </summary> 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)); /// <summary> /// 分隔角度 /// </summary> private double Angle get int count = MoreGraphics ? MoreDatas[0].Count : Datas.Count; double angle = 360 / count; return angle; /// <summary> /// 数据 /// </summary> public List<RadarObj> Datas get return (List<RadarObj>)GetValue(DatasProperty); set SetValue(DatasProperty, value); public static readonly DependencyProperty DatasProperty = DependencyProperty.Register("Datas", typeof(List<RadarObj>), typeof(RadarControl), new PropertyMetadata(new List<RadarObj>())); /// <summary> /// 多元数据 /// </summary> public List<RadarObj>[] MoreDatas get return (List<RadarObj>[])GetValue(MoreDatasProperty); set SetValue(MoreDatasProperty, value); public static readonly DependencyProperty MoreDatasProperty = DependencyProperty.Register("MoreDatas", typeof(List<RadarObj>[]), typeof(RadarControl), new PropertyMetadata(new List<RadarObj>[2])); /// <summary> /// 多元数据画笔 /// </summary> public List<Brush> RadarNetBrushes get return (List<Brush>)GetValue(RadarNetBrushesProperty); set SetValue(RadarNetBrushesProperty, value); public static readonly DependencyProperty RadarNetBrushesProperty = DependencyProperty.Register("RadarNetBrushes", typeof(List<Brush>), typeof(RadarControl), new PropertyMetadata(new List<Brush>())); /// <summary> /// 当前绘制大区域 /// </summary> 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(); /// <summary> /// 设置标注 /// </summary> /// <param name="obj"></param> /// <param name="location"></param> /// <param name="isGroupLabel"></param> private void SetLabel(RadarObj obj, Point location, bool isGroupLabel) //计算偏移量 bool x = true; bool y = true; if (location.X < 0) x = false; if (location.Y < 0) y = false; TextBlock txb = new TextBlock() Text = isGroupLabel ? obj.Name : obj.DataValue.ToString(), Foreground = this.Foreground, FontSize = this.FontSize ; Size s = ControlSizeUtils.GetTextAreaSize(txb.Text,this.FontSize); CanvasPanel.Children.Add(txb); if (location.X > -5 && location.X < 5) Canvas.SetLeft(txb, location.X - (s.Width / 2)); else Canvas.SetLeft(txb, location.X + (x ? 0 : -(s.Width))); if (location.Y > -5 && location.Y < 5) Canvas.SetTop(txb, location.Y - (s.Height / 2)); else Canvas.SetTop(txb, location.Y + (y ? 0 : -(s.Height))); /// <summary> /// 设置数据显示 /// </summary> 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 < Datas.Count; i++) Datas[i].DataRaidus = Datas[i].DataValue * scale; //获取最大数值 double maxData = Datas.Max(i => i.DataRaidus); //计算纬线间距半径 double length = maxData / LatitudeCount; for (int index = 1; index < LatitudeCount + 1; index++) //多边形半径 var r = length * index; Polygon polygonBorder = new Polygon() Fill = Brushes.Transparent, Stroke = RadarNetBrush, StrokeThickness = RadarNetThickness ; //绘制多边形 for (int currentIndex = 0; currentIndex < Datas.Count; currentIndex++) double angle = ((Angle * currentIndex + 90) / 360) * 2 * Math.PI; polygonBorder.Points.Add(new Point(r * Math.Cos(angle), r * Math.Sin(angle))); CanvasPanel.Children.Add(polygonBorder); //数值区域多边形 Polygon polygonArea = new Polygon() Fill = AreaBrush, Opacity = 0.5, Stroke = AreaPointBrush, StrokeThickness = 5 ; //经线长度 var maxRadius = LatitudeCount * length; List<Ellipse> ellipselst = new List<Ellipse>(); Dictionary<RadarObj, Point> valuesLabelLocations = new Dictionary<RadarObj, Point>(); Dictionary<RadarObj, Point> groupLabelLocations = new Dictionary<RadarObj, Point>(); //绘制数据多边形 for (int Index = 0; Index < Datas.Count; Index++) //计算角度 double angle = ((Angle * Index + 90) / 360) * 2 * Math.PI; //计算距离值 var cou = Datas[Index].DataRaidus / length; //计算倍距 var rac = Datas[Index].DataRaidus % length;//计算余距 double Radius = cou * length + rac; //超过最大半径则设置为最大半径 if (Radius > 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; /// <summary> /// 设置数据显示 /// </summary> 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 < MoreDatas.Length; index++) for (int i = 0; i < MoreDatas[index].Count; i++) MoreDatas[index][i].DataRaidus = MoreDatas[index][i].DataValue * scale; //获取最大数值 double maxData = 0.000; foreach (var item in MoreDatas) if (item.Max(i => i.DataRaidus) > maxData) maxData = item.Max(i => i.DataRaidus); //计算纬线间距半径 double length = maxData / LatitudeCount; for (int index = 1; index < LatitudeCount + 1; index++) //多边形半径 var r = length * index;//RadarNetBrush Polygon polygonBorder = new Polygon() Fill = Brushes.Transparent, Stroke = RadarNetBrush, StrokeThickness = RadarNetThickness ; //绘制多边形 for (int currentIndex = 0; currentIndex < MoreDatas[0].Count; currentIndex++) double angle = ((Angle * currentIndex + 90) / 360) * 2 * Math.PI; polygonBorder.Points.Add(new Point(r * Math.Cos(angle), r * Math.Sin(angle))); CanvasPanel.Children.Add(polygonBorder); //数值区域多边形 List<Polygon> polygonAreaList = new List<Polygon>(); for (int index = 0; index < this.MoreDatas.Length; index++) polygonAreaList.Add(new Polygon() Fill = RadarNetBrushes[index], Opacity = 0.5, Stroke = Brushes.LightGreen, StrokeThickness = 3 ); //经线长度 var maxRadius = LatitudeCount * length; List<Ellipse> ellipselst = new List<Ellipse>(); Dictionary<RadarObj, Point> valuesLabelLocations = new Dictionary<RadarObj, Point>(); Dictionary<RadarObj, Point> groupLabelLocations = new Dictionary<RadarObj, Point>(); //绘制数据多边形 for (int Index = 0; Index < MoreDatas[0].Count; Index++) //计算角度 double angle = ((Angle * Index + 90) / 360) * 2 * Math.PI; //逐步生成每类数据的各组实际数据:例如A、B、C、D的交通数据数据 for (int dataIndex = 0; dataIndex < MoreDatas.Length; dataIndex++) //计算距离值 var cou = MoreDatas[dataIndex][Index].DataRaidus / length; //计算倍距 var rac = MoreDatas[dataIndex][Index].DataRaidus % length;//计算余距 double Radius = cou * length + rac; //超过最大半径则设置为最大半径 if (Radius > 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() /// <summary> /// 加载数据 /// </summary> /// <param name="dataobj"></param> public void SetData(object dataobj) if (!MoreGraphics) this.Datas = (dataobj) as List<RadarObj>; this.InitalData(); else this.MoreDatas = (dataobj) as List<RadarObj>[]; InitalMoreData(); private Brush _stroke = Brushes.Yellow; /// <summary> /// Series stroke /// </summary> public Brush Stroke get return _stroke; set _stroke = value; private Brush _fill = Brushes.Yellow; /// <summary> /// Series Fill /// </summary> 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<Brush> Brushes.LightSkyBlue, Brushes.Violet ; this.GrdMain.Children.Clear(); this.GrdMain.Children.Add(rdc); List<RadarObj>[] lst = CrData(), CrData() ; rdc.SetData(lst); private List<RadarObj> CrData() List<RadarObj> list = new List<RadarObj>(); 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.动画辅助类
/// <summary> /// 动画帮助类 /// </summary> public class AnimationUtils /// <summary> /// 渐影动画 /// </summary> /// <param name="element">控件对象</param> /// <param name="seconds">播放时间长度</param> /// <param name="lateSeconds">延迟播放时间</param> 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); /// <summary> /// 透明度动画 /// </summary> /// <param name="elem"></param> /// <param name="to"></param> 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); /// <summary> /// 支撑同时旋转和缩放的动画 /// </summary> /// <param name="element">控件</param> /// <param name="from">元素开始的大小</param> /// <param name="to">元素到达的大小</param> /// <param name="time">动画世界</param> /// <param name="completed">结束事件</param> 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.标注计算类
/// <summary> /// 计算指定字符串占用的高宽 /// </summary> 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); /// <summary> /// 衡量字符尺寸 /// </summary> /// <returns></returns> 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 < splitted.Length; n++) try ushort glyphIndex = gt.CharacterToGlyphMap[splitted[n]]; double width = gt.AdvanceWidths[glyphIndex] * fontSize; double height = gt.AdvanceHeights[glyphIndex] * fontSize; lineHeight = Math.Max(totalHeight, height); lineWidth += width; catch (Exception exp) lineWidth += fontSize; totalWidth = Math.Max(totalWidth, lineWidth); totalHeight = Math.Max(totalHeight, lineHeight); if (totalWidth < 5) totalWidth = 5; return new Size(totalWidth, totalHeight);
3.笔刷集合
public static class ChartColorPool public static List<string> ColorStrings = new List<string>() "#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 雷达图的主要内容,如果未能解决你的问题,请参考以下文章