原文:Silverlight 雷达图和一种特殊泡泡画法

自上次发了雷达图,也没怎么说一下。

这次又做了一种图,继续共享一下,就是以一个点为中心,周围绕着几个点,用一个箭头与中心相连并带有某些信息。圆 和中心都可以响应鼠标事件。

我一向不会讲解所做的东西。所以大部分我直接上源码的。

简单讲解一下:

代码结构分为4部分,

1.

首先是画布,其实就是一个canvas因为现在只有二种图,

一个雷达画布 RadarCanvas(比较特殊),和一个二维坐标画布 CoorCanvas,都派生自ChartCanvas;

2.就是轴

坐标轴CoorAxis 和RadarAxis 都派生自IAxis,其实里面什么也没有。就是一个存一些值,比较这个轴的颜色,它的起始与终结坐标。雷达轴的角度偏移等,。

3.model

存值的类了,暂时有 clm泡泡图的点击事件参数 CLMArrowClickEventArg,DataPoint图坐标点,图点点击事件参数ItemClickEventArg,字段映射ItemMapping

4.图形

现有CLMBubbleSeries,它是一个特殊的泡泡图,我们项目中用到的。这里就不说它有什么用。只讲实现。

RadarSeries,它就是雷达图形

它们都继承自ISeries

核心就是讲Series怎么画的

 

