Пример #1
0
        /// <summary>
        /// 添加点的小圆圈,方便鼠标点中。并加提示
        /// </summary>
        /// <param name="center"></param>
        /// <param name="rotate"></param>
        protected Ellipse AddPoint(Point center, double rotate, object tooltip, Model.DataPoint p)
        {
            var circle = Common.Helper.CreateEllipse(center, rotate);

            circle.Stroke = this.Stroke;
            circle.Fill   = this.Fill;
            ToolTipService.SetToolTip(circle, tooltip);

            if (this.ItemClick != null)
            {
                circle.Cursor             = Cursors.Hand;
                circle.MouseLeftButtonUp += (sender, e) => {
                    var arg = new Model.ItemClickEventArg()
                    {
                        Data = this.DataContext,
                        Item = p
                    };
                    ItemClick(circle, arg);
                };
            }

            Canvas.AddChild(circle);

            System.Windows.Controls.Canvas.SetZIndex(circle, Common.BaseParams.TooltipZIndex);

            return(circle);
        }
Пример #2
0
        /// <summary>
        /// 生成当前图形
        /// </summary>
        /// <returns></returns>
        public override System.Collections.Generic.IEnumerable <Shape> CreatePath()
        {
            if (storyboard != null)
            {
                storyboard.Stop();
            }
            if (Canvas.IsAnimate)
            {
                this.storyboard = new Storyboard();
            }

            this.Shaps.Clear();
            if (DataContext == null)
            {
                return(base.CreatePath());
            }

            var center = new Point()
            {
                X = this.Canvas.Width / 2, Y = centerSize * 2
            };
            var left = (center.X - circleSize - centerSize) / 2;

            if (left <= circleSize / 2)
            {
                left = circleSize + 2;
            }
            var bottom    = (center.Y + circleSize + centerSize);
            var maxbottom = Canvas.Height - Canvas.Margin.Bottom - circleSize - 4;
            //距离中心距离
            var radiacenter = Math.Min(center.X - left, maxbottom);

            var circleIndex = -1;
            var data        = DataContext as System.Collections.ICollection;

            //小圆个数
            var circlecount = data.Count;
            var rotatestep  = 3.8 / circlecount;//每个小圆的角度
            var mapping     = GetMapping(Model.ItemMapping.EnumDataMember.Y);

            if (mapping == null)
            {
                throw new Exception("至少需要指定一个Y轴字段映射");
            }

            var tocentername = "";

            //画泡泡
            foreach (var m in data)
            {
                if (m != null)
                {
                    var item = new Model.DataPoint();

                    item.PotinShape = new Path();
                    var v = Common.Helper.GetPropertyName(m, mapping.MemberName);;
                    item.PointType   = Model.DataPoint.EnumPointType.ChartPoint;
                    item.StringValue = v == null?"":v.ToString();

                    var tooltip = CreateTooltip(mapping.MemberName, item.StringValue);
                    ToolTipService.SetToolTip(item.PotinShape, tooltip);

                    var el = new EllipseGeometry();
                    item.PotinShape.Data = el;

                    //画中心位置
                    if (circleIndex == -1)
                    {
                        item.Position    = el.Center = center;
                        el.RadiusX       = el.RadiusY = centerSize;
                        tocentername     = item.StringValue;
                        item.StringValue = (CenterName ?? mapping.MemberName) + "\n" + item.StringValue;
                        //加入标签
                        Canvas.AddChild(item.CreateLabel());
                    }
                    //画边上的小圆
                    else
                    {
                        var position = new Point()
                        {
                            X = left
                        };
                        //离最左的小圆斜角偏移量
                        //二圆直接偏移量的一半
                        var rotate = rotatestep * circleIndex / 2;
                        var rsin   = Math.Sin(rotate);
                        var rcos   = Math.Cos(rotate);
                        //二圆偏移量
                        var step  = rsin * radiacenter * 2;
                        var ystep = step * rcos;
                        var xstep = step * rsin;

                        position.X = left + xstep;
                        position.Y = center.Y + ystep;

                        if (position.Y >= maxbottom)
                        {
                            position.Y = maxbottom;
                        }

                        item.Position = position;
                        el.RadiusX    = el.RadiusY = circleSize;

                        if (Canvas.IsAnimate)
                        {
                            var anima = new PointAnimation();
                            anima.To       = position;
                            anima.Duration = TimeSpan.FromMilliseconds(AnimateDurtion);

                            Storyboard.SetTarget(anima, el);
                            el.Center = center;
                            Storyboard.SetTargetProperty(anima, new PropertyPath("Center"));

                            anima.Completed += new EventHandler((sender, e) =>
                            {
                                Canvas.AddChild(item.CreateLabel());
                            });
                            this.storyboard.Children.Add(anima);
                        }
                        else
                        {
                            el.Center = position;
                            //加入标签
                            Canvas.AddChild(item.CreateLabel());
                        }

                        var arrow = new Controls.CLMArrow();
                        arrow.Fill     = this.Fill;
                        arrow.Stroke   = this.Stroke;
                        arrow.Rotate   = rotate;
                        arrow.ToName   = tocentername;
                        arrow.FromName = item.StringValue;
                        var startystep = circleSize * ((center.Y - item.Position.Y) / radiacenter);
                        var startxstep = circleSize * ((center.X - item.Position.X) / radiacenter);
                        arrow.StartPoint = new Point(item.Position.X + startxstep, item.Position.Y + startystep);
                        var endystep = centerSize * rsin;
                        var endxstep = centerSize * rcos;
                        arrow.EndPoint = new Point(center.X + endxstep, center.Y + endystep);

                        arrow.Create(Canvas);
                    }

                    if (Canvas.IsFillShape)
                    {
                        item.PotinShape.Fill = this.Fill;
                    }
                    item.PotinShape.Stroke          = this.Stroke;
                    item.PotinShape.StrokeThickness = Canvas.LineWidth;
                    this.Shaps.Add(item.PotinShape);

                    circleIndex++;
                }
            }

            return(base.CreatePath());
        }
