/// <summary>
        /// 初始化数据
        /// </summary>
        private void initData()
        {
            CanvasPanel.Children.Clear();
            if (this.Datas != null && this.Datas.Count > 0)
            {
                this.CanvasPanel.Width = this.CanvasPanel.Height = 0;

                //求角度比例尺  (每个值占多大的角度  可以算到每一块图所占的角度)
                var angelScale = 360.00 / Datas.Sum(i => i.DataValue);

                //最大半径
                var maxRadius = (MaxSize / 2) - RoseMargin - (ShowValuesLabel ? LabelPathLength : 0);

                //半径比例尺  (值和比例尺相乘等于每一块图的半径)
                var radiusScale = maxRadius / Datas.Max(o => o.DataValue);

                //计算半径宽度值
                for (int i = 0; i < Datas.Count; i++)
                {
                    Datas[i].DataRaidus = Datas[i].DataValue * radiusScale;
                }
                //扇形角度初始化
                double angleSectorStart = 0;
                double angleSectorEnd   = 0;

                //循环绘制扇形区域
                int scaleTimeSpan = 0;
                int pathTimespan  = 0;
                int textTimeSpan  = 0;
                for (int index = 0; index < Datas.Count; index++)
                {
                    //计算扇形角度
                    if (index == 0)
                    {
                        angleSectorStart = 0;
                        angleSectorEnd   = Datas[index].DataValue * angelScale;
                    }
                    else if (index + 1 == Datas.Count)
                    {
                        angleSectorStart += Datas[index - 1].DataValue * angelScale;
                        angleSectorEnd    = 360;
                    }
                    else
                    {
                        angleSectorStart += Datas[index - 1].DataValue * angelScale;
                        angleSectorEnd    = angleSectorStart + Datas[index].DataValue * angelScale;
                    }
                    var currentRadius = RoseInsideMargin + Datas[index].DataRaidus;
                    //计算扇形点位,用于绘制PATH
                    Point ptOutSideStart = GetPoint(currentRadius, angleSectorStart * Math.PI / 180);
                    Point ptOutSideEnd   = GetPoint(currentRadius, angleSectorEnd * Math.PI / 180);
                    Point ptInSideStart  = GetPoint(RoseInsideMargin, angleSectorStart * Math.PI / 180);
                    Point ptInSideEnd    = GetPoint(RoseInsideMargin, angleSectorEnd * Math.PI / 180);
                    if (string.IsNullOrEmpty(Datas[index].RColor))
                    {
                        Datas[index].RColor = ChartColorPool.ColorStrings[index];
                    }
                    Path pthSector = new Path()
                    {
                        Fill = Datas[index].Fill
                    };
                    //PATH数据格式 M0,100  L50,100 A50,50 0 0 1 100,50 L100,0 A100,100 0 0 0 0,100 Z
                    StringBuilder datastrb = new StringBuilder();

                    #region BuilderPathData

                    datastrb.Append("M");
                    datastrb.Append(ptOutSideStart.X.ToString());
                    datastrb.Append(",");
                    datastrb.Append(ptOutSideStart.Y.ToString());
                    datastrb.Append(" L");
                    datastrb.Append(ptInSideStart.X.ToString());
                    datastrb.Append(",");
                    datastrb.Append(ptInSideStart.Y.ToString());
                    datastrb.Append(" A");
                    datastrb.Append(RoseInsideMargin.ToString());
                    datastrb.Append(",");
                    datastrb.Append(RoseInsideMargin.ToString());
                    datastrb.Append(" 0 0 1 ");
                    datastrb.Append(ptInSideEnd.X.ToString());
                    datastrb.Append(",");
                    datastrb.Append(ptInSideEnd.Y.ToString());
                    datastrb.Append(" L");
                    datastrb.Append(ptOutSideEnd.X.ToString());
                    datastrb.Append(",");
                    datastrb.Append(ptOutSideEnd.Y.ToString());
                    datastrb.Append(" A");
                    datastrb.Append(currentRadius.ToString());
                    datastrb.Append(",");
                    datastrb.Append(currentRadius.ToString());
                    datastrb.Append(" 0 0 0 ");
                    datastrb.Append(ptOutSideStart.X.ToString());
                    datastrb.Append(",");
                    datastrb.Append(ptOutSideStart.Y.ToString());
                    datastrb.Append(" Z");

                    #endregion BuilderPathData
                    try
                    {
                        pthSector.Data = (Geometry) new GeometryConverter().ConvertFromString(datastrb.ToString());
                    }
                    catch (Exception exp)
                    { }
                    //设置扇形显示的动画
                    AnimationUtils.FloatElement(pthSector, 1, 200, pathTimespan += 200);
                    AnimationUtils.ScaleRotateEasingAnimationShow(pthSector, 0.1, 1, 1500, scaleTimeSpan += 200, null);

                    CanvasPanel.Children.Add(pthSector);
                    if (ShowValuesLabel)
                    {
                        //计算延伸线角度
                        double lbPathAngle = angleSectorStart + (angleSectorEnd - angleSectorStart) / 2;
                        //起点
                        Point ptLbStart = GetPoint(currentRadius, lbPathAngle * Math.PI / 180);
                        //终点
                        Point ptLbEnd = GetPoint(maxRadius + LabelPathLength, lbPathAngle * Math.PI / 180);
                        Path  pthLb   = new Path()
                        {
                            Stroke = Datas[index].Stroke, StrokeThickness = 1
                        };
                        pthLb.Data = (Geometry) new GeometryConverter().ConvertFromString(string.Format("M{0},{1} {2},{3}", ptLbStart.X.ToString(), ptLbStart.Y.ToString(), ptLbEnd.X.ToString(), ptLbEnd.Y.ToString()));
                        double dur = (textTimeSpan += 200) + 1500;
                        AnimationUtils.CtrlDoubleAnimation(pthLb, 1000, dur);
                        CanvasPanel.Children.Add(pthLb);
                        SetLabel(Datas[index], ptLbEnd, dur);
                    }
                }
                this.SizeChanged -= RadarControl_SizeChanged;
                this.SizeChanged += RadarControl_SizeChanged;
            }
        }
Ejemplo n.º 2
0
        private void RadarChartControl_OnLoaded(object sender, RoutedEventArgs e)
        {
            if (!CheckData())
            {
                throw new Exception("RadarChart的数据之间不匹配!请重新配置!");
            }
            //获取最大数值
            int maxData = Datas.Max(i => i.DataList.Max(o => o.Data));

            //设置面板和背景
            SetCanvasAndBackground(maxData);

            //设置数据标题
            SetDataTitle(Datas);

            //获取半圈大小
            double length = Size / 2 / maxData;

            //连接点半径
            int ellipseR = EllipseSize / 2;

            foreach (var chartItem in Datas)
            {
                var color = chartItem.Color;

                //俩个多边形,一个设置背景,一个设置边框
                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);
                    //多边形添加节点
                    var point = new Point()
                    {
                        X = x,
                        Y = y
                    };
                    polygonArea.Points.Add(point);
                    polygonBorder.Points.Add(point);
                    //设置节点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);
            }
            //设置标题
            SetArguments();
        }
        /// <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;
            }
        }