首先看它们的基类:

  1. /// <summary>
  2. /// 图表线或图接口
  3. /// </summary>
  4. public abstract class ISeries : Common.IBaseControl
  5. {
  6. public ISeries(ChartCanvas canvas)
  7. {
  8. Canvas = canvas;
  9.  
  10. Points = new System.Collections.ObjectModel.ObservableCollection<Model.DataPoint>();
  11.  
  12. ItemMappings = new System.Collections.ObjectModel.ObservableCollection<Model.ItemMapping>();
  13. }
  14.  
  15. /// <summary>
  16. /// 动画执行时间
  17. /// </summary>
  18. protected const int AnimateDurtion = ;
  19.  
  20. /// <summary>
  21. /// 项单击事件
  22. /// </summary>
  23. public EventHandler<Model.ItemClickEventArg> ItemClick;
  24.  
  25. /// <summary>
  26. /// 画布
  27. /// </summary>
  28. public ChartCanvas Canvas { get; set; }
  29.  
  30. /// <summary>
  31. /// 当前颜色
  32. /// </summary>
  33. public Brush Stroke
  34. {
  35. get;
  36. set;
  37. }
  38.  
  39. /// <summary>
  40. /// 填充色
  41. /// </summary>
  42. public Brush Fill
  43. {
  44. get;
  45. set;
  46. }
  47.  
  48. /// <summary>
  49. /// 图例名
  50. /// </summary>
  51. public string LegendLabel
  52. {
  53. get;
  54. set;
  55. }
  56.  
  57. /// <summary>
  58. /// 当前线的label格式
  59. /// /// #Y=当前值,#YName=当前Y轴名称,#C{列名}=表示绑定当前数据对象的指定列值
  60. /// </summary>
  61. public string ItemTooltipFormat { get; set; }
  62.  
  63. /// <summary>
  64. /// 当前绑定的对象
  65. /// </summary>
  66. public object DataContext { get; set; }
  67.  
  68. /// <summary>
  69. /// 当前索引
  70. /// </summary>
  71. public int Index { get; set; }
  72.  
  73. /// <summary>
  74. /// 图点
  75. /// </summary>
  76. public System.Collections.ObjectModel.ObservableCollection<Model.DataPoint> Points { get; set; }
  77.  
  78. /// <summary>
  79. /// 当前图型属性映射
  80. /// </summary>
  81. public System.Collections.ObjectModel.ObservableCollection<Model.ItemMapping> ItemMappings
  82. {
  83. get;
  84. internal set;
  85. }
  86.  
  87. /// <summary>
  88. /// 获取对象的属性的值
  89. /// </summary>
  90. /// <param name="name"></param>
  91. /// <returns></returns>
  92. public object GetValue(string name)
  93. {
  94. var mapping = GetMapping(name);
  95. if (mapping != null) name = mapping.MemberName;
  96.  
  97. var obj = Common.Helper.GetPropertyName(DataContext, name);
  98. return obj;
  99. }
  100.  
  101. /// <summary>
  102. /// 获取对象的值
  103. /// </summary>
  104. /// <param name="name">属性名</param>
  105. /// <returns></returns>
  106. public double GetNumberValue(string name)
  107. {
  108. double value = ;
  109. var obj = GetValue(name);
  110. if (obj != null)
  111. {
  112. if (Silverlight.Common.Data.TypeHelper.IsNumber(obj.GetType()))
  113. {
  114. if (!double.TryParse(obj.ToString(), out value))
  115. {
  116. value = Index + ;
  117. }
  118. }
  119. else
  120. {
  121. value = Index + ;
  122. }
  123. }
  124. return value;
  125. }
  126.  
  127. /// <summary>
  128. /// 获取指定的字段映射
  129. /// </summary>
  130. /// <param name="dm"></param>
  131. /// <returns></returns>
  132. public Model.ItemMapping GetMapping(Model.ItemMapping.EnumDataMember dm)
  133. {
  134. foreach (var m in ItemMappings)
  135. {
  136. if (m.DataMember == dm) return m;
  137. }
  138. return null;
  139. }
  140.  
  141. /// <summary>
  142. /// 获取指定的字段映射
  143. /// </summary>
  144. /// <param name="dm"></param>
  145. /// <returns></returns>
  146. public Model.ItemMapping GetMapping(string name)
  147. {
  148. foreach (var m in ItemMappings)
  149. {
  150. if (name.Equals(m.OldName, StringComparison.OrdinalIgnoreCase) ||
  151. name.Equals(m.MemberName, StringComparison.OrdinalIgnoreCase) ||
  152. name.Equals(m.DisplayName, StringComparison.OrdinalIgnoreCase))
  153. return m;
  154. }
  155. return null;
  156. }
  157.  
  158. /// <summary>
  159. /// 获取指定的字段映射
  160. /// </summary>
  161. /// <param name="dm"></param>
  162. /// <returns></returns>
  163. public System.Collections.Generic.IEnumerable<Model.ItemMapping> GetMappings(Model.ItemMapping.EnumDataMember dm)
  164. {
  165. var ms = (from m in ItemMappings
  166. where m.DataMember == dm
  167. select m).ToArray<Model.ItemMapping>();
  168. return ms;
  169. }
  170.  
  171. /// <summary>
  172. /// 当前动画
  173. /// </summary>
  174. protected Storyboard storyboard;
  175.  
  176. /// <summary>
  177. /// 展现
  178. /// </summary>
  179. public virtual void Draw()
  180. {
  181. var ps = CreatePath();
  182. foreach (var p in ps)
  183. {
  184. Canvas.AddChild(p);
  185. }
  186. if (storyboard != null && Canvas.IsAnimate)
  187. {
  188. storyboard.Begin();
  189. }
  190. }
  191.  
  192. System.Collections.Generic.List<Shape> shaps=new System.Collections.Generic.List<Shape>();
  193. /// <summary>
  194. /// 当前线条
  195. /// </summary>
  196. public System.Collections.Generic.List<Shape> Shaps
  197. {
  198. get { return shaps; }
  199. protected set { shaps = value; }
  200. }
  201.  
  202. /// <summary>
  203. /// 生成图形
  204. /// </summary>
  205. /// <returns></returns>
  206. public virtual System.Collections.Generic.IEnumerable<Shape> CreatePath()
  207. {
  208. return Shaps;
  209. }
  210.  
  211. /// <summary>
  212. /// 生成图例
  213. /// </summary>
  214. /// <returns></returns>
  215. internal virtual StackPanel CreateLegend()
  216. {
  217. if (!string.IsNullOrWhiteSpace(LegendLabel))
  218. {
  219. var panel = new StackPanel();
  220. panel.Orientation = Orientation.Horizontal;
  221. var colorarea = new Rectangle();
  222. colorarea.Width = ;
  223. colorarea.Height = ;
  224. colorarea.Fill = this.Fill;
  225. colorarea.Stroke = this.Stroke;
  226. panel.Margin = new Thickness();
  227. panel.Children.Add(colorarea);
  228.  
  229. var text = new TextBlock();
  230. text.Margin = new Thickness();
  231.  
  232. var dic=new System.Collections.Generic.Dictionary<string,string>();
  233. foreach (var m in ItemMappings)
  234. {
  235. if (!dic.ContainsKey("YName") && !string.IsNullOrWhiteSpace(m.DisplayName))
  236. {
  237. dic.Add("YName", m.DisplayName??m.MemberName);
  238. }
  239. }
  240.  
  241. text.Text = Common.Helper.DserLabelName(LegendLabel,dic ,
  242. (string name) =>
  243. {
  244. return GetValue(name);
  245. });
  246. text.Foreground = new SolidColorBrush(Colors.Black);
  247. panel.Children.Add(text);
  248.  
  249. return panel;
  250. }
  251. return null;
  252. }
  253.  
  254. /// <summary>
  255. /// 添加点的小圆圈,方便鼠标点中。并加提示
  256. /// </summary>
  257. /// <param name="center"></param>
  258. /// <param name="rotate"></param>
  259. protected Ellipse AddPoint(Point center, double rotate,object tooltip,Model.DataPoint p)
  260. {
  261. var circle = Common.Helper.CreateEllipse(center, rotate);
  262. circle.Stroke = this.Stroke;
  263. circle.Fill = this.Fill;
  264. ToolTipService.SetToolTip(circle, tooltip);
  265.  
  266. if (this.ItemClick != null) {
  267. circle.Cursor = Cursors.Hand;
  268. circle.MouseLeftButtonUp += (sender, e) => {
  269. var arg = new Model.ItemClickEventArg() {
  270. Data=this.DataContext,
  271. Item=p
  272. };
  273. ItemClick(circle,arg);
  274. };
  275. }
  276.  
  277. Canvas.AddChild(circle);
  278.  
  279. System.Windows.Controls.Canvas.SetZIndex(circle, Common.BaseParams.TooltipZIndex);
  280.  
  281. return circle;
  282. }
  283.  
  284. /// <summary>
  285. /// 生成提示信息
  286. /// #Y=当前值,#YName=当前Y轴名称,#C{列名}=表示绑定当前数据对象的指定列值
  287. /// </summary>
  288. /// <returns></returns>
  289. protected string CreateTooltip(string yName)
  290. {
  291. if (!string.IsNullOrWhiteSpace(this.ItemTooltipFormat))
  292. {
  293. var yvalue = GetValue(yName);
  294. var tmp = Common.Helper.DserLabelName(this.ItemTooltipFormat,
  295. new System.Collections.Generic.Dictionary<string, string>() { { "YName", yName }, { "Y", yvalue==null?"":yvalue.ToString() } },
  296. (string name) =>
  297. {
  298. return GetValue(name);
  299. });
  300. return tmp;
  301. }
  302. return this.ItemTooltipFormat;
  303. }
  304.  
  305. public void Show()
  306. {
  307. throw new NotImplementedException();
  308. }
  309.  
  310. public void Hide()
  311. {
  312. throw new NotImplementedException();
  313. }
  314. }

