/// <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); }
/// <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()); }
/// <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()); }
/// <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()); }
/// <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; } } }
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()); }