Пример #3
0
        /// <summary>
        /// 生成当前线条
        /// </summary>
        /// <returns></returns>
        public override System.Collections.Generic.IEnumerable <Shape> CreatePath()
        {
            if (storyboard != null)
            {
                storyboard.Stop();
            }

            var canvas = Canvas as RadarCanvas;
            var index  = 0;

            if (canvas.IsAnimate)
            {
                this.storyboard = new Storyboard();
            }

            Path path = Shaps.Count > 0 ? Shaps[0] as Path : new Path();

            if (Shaps.Count == 0)
            {
                Shaps.Add(path);
            }

            if (canvas.IsFillShape)
            {
                path.Fill = this.Fill;
            }
            System.Windows.Controls.Canvas.SetZIndex(path, Common.BaseParams.ShapZIndex);

            path.StrokeThickness = canvas.LineWidth;
            path.Stroke          = this.Stroke;

            var geo = path.Data == null ? new PathGeometry() : path.Data as PathGeometry;

            path.Data = geo;
            PathFigure fig = null;

            if (geo.Figures.Count == 0)
            {
                fig = new PathFigure();
                geo.Figures.Add(fig);
                fig.IsClosed = true;
            }
            else
            {
                fig = geo.Figures[0];
                fig.Segments.Clear();
            }

            if (canvas.IsAnimate)
            {
                this.storyboard = new Storyboard();
            }
            if (Points == null)
            {
                Points = new System.Collections.ObjectModel.ObservableCollection <Model.DataPoint>();
            }
            Points.Clear();

            //起始点和线段点要分开处理
            foreach (var a in canvas.Axises)
            {
                if (a.AType != Axis.AxisType.YRadar)
                {
                    continue;
                }
                var axis = a as Axis.RadarAxis;

                var p = new Model.DataPoint();
                Points.Add(p);

                //获取当前点的值
                p.NumberValue = this.GetNumberValue(a.BindName);
                var r = a.Step * (p.NumberValue.Value - a.MinValue);

                //生成提示信息
                var tooltip = CreateTooltip(a.BindName);

                //目标点
                p.Position = new Point(canvas.Center.X + axis.RotateCos * r, canvas.Center.Y + axis.RotateSin * r);

                var point = AddPoint(p.Position, 10, tooltip, p);
                if (canvas.IsAnimate)
                {
                    point.Visibility = Visibility.Collapsed;

                    var anima = new PointAnimation();
                    anima.To       = p.Position;
                    anima.Duration = TimeSpan.FromMilliseconds(AnimateDurtion);

                    if (index != 0)
                    {
                        var seg = new LineSegment();
                        seg.Point = canvas.Center;
                        fig.Segments.Add(seg);
                        Storyboard.SetTarget(anima, seg);
                        Storyboard.SetTargetProperty(anima, new PropertyPath("Point"));
                    }
                    else
                    {
                        Storyboard.SetTarget(anima, fig);
                        fig.StartPoint = canvas.Center;
                        Storyboard.SetTargetProperty(anima, new PropertyPath("StartPoint"));
                        index++;
                    }

                    //动画展示完后加入点
                    anima.Completed += new EventHandler((object sender, EventArgs e) =>
                    {
                        var panima       = sender as PointAnimation;
                        point.Visibility = Visibility.Visible;
                    });

                    this.storyboard.Children.Add(anima);
                }
                else
                {
                    if (index != 0)
                    {
                        var seg = new LineSegment();
                        seg.Point = p.Position;
                        fig.Segments.Add(seg);
                    }
                    else
                    {
                        fig.StartPoint = p.Position;
                        index++;
                    }
                }
            }
            return(base.CreatePath());
        }