嗯。没有很多东西,都是一些基础操作,和几个接口。

下面就可以看泡泡图CLMBubbleSeries:

其构造函数:

  1. public CLMBubbleSeries(CoorCanvas canvas)
  2. : base(canvas) {
  3. this.Stroke = new SolidColorBrush(Color.FromArgb(, , , ));
  4. this.Fill = new SolidColorBrush(Color.FromArgb(, , , ));
  5. }

初始化它的颜色。

最重要的是二个函数

  1. /// <summary>
  2. /// 生成当前图形
  3. /// </summary>
  4. /// <returns></returns>
  5. public override System.Collections.Generic.IEnumerable<Shape> CreatePath()
  6. {
  7. if (storyboard != null) storyboard.Stop();
  8. if (Canvas.IsAnimate) this.storyboard = new Storyboard();
  9.  
  10. this.Shaps.Clear();
  11. if (DataContext == null) return base.CreatePath();
  12. var data = DataContext as System.Collections.ICollection;
  13.  
  14. var circlesize = data.Count > ? circleSize / data.Count * : circleSize;
  15. var center=new Point() { X = this.Canvas.Width / , Y = centerSize * 2.3 };
  16. var left = Canvas.Margin.Left + circlesize * ;
  17. if (left <= circlesize / ) left = circlesize + ;
  18. var bottom = (center.Y + circlesize + centerSize);
  19. var maxbottom = Canvas.Height - Canvas.Margin.Bottom - circlesize - ;
  20. //距离中心距离
  21. var radiacenter = Math.Min(center.X - left, maxbottom);
  22. var circleIndex = -;
  23.  
  24. //小圆个数
  25. var circlecount = data.Count;
  26. var rotatestep = 3.78 / circlecount;//每个小圆的角度
  27. var mapping = GetMapping(Model.ItemMapping.EnumDataMember.Y);
  28.  
  29. if (mapping == null) throw new Exception("至少需要指定一个Y轴字段映射");
  30. //与中心点关联设置
  31. var links = GetMappings(Model.ItemMapping.EnumDataMember.CLMLink);
  32.  
  33. var tocentername="";
  34. //画泡泡
  35. foreach (var m in data)
  36. {
  37. if (m != null)
  38. {
  39. var item = new Model.DataPoint();
  40.  
  41. item.PotinShape= new Path();
  42. var v = Common.Helper.GetPropertyName(m, mapping.MemberName); ;
  43. item.PointType = Model.DataPoint.EnumPointType.ChartPoint;
  44. item.StringValue = v==null?"":v.ToString();
  45. System.Windows.Controls.Canvas.SetZIndex(item.PotinShape, Common.BaseParams.ShapZIndex);
  46.  
  47. var el = new EllipseGeometry();
  48. item.PotinShape.Data = el;
  49.  
  50. //画中心位置
  51. if (circleIndex == -)
  52. {
  53. item.Position = el.Center = center;
  54. el.RadiusX = el.RadiusY = centerSize;
  55. item.Width = item.Height = centerSize * ;
  56. tocentername = item.StringValue;
  57. item.StringValue =(CenterName??mapping.MemberName) + "\n" + item.StringValue;
  58.  
  59. var label = item.CreateLabel();
  60. //加入标签
  61. Canvas.AddChild(label);
  62.  
  63. if (ItemClick != null)
  64. {
  65. label.Cursor = Cursors.Hand;
  66. var centerdata = m;
  67. label.MouseLeftButtonUp += (sender, e) =>
  68. {
  69. var arg = new Model.ItemClickEventArg()
  70. {
  71. Data = centerdata,
  72. Item = item
  73. };
  74. ItemClick(sender, arg);
  75. };
  76. }
  77.  
  78. var tootip = CreateTooltip(m);
  79. ToolTipService.SetToolTip(label,tootip);
  80. }
  81. //画边上的小圆
  82. else
  83. {
  84. //初始化小圆点
  85. InitPoint(el, item, rotatestep, circleIndex, radiacenter, center, maxbottom, circlesize, tocentername,circlecount,links,m);
  86. }
  87.  
  88. if(Canvas.IsFillShape)item.PotinShape.Fill = this.Fill;
  89. item.PotinShape.Stroke = this.Stroke;
  90. item.PotinShape.StrokeThickness = Canvas.LineWidth;
  91. this.Shaps.Add(item.PotinShape);
  92.  
  93. circleIndex++;
  94. }
  95. }
  96.  
  97. return base.CreatePath();
  98. }

