(一). 概述
本文主要演示一个比较简单的 WebChart 柱状实现, 可以一方面了解一个较完整的控件开发实例,
里面用到了复合样式及视图存储等内容. 另一方面了解一下WebChart的实现原理. 在Web开发中, 最终
是用浏览器呈现各种图表, 图表控件呈现过程是 根据控件提供的属性接口接收到数据参数, 用最基本的
Html元素
来呈现图表.
注: 本文参考 [Asp.net 2.0高级编程] 方案, 由于本书中配套代码说明链接打不开, 所以在文章最后面可以 下载我上传的自己做得比较完整的示例代码.
(二). 运行效果 1. 在浏览器中运行的柱状图
2. 主要属性 ( 可以通过修改这些属性参数修改其 外观样式和文本显示格式等信息)
主要属性用法介绍:
(三). 代码 代码比较简单, 就两个文件; 主要代码, 都包含了中文注释. 在这里对代码不作多介绍. 1. 主控件文件 SimpleGaugeBar.cs 代码 1 namespace KingControls
2 { 3 /// 4 /// Author: [ ChengKing(ZhengJian) ] 5 /// Blog: Http://blog.csdn.net/ChengKing 6 /// 本代码 参照 Asp.net 2.0高级编程 方案 7 /// 8 [DefaultProperty("Value")] 9 [ToolboxData("{0}:SimpleGaugeBar>")] 10 [PersistChildrenAttribute(false)] 11 public class SimpleGaugeBar : CompositeControl 12 { 13 //在绘制输出画面时,标志是哪个TD为分界点(从这个分界点改变表格的颜色绘制) 14 private int _intDividerCell; 15 16 private TextItemStyle _textStyle; 17 18 public SimpleGaugeBar() 19 { 20 } 21 22 #region 属性 23 /// 24 /// 进度条值 25 /// 26 public float Value 27 { 28 get 29 { 30 object o = ViewState["Value"]; 31 if (o == null) 32 return 0; 33 return float.Parse(o.ToString()); 34 } 35 set 36 { 37 this.ViewState["Value"] = value; 38 if (value > Maximum) 39 { 40 this.ViewState["Value"] = Maximum; 41 } 42 } 43 } 44 45 /// 46 /// 全值 47 /// 48 public float Maximum 49 { 50 get 51 { 52 object o = this.ViewState["Maximum"]; 53 if (o == null) 54 { 55 return 100; 56 } 57 return float.Parse(o.ToString()); 58 } 59 set 60 { 61 this.ViewState["Maximum"] = value; 62 } 63 } 64 65 /// 66 /// 表示进度条分几段 67 /// 68 public int Segments 69 { 70 get 71 { 72 object o = this.ViewState["Segments"]; 73 if (o == null) 74 { 75 return 4; 76 } 77 return int.Parse(o.ToString()); 78 } 79 set 80 { 81 this.ViewState["Segments"] = value; 82 if (value 1) 83 { 84 this.ViewState["Segments"] = 1; 85 } 86 } 87 } 88 89 /// 90 /// 文本呈现格式 91 /// 92 public string FormatString 93 { 94 get 95 { 96 object o = this.ViewState["FormatString"]; 97 if (o == null) 98 { 99 return "{0}/{1}"; 100 } 101 return (string)o; 102 } 103 set 104 { 105 this.ViewState["FormatString"] = value; 106 } 107 } 108 109 public bool GridLines 110 { 111 get 112 { 113 object o = this.ViewState["GridLines"]; 114 if (o == null) 115 { 116 return true; 117 } 118 return (bool)o; 119 } 120 set 121 { 122 this.ViewState["GridLines"] = value; 123 } 124 } 125 126 [PersistenceMode(PersistenceMode.EncodedInnerDefaultProperty)] 127 [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 128 [NotifyParentProperty(true)] 129 public TextItemStyle TextStyle 130 { 131 get 132 { 133 if (_textStyle == null) 134 { 135 _textStyle = new TextItemStyle(); 136 } 137 if (IsTrackingViewState) 138 { 139 ((IStateManager)_textStyle).TrackViewState(); 140 } 141 return _textStyle; 142 } 143 } 144 145 #endregion 146 147 #region 方法 148 149 protected override void Render(HtmlTextWriter writer) 150 { 151 PrepareControlForRendering(); 152 base.Render(writer); 153 154 //base.RenderContents(writer); 155 //this.RenderContents(writer); 156 //this.Render(writer); 157 158 } 159 160 protected override void CreateChildControls() 161 { 162 //base.CreateChildControls(); 163 this.Controls.Clear(); 164 CreateControlHierarchy(); 165 ClearChildViewState(); 166 } 167 168 /// 169 /// 在Web开发中,用Table/TR/TD来表示图形输出 170 /// 171 protected virtual void CreateControlHierarchy() 172 { 173 //最外层表格 174 Table outer = new Table(); 175 TableRow outerRow = new TableRow(); 176 outer.Rows.Add(outerRow); 177 178 TableCell rulerCell = new TableCell(); 179 outerRow.Cells.Add(rulerCell); 180 BuildGaugeBar(rulerCell); 181 182 //根据条件增加文本显示单元格 183 TableCell textCell = new TableCell(); 184 if (!TextStyle.DisplayTextAtBottom) 185 { 186 outerRow.Cells.Add(textCell); 187 BuildLabel(textCell); 188 } 189 190 this.Controls.Add(outer); 191 192 if (!TextStyle.RenderInsideTable && TextStyle.DisplayTextAtBottom) 193 { 194 BuildLabel(null); 195 } 196 } 197 198 /// 199 /// 用Label来呈现文本,如: { 8/10 } 200 /// 201 /// 202 void BuildLabel(TableCell tc) 203 { 204 float buf = GetValueToRepresent(); 205 string msg = GetTextToRepresent(); 206 207 Label lbl = new Label(); 208 if (tc is TableCell) 209 { 210 tc.Controls.Add(lbl); 211 } 212 else 213 { 214 this.Controls.Add(lbl); 215 } 216 lbl.Text = String.Format(msg, buf, Maximum); 217 } 218 219 void BuildGaugeBar(TableCell tc) 220 { 221 Table t = new Table(); 222 TableRow tr = new TableRow(); 223 t.Rows.Add(tr); 224 225 BuildRuler(tr); 226 227 if (TextStyle.RenderInsideTable) 228 { 229 BuildLabelIntoTable(t); 230 } 231 tc.Controls.Add(t); 232 } 233 234 void BuildRuler(TableRow ruler) 235 { 236 float val = GetValueToRepresent(); 237 float valueToRepresent = 100f * val / Maximum; 238 int numOfSegments = GetNumOfSegments(); 239 int segmentWidth = 100 / numOfSegments; 240 bool finished = false; 241 for (int i = 1; i numOfSegments; i++) 242 { 243 if (valueToRepresent i * segmentWidth) 244 { 245 if (finished) 246 { 247 TableCell stillToDo = new TableCell(); 248 ruler.Cells.Add(stillToDo); 249 stillToDo.Width = Unit.Percentage(segmentWidth); 250 } 251 else 252 { 253 _intDividerCell = i - 1; 254 TableCell cell = new TableCell(); 255 ruler.Cells.Add(cell); 256 cell.Width = Unit.Percentage(segmentWidth); 257 cell.Height = Unit.Percentage(100); 258 259 //增加子表 260 Table child = new Table(); 261 child.Width = Unit.Percentage(100); 262 child.Height = Unit.Percentage(100); 263 cell.Controls.Add(child); 264 child.CellPadding = 0; 265 child.CellSpacing = 0; 266 TableRow childRow = new TableRow(); 267 child.Rows.Add(childRow); 268 269 float fx = (100 * (valueToRepresent - segmentWidth * (i - 1)) / segmentWidth); 270 if (valueToRepresent > (i - 1) * segmentWidth) 271 { 272 TableCell left = new TableCell(); 273 childRow.Cells.Add(left); 274 left.Width = Unit.Percentage(fx); 275 } 276 |