Пример #4
0
        /// <summary>
        /// 生成当前图形
        /// </summary>
        /// <returns></returns>
        public override System.Collections.Generic.IEnumerable <Shape> CreatePath()
        {
            if (storyboard != null)
            {
                storyboard.Stop();
            }
            if (Canvas.IsAnimate)
            {
                this.storyboard = new Storyboard();
            }

            this.Shaps.Clear();
            if (DataContext == null)
            {
                return(base.CreatePath());
            }
            var data = DataContext as System.Collections.ICollection;

            var circlesize = data.Count > 20 ? circleSize / data.Count * 20 : circleSize;
            var center     = new Point()
            {
                X = this.Canvas.Width / 2, Y = centerSize * 2.3
            };
            var left = Canvas.Margin.Left + circlesize * 2;

            if (left <= circlesize / 2)
            {
                left = circlesize + 2;
            }
            var bottom    = (center.Y + circlesize + centerSize);
            var maxbottom = Canvas.Height - Canvas.Margin.Bottom - circlesize - 4;
            //距离中心距离
            var radiacenter = Math.Min(center.X - left, maxbottom);
            var circleIndex = -1;

            //小圆个数
            var circlecount = data.Count;
            var rotatestep  = 3.78 / circlecount;//每个小圆的角度
            var mapping     = GetMapping(Model.ItemMapping.EnumDataMember.Y);

            if (mapping == null)
            {
                throw new Exception("至少需要指定一个Y轴字段映射");
            }
            //与中心点关联设置
            var links = GetMappings(Model.ItemMapping.EnumDataMember.CLMLink);

            var tocentername = "";

            //画泡泡
            foreach (var m in data)
            {
                if (m != null)
                {
                    var item = new Model.DataPoint();

                    item.PotinShape = new Path();
                    var v = Common.Helper.GetPropertyName(m, mapping.MemberName);;
                    item.PointType   = Model.DataPoint.EnumPointType.ChartPoint;
                    item.StringValue = v == null?"":v.ToString();
                    System.Windows.Controls.Canvas.SetZIndex(item.PotinShape, Common.BaseParams.ShapZIndex);

                    var el = new EllipseGeometry();
                    item.PotinShape.Data = el;

                    //画中心位置
                    if (circleIndex == -1)
                    {
                        item.Position    = el.Center = center;
                        el.RadiusX       = el.RadiusY = centerSize;
                        item.Width       = item.Height = centerSize * 2;
                        tocentername     = item.StringValue;
                        item.StringValue = (CenterName ?? mapping.MemberName) + "\n" + item.StringValue;

                        var label = item.CreateLabel();
                        //加入标签
                        Canvas.AddChild(label);

                        if (ItemClick != null)
                        {
                            label.Cursor = Cursors.Hand;
                            var centerdata = m;
                            label.MouseLeftButtonUp += (sender, e) =>
                            {
                                var arg = new Model.ItemClickEventArg()
                                {
                                    Data = centerdata,
                                    Item = item
                                };
                                ItemClick(sender, arg);
                            };
                        }

                        var tootip = CreateTooltip(m);
                        ToolTipService.SetToolTip(label, tootip);
                    }
                    //画边上的小圆
                    else
                    {
                        //初始化小圆点
                        InitPoint(el, item, rotatestep, circleIndex, radiacenter, center, maxbottom, circlesize, tocentername, circlecount, links, m);
                    }

                    if (Canvas.IsFillShape)
                    {
                        item.PotinShape.Fill = this.Fill;
                    }
                    item.PotinShape.Stroke          = this.Stroke;
                    item.PotinShape.StrokeThickness = Canvas.LineWidth;
                    this.Shaps.Add(item.PotinShape);

                    circleIndex++;
                }
            }

            return(base.CreatePath());
        }