画一个中心圆 ,和用InitPoint来画周围的小圆。

  1. /// <summary>
  2. /// 初始化项
  3. /// </summary>
  4. /// <param name="el"></param>
  5. /// <param name="item"></param>
  6. /// <param name="rotatestep"></param>
  7. /// <param name="circleIndex"></param>
  8. /// <param name="radiacenter"></param>
  9. /// <param name="center"></param>
  10. /// <param name="maxbottom"></param>
  11. /// <param name="circlesize"></param>
  12. /// <param name="tocentername"></param>
  13. private void InitPoint(EllipseGeometry el,Model.DataPoint item,
  14. double rotatestep, int circleIndex, double radiacenter, Point center,
  15. double maxbottom, double circlesize, string tocentername, int circlecount,
  16. System.Collections.Generic.IEnumerable<Model.ItemMapping> links,object data)
  17. {
  18. var position = new Point();
  19. var rotate = rotatestep * circleIndex + 2.95;
  20. var rsin = Math.Sin(rotate);
  21. var rcos = Math.Cos(rotate);
  22. //二圆偏移量
  23. var ystep = rsin * radiacenter;
  24. var xstep = rcos * radiacenter;
  25.  
  26. position.X = center.X + xstep;
  27. position.Y = center.Y - ystep;
  28.  
  29. if (position.Y >= maxbottom) position.Y = maxbottom;
  30.  
  31. item.Position = position;
  32. el.RadiusX = el.RadiusY = circlesize;
  33. item.Width = item.Height = circlesize * ;
  34.  
  35. var arrow = new Controls.CLMArrow(Canvas);
  36. arrow.Fill = this.Fill;
  37. arrow.Stroke = this.Stroke;
  38. arrow.Rotate = rotate;
  39. arrow.ToName = tocentername;
  40. arrow.FromName = item.StringValue;
  41. arrow.RotateSin = rsin;
  42. arrow.RotateCos = rcos;
  43.  
  44. var startystep = (circlesize) * arrow.RotateSin;
  45. var startxstep = (circlesize) * arrow.RotateCos;
  46. arrow.StartPoint = new Point(item.Position.X - startxstep, item.Position.Y + startystep);
  47. var endystep = centerSize * arrow.RotateSin;
  48. var endxstep = centerSize * arrow.RotateCos;
  49. arrow.EndPoint = new Point(center.X + endxstep, center.Y - endystep);
  50.  
  51. if (links != null)
  52. {
  53. var count = links.Count<Model.ItemMapping>();
  54. if (count > )
  55. {
  56. var lnk = links.ElementAt<Model.ItemMapping>();
  57. var tmp = Common.Helper.GetPropertyName(data, lnk.MemberName);
  58. if (!string.IsNullOrWhiteSpace(lnk.MarkName)) arrow.FromMarkName = lnk.MarkName;
  59. arrow.FromValue = tmp == null ? "" : tmp.ToString();
  60. }
  61. if (count > )
  62. {
  63. var lnk = links.ElementAt<Model.ItemMapping>();
  64. var tmp = Common.Helper.GetPropertyName(data, lnk.MemberName);
  65. if (!string.IsNullOrWhiteSpace(lnk.MarkName)) arrow.ToMarkName = lnk.MarkName;
  66. arrow.ToValue = tmp == null ? "" : tmp.ToString();
  67. }
  68. }
  69.  
  70. //设置箭头提示事件
  71. if (ArrowTooltipClick != null) arrow.SetClickEvent(ArrowTooltipClick);
  72.  
  73. arrow.Draw();
  74. item.TargetControl = arrow;
  75.  
  76. var label = item.CreateLabel();
  77. Canvas.AddChild(label);
  78.  
  79. if (ItemClick != null)
  80. {
  81. label.Cursor = Cursors.Hand;
  82. label.MouseLeftButtonUp += (sender, e) =>
  83. {
  84. var arg = new Model.ItemClickEventArg()
  85. {
  86. Data = data,
  87. Item = item
  88. };
  89. ItemClick(sender, arg);
  90. };
  91. }
  92.  
  93. if (Canvas.IsAnimate)
  94. {
  95. label.Visibility = Visibility.Collapsed;
  96. var anima = new PointAnimation();
  97. anima.To = position;
  98. anima.Duration = TimeSpan.FromMilliseconds(AnimateDurtion);
  99.  
  100. Storyboard.SetTarget(anima, el);
  101. el.Center = center;
  102. Storyboard.SetTargetProperty(anima, new PropertyPath("Center"));
  103.  
  104. var sizeanimax = new DoubleAnimation();
  105. sizeanimax.From = ;
  106. sizeanimax.To = circlesize;
  107. Storyboard.SetTarget(sizeanimax, el);
  108. Storyboard.SetTargetProperty(sizeanimax, new PropertyPath("RadiusX"));
  109.  
  110. var sizeanimay = new DoubleAnimation();
  111. sizeanimay.From = ;
  112. sizeanimay.To = circlesize;
  113. Storyboard.SetTarget(sizeanimay, el);
  114. Storyboard.SetTargetProperty(sizeanimay, new PropertyPath("RadiusY"));
  115.  
  116. anima.Completed += new EventHandler((sender, e) =>
  117. {
  118. label.Visibility = Visibility.Visible;
  119. InitMouseEvent(label, arrow);
  120. if (circleIndex == circlecount / - ) {
  121. arrow.Show();
  122. currentShowedArrow = arrow;
  123. }
  124. });
  125. this.storyboard.Children.Add(anima);
  126. this.storyboard.Children.Add(sizeanimax);
  127. this.storyboard.Children.Add(sizeanimay);
  128. }
  129. else
  130. {
  131. el.Center = position;
  132. //加入标签
  133. //var label = item.CreateLabel();
  134. //Canvas.AddChild(label);
  135. InitMouseEvent(label, arrow);
  136. if (circleIndex == circlecount / - ) {
  137. arrow.Show();
  138. currentShowedArrow = arrow;
  139. }
  140. }
  141. }

最后是画坐标图代码:

  1. /// <summary>
  2. /// 画坐标图
  3. /// </summary>
  4. private void DrawCoor()
  5. {
  6. if (!IsDrawBaseLine) return;
  7.  
  8. coorGeometry.Figures.Clear();
  9.  
  10. var xaxis = new Axis.CoorAxis();
  11. xaxis.AxisShap = coorPath;
  12. xaxis.AType = Axis.AxisType.XValue;
  13.  
  14. var yaxis = new Axis.CoorAxis();
  15. yaxis.AType = Axis.AxisType.YValue;
  16. yaxis.AxisShap = coorPath;
  17.  
  18. this.Axises.Add(xaxis);
  19. this.Axises.Add(yaxis);
  20.  
  21. var coorfigure = new PathFigure();
  22. coorGeometry.Figures.Add(coorfigure);
  23.  
  24. //画上箭头
  25. yaxis.StartPoint = coorfigure.StartPoint = new Point(Margin.Left, Margin.Top - arrowMargin);
  26. var tlp = new Point() { X = Margin.Left - arrowMargin, Y = Margin.Top + arrowMargin };
  27. coorfigure.Segments.Add(new LineSegment() { Point = tlp });
  28. coorfigure.Segments.Add(new LineSegment() { Point = tlp });
  29. coorfigure.Segments.Add(new LineSegment() { Point = coorfigure.StartPoint });
  30. var trp = new Point() { X = Margin.Left + arrowMargin, Y = Margin.Top + arrowMargin };
  31. coorfigure.Segments.Add(new LineSegment() { Point = trp });
  32. coorfigure.Segments.Add(new LineSegment() { Point = trp });
  33. coorfigure.Segments.Add(new LineSegment() { Point = coorfigure.StartPoint });
  34.  
  35. //左侧Y轴
  36. yaxis.EndPoint = xaxis.StartPoint = new Point() { X = Margin.Left, Y = this.Height - Margin.Bottom };
  37. coorfigure.Segments.Add(new LineSegment() { Point = xaxis.StartPoint });
  38. //x轴
  39. xaxis.EndPoint = new Point() { X = this.Width - Margin.Right + arrowMargin, Y = xaxis.StartPoint.Y };
  40. coorfigure.Segments.Add(new LineSegment() { Point = xaxis.EndPoint });
  41.  
  42. //画右箭头
  43. var brtp = new Point() { X = this.Width - Margin.Right - arrowMargin, Y = xaxis.EndPoint.Y - arrowMargin };
  44. var brbp = new Point() { X = brtp.X, Y = xaxis.EndPoint.Y + arrowMargin };
  45. coorfigure.Segments.Add(new LineSegment() { Point = brtp });
  46. coorfigure.Segments.Add(new LineSegment() { Point = brtp });
  47. coorfigure.Segments.Add(new LineSegment() { Point = xaxis.EndPoint });
  48. coorfigure.Segments.Add(new LineSegment() { Point = brbp });
  49. coorfigure.Segments.Add(new LineSegment() { Point = brbp });
  50.  
  51. AddChild(coorPath);
  52.  
  53. DrawLine();//画虚线
  54. }
  55.  
  56. /// <summary>
  57. /// 画虚线
  58. /// </summary>
  59. private void DrawLine()
  60. {
  61. var w = this.Width - Margin.Left - Margin.Right;
  62. var h = this.Height - Margin.Top - Margin.Bottom;
  63.  
  64. var vstep = h / HorizontalCount;
  65.  
  66. for (var i = ; i <= HorizontalCount; i++)
  67. {
  68. var l = new Line();
  69. l.StrokeLineJoin = PenLineJoin.Round;
  70. l.StrokeDashArray.Add();
  71. l.Stroke = DashColor;
  72. l.StrokeThickness = ;
  73. l.X1 = Margin.Left;
  74. l.Y1 = this.Height - Margin.Bottom - (vstep * i);
  75. l.X2 = this.Width - Margin.Right;
  76. l.Y2 = l.Y1;
  77. AddChild(l);
  78. }
  79.  
  80. var xstep = w / VerticalCount;
  81. for (var i = ; i <= VerticalCount; i++)
  82. {
  83. var l = new Line();
  84. l.Stroke = DashColor;
  85. l.StrokeDashArray.Add();
  86. l.StrokeThickness = ;
  87. l.X1 = Margin.Left + xstep * i;
  88. l.Y1 = Margin.Top;
  89. l.X2 = l.X1;
  90. l.Y2 = this.Height - Margin.Bottom;
  91. AddChild(l);
  92. }

啊。我是正的不太会讲解。直接上源码算了

源码地址:源码

Silverlight 雷达图和一种特殊泡泡画法的更多相关文章

  1. JavaScript数据可视化编程学习(二)Flotr2,雷达图

    一.雷达图 使用雷达图显示多维数据. 如果你有多维的数据要展示,那么雷达图就是一种非常有效的可视化方法. 由于雷达图不常用,比较陌生,所以向用户解释的时候有一些难度.注意使用雷达图会增加用户认知负担. ...

  2. 第三方Charts绘制图表四种形式:饼状图,雷达图,柱状图,直线图

    对于第三方框架Charts(Swift版本,在OC项目中需要添加桥接头文件),首先要解决在项目中集成的问题,集成步骤: 一.下载Charts框架 下载地址:https://github.com/dan ...

  3. [2014.01.27]wfRadar 雷达图组件 2.5

    全新开发的雷达图组件--wfRadar,使用简单,功能强大,图像处理效果极佳. 组件支持多种图片格式,包括bmp,jpg,gif,wmf,emf,ico,png,pcx,tif,tga,pcx,dcx ...

  4. 利用d3.js绘制雷达图

    利用d3,js将数据可视化,能够做到数据与代码的分离.方便以后改动数据. 这次利用d3.js绘制了一个五维的雷达图.即将多个对象的五种属性在一张图上对照. 数据写入data.csv.数据类型写入typ ...

  5. echarts雷达图点击事件

    最近看见别人问的问题,点击雷达图的拐点,获取点击数据的问题,直接上代码. echarts配置问题:https://www.douban.com/note/509404582/ <!doctype ...

  6. Echarts数据可视化series-radar雷达图,开发全解+完美注释

    全栈工程师开发手册 (作者:栾鹏) Echarts数据可视化开发代码注释全解 Echarts数据可视化开发参数配置全解 6大公共组件详解(点击进入): title详解. tooltip详解.toolb ...

  7. echarts雷达图点击事件 包含(2.x,3.85,4.02)测试

    最近看见别人问的问题,点击雷达图的拐点,获取点击数据的问题,直接上代码. echarts 2x 的点击事件 echarts配置问题:https://www.douban.com/note/509404 ...

  8. HTML5 Canvas制作雷达图实战

    雷达图又叫蜘蛛网图,是一种对各项数据查看很明显的表现图,在很多游戏中,对游戏中的每个角色的分析图一般也用这种图. 下面,用HTML5的Cavas来实现雷达图. 效果 一.创建Canvas var mW ...

  9. <Android 应用 之路> MPAndroidChart~BubbleChart(气泡图) and RadarChart(雷达图)

    简介 MPAndroidChart是PhilJay大神给Android开发者带来的福利.MPAndroidChart是一个功能强大并且使用灵活的图表开源库,支持Android和iOS两种,这里我们暂时 ...

随机推荐

  1. COCOS2D-X FRAME动画创作随笔

    CCAnimate继承CCActionInterval,和CCAnimate是一家action,有着action所有的属性和方法. CCAnimate一些重要的方法: static CCAnimate ...

  2. Java爬虫,信息抓取的实现(转)

    转载请注明出处:http://blog.csdn.net/lmj623565791/article/details/23272657 今天公司有个需求,需要做一些指定网站查询后的数据的抓取,于是花了点 ...

  3. BZOJ 2435 NOI2011 道路建设 BFS/DFS

    标题效果:给定一个树(直接将树.不要贪图生成树图!).寻找每条边权值*分差的两侧之间 BFS水必须是能 竟DFS能够住...系统堆栈可能有些不够,我们可以使用内联汇编手册中大型系统堆栈 详见代码 这个 ...

  4. linux下getsockopt和setsockopt具体解释及測试

    linux下getsockopt和setsockopt具体解释及測试 NAME 名字 getsockopt, setsockopt - get and set options on sockets 获 ...

  5. android 内存泄漏分析技巧

    java虚拟机执行一般都有一个内存界限,超过这个界限,就会报outofmemory.这个时候一般都是存在内存泄漏.解决内存泄漏问题,窃以为分为两个步骤:分析应用程序是否真的有内存泄漏,找到内存泄漏的地 ...

  6. 全栈JavaScript路(八)得知 CDATASection 种类 节点

    CDATASection 只船舶类型节点 基于XML 文件.演出CDATA 数据. 构造函数: CDATASection function(){[native code]} CDATASection ...

  7. Android Context MODE的四种模式解析(转)

    Context.MODE_PRIVATE:为默认操作模式,代表该文件是私有数据,只能被应用本身访问,在该模式下,写入的内容会覆盖原文件的内容,如果想把新写入的内容追加到原文件中.可以使用Context ...

  8. cocos2d-x 网络请求

    [cocos2dx]rapidjson用法以及中文显示的解决方法 cocos2dx 读取json及解析 cocos2dx rapidjson 高速解析JSON  --- [cocos2d-x官方文档] ...

  9. Chromium Graphics: GPUclient的原理和实现分析之间的同步机制-Part I

    摘要:Chromium于GPU多个流程架构的同意GPUclient这将是这次访问的同时GPU维修,和GPUclient这之间可能存在数据依赖性.因此必须提供一个同步机制,以确保GPU订购业务.本文讨论 ...

  10. 1023 Train Problem II(卡特兰数)

    Problem Description As we all know the Train Problem I, the boss of the Ignatius Train Station want ...