Пример #5
0
        /// <summary>
        /// 初始化项
        /// </summary>
        /// <param name="el"></param>
        /// <param name="item"></param>
        /// <param name="rotatestep"></param>
        /// <param name="circleIndex"></param>
        /// <param name="radiacenter"></param>
        /// <param name="center"></param>
        /// <param name="maxbottom"></param>
        /// <param name="circlesize"></param>
        /// <param name="tocentername"></param>
        private void InitPoint(EllipseGeometry el, Model.DataPoint item,
                               double rotatestep, int circleIndex, double radiacenter, Point center,
                               double maxbottom, double circlesize, string tocentername, int circlecount,
                               System.Collections.Generic.IEnumerable <Model.ItemMapping> links, object data)
        {
            var position = new Point();
            var rotate   = rotatestep * circleIndex + 2.95;
            var rsin     = Math.Sin(rotate);
            var rcos     = Math.Cos(rotate);
            //二圆偏移量
            var ystep = rsin * radiacenter;
            var xstep = rcos * radiacenter;

            position.X = center.X + xstep;
            position.Y = center.Y - ystep;

            if (position.Y >= maxbottom)
            {
                position.Y = maxbottom;
            }

            item.Position = position;
            el.RadiusX    = el.RadiusY = circlesize;
            item.Width    = item.Height = circlesize * 2;

            var arrow = new Controls.CLMArrow(Canvas);

            arrow.Fill      = this.Fill;
            arrow.Stroke    = this.Stroke;
            arrow.Rotate    = rotate;
            arrow.ToName    = tocentername;
            arrow.FromName  = item.StringValue;
            arrow.RotateSin = rsin;
            arrow.RotateCos = rcos;

            var startystep = (circlesize) * arrow.RotateSin;
            var startxstep = (circlesize) * arrow.RotateCos;

            arrow.StartPoint = new Point(item.Position.X - startxstep, item.Position.Y + startystep);
            var endystep = centerSize * arrow.RotateSin;
            var endxstep = centerSize * arrow.RotateCos;

            arrow.EndPoint = new Point(center.X + endxstep, center.Y - endystep);

            if (links != null)
            {
                var count = links.Count <Model.ItemMapping>();
                if (count > 0)
                {
                    var lnk = links.ElementAt <Model.ItemMapping>(0);
                    var tmp = Common.Helper.GetPropertyName(data, lnk.MemberName);
                    if (!string.IsNullOrWhiteSpace(lnk.MarkName))
                    {
                        arrow.FromMarkName = lnk.MarkName;
                    }
                    arrow.FromValue = tmp == null ? "" : tmp.ToString();
                }
                if (count > 1)
                {
                    var lnk = links.ElementAt <Model.ItemMapping>(1);
                    var tmp = Common.Helper.GetPropertyName(data, lnk.MemberName);
                    if (!string.IsNullOrWhiteSpace(lnk.MarkName))
                    {
                        arrow.ToMarkName = lnk.MarkName;
                    }
                    arrow.ToValue = tmp == null ? "" : tmp.ToString();
                }
            }

            //设置箭头提示事件
            if (ArrowTooltipClick != null)
            {
                arrow.SetClickEvent(ArrowTooltipClick);
            }

            arrow.Draw();
            item.TargetControl = arrow;

            var label = item.CreateLabel();

            Canvas.AddChild(label);

            if (ItemClick != null)
            {
                label.Cursor             = Cursors.Hand;
                label.MouseLeftButtonUp += (sender, e) =>
                {
                    var arg = new Model.ItemClickEventArg()
                    {
                        Data = data,
                        Item = item
                    };
                    ItemClick(sender, arg);
                };
            }

            if (Canvas.IsAnimate)
            {
                label.Visibility = Visibility.Collapsed;
                var anima = new PointAnimation();
                anima.To       = position;
                anima.Duration = TimeSpan.FromMilliseconds(AnimateDurtion);

                Storyboard.SetTarget(anima, el);
                el.Center = center;
                Storyboard.SetTargetProperty(anima, new PropertyPath("Center"));

                var sizeanimax = new DoubleAnimation();
                sizeanimax.From = 0;
                sizeanimax.To   = circlesize;
                Storyboard.SetTarget(sizeanimax, el);
                Storyboard.SetTargetProperty(sizeanimax, new PropertyPath("RadiusX"));

                var sizeanimay = new DoubleAnimation();
                sizeanimay.From = 0;
                sizeanimay.To   = circlesize;
                Storyboard.SetTarget(sizeanimay, el);
                Storyboard.SetTargetProperty(sizeanimay, new PropertyPath("RadiusY"));

                anima.Completed += new EventHandler((sender, e) =>
                {
                    label.Visibility = Visibility.Visible;
                    InitMouseEvent(label, arrow);
                    if (circleIndex == circlecount / 2 - 1)
                    {
                        arrow.Show();
                        currentShowedArrow = arrow;
                    }
                });
                this.storyboard.Children.Add(anima);
                this.storyboard.Children.Add(sizeanimax);
                this.storyboard.Children.Add(sizeanimay);
            }
            else
            {
                el.Center = position;
                //加入标签
                //var label = item.CreateLabel();
                //Canvas.AddChild(label);
                InitMouseEvent(label, arrow);
                if (circleIndex == circlecount / 2 - 1)
                {
                    arrow.Show();
                    currentShowedArrow = arrow;
                }
            }
        }
Пример #6
0
        public override System.Collections.Generic.IEnumerable <Shape> CreatePath()
        {
            this.Shaps.Clear();
            if (DataContext == null)
            {
                return(base.CreatePath());
            }
            var data = DataContext as System.Collections.ICollection;
            //获取绑定的属性
            var mapping = GetMapping(Model.ItemMapping.EnumDataMember.Y);

            if (mapping == null)
            {
                throw new Exception("请设定一个默认的绑定属性.");
            }
            var lengendmapping = GetMapping(Model.ItemMapping.EnumDataMember.Lengend);

            var lst = new System.Collections.Generic.List <Model.DataPoint>();

            foreach (var d in data)
            {
                var    p   = new Model.DataPoint();
                double v   = 0;
                var    obj = Silverlight.Common.Reflection.ClassHelper.GetPropertyValue(d, mapping.MemberName);
                if (obj != null && double.TryParse(obj.ToString(), out v))
                {
                    p.NumberValue = v;
                }
                if (lengendmapping != null)
                {
                    obj = Silverlight.Common.Reflection.ClassHelper.GetPropertyValue(d, lengendmapping.MemberName);
                    if (obj != null)
                    {
                        p.StringValue = obj.ToString();
                    }
                }
                lst.Add(p);
                Points.Add(p);
            }
            lst.Sort();


            var  legwidth = Canvas.Width * 0.3;
            Rect rec      = new Rect(Canvas.Margin.Left, Canvas.Margin.Top, Canvas.Width - legwidth, Canvas.Height);

            var itemHeight = rec.Height / lst.Count - lst.Count * 2;
            //var curWidth = rec.Width;
            double     maxValue = lst[0].NumberValue.Value;
            var        index    = 0;
            PathFigure lastFig  = null;

            foreach (var p in lst)
            {
                p.Height = itemHeight;

                p.PotinShape = new Path();
                Shaps.Add(p.PotinShape);

                var color = index >= Canvas.SeriesColors.Length?Canvas.SeriesColors[0] : Canvas.SeriesColors[index];
                color.A           = 200;
                p.PotinShape.Fill = new SolidColorBrush(color);
                System.Windows.Controls.Canvas.SetZIndex(p.PotinShape, Common.BaseParams.ShapZIndex);

                p.PotinShape.StrokeThickness = Canvas.LineWidth;
                p.PotinShape.Stroke          = new SolidColorBrush(Colors.Black);

                var geo = new PathGeometry();
                p.PotinShape.Data = geo;
                var fig = new PathFigure();
                geo.Figures.Add(fig);
                fig.IsClosed = true;

                var per = p.NumberValue.Value / maxValue;
                p.Width = per * rec.Width;
                var top  = rec.Top + index * itemHeight + 2 * index;
                var left = rec.Left + (rec.Width - p.Width) / 2;

                p.Position = fig.StartPoint = new Point(left, top);
                var l1 = new LineSegment()
                {
                    Point = new Point(left + p.Width, top)
                };
                fig.Segments.Add(l1);
                //确定上一个图的下边框
                if (lastFig != null)
                {
                    var l2 = new LineSegment()
                    {
                        Point = new Point(l1.Point.X, lastFig.StartPoint.Y + itemHeight)
                    };
                    lastFig.Segments.Add(l2);
                    var l3 = new LineSegment()
                    {
                        Point = new Point(left, l2.Point.Y)
                    };
                    lastFig.Segments.Add(l3);
                }
                //当为最后一个
                if (index == lst.Count - 1)
                {
                    var bottomwidth = p.Width * 0.7;
                    var l2          = new LineSegment()
                    {
                        Point = new Point(l1.Point.X - (p.Width - bottomwidth) / 2, top + itemHeight)
                    };
                    fig.Segments.Add(l2);
                    var l3 = new LineSegment()
                    {
                        Point = new Point(l2.Point.X - bottomwidth, l2.Point.Y)
                    };
                    fig.Segments.Add(l3);
                }
                //var l2 = new LineSegment() { Point = new Point(l1.Point.X, top) };
                //fig.Segments.Add(l2);
                //var l3 = new LineSegment() { Point = new Point(left + curWidth, top) };
                //fig.Segments.Add(l3);
                //var l4 = new LineSegment() { Point = new Point(left + curWidth, top) };
                //fig.Segments.Add(l4);

                p.ForeColor = Colors.Black;
                var label = p.CreateLabel(p.NumberValue.Value.ToString() + "\n" + (per * 100).ToString("0.#") + "%");
                label.Width = rec.Width;
                label.SetValue(System.Windows.Controls.Canvas.LeftProperty, rec.Left);
                label.SetValue(System.Windows.Controls.Canvas.TopProperty, p.Position.Y);
                Canvas.AddChild(label);

                if (!string.IsNullOrWhiteSpace(p.StringValue))
                {
                    var txt = new TextBlock()
                    {
                        TextWrapping        = TextWrapping.Wrap, TextAlignment = TextAlignment.Left, Text = p.StringValue, MaxWidth = legwidth,
                        VerticalAlignment   = VerticalAlignment.Center,
                        HorizontalAlignment = HorizontalAlignment.Left,
                        FontWeight          = FontWeights.Bold,
                        Foreground          = new SolidColorBrush(p.ForeColor.Value)
                    };
                    var grid = new Grid()
                    {
                        Width = legwidth, Height = itemHeight
                    };
                    grid.Children.Add(txt);
                    grid.SetValue(System.Windows.Controls.Canvas.LeftProperty, p.Position.X + p.Width + 8);
                    grid.SetValue(System.Windows.Controls.Canvas.TopProperty, p.Position.Y);
                    Canvas.AddChild(grid);
                }
                index++;
                lastFig = fig;
            }

            return(base.CreatePath());
        }