00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 using System;
00053 using System.Drawing;
00054
00055 namespace NPlot
00056 {
00057
00061 public class StepPlot : BaseSequencePlot, IPlot, ISequencePlot
00062 {
00063
00067 public StepPlot()
00068 {
00069 this.Center = false;
00070 }
00071
00072
00079 public virtual void Draw( Graphics g, PhysicalAxis xAxis, PhysicalAxis yAxis )
00080 {
00081
00082 SequenceAdapter data =
00083 new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData );
00084
00085 for (int i=0; i<data.Count; ++i)
00086 {
00087 PointD p1 = data[i];
00088 if (Double.IsNaN(p1.X) || Double.IsNaN(p1.Y))
00089 {
00090 continue;
00091 }
00092
00093 PointD p2;
00094 PointD p3;
00095 if (i+1 != data.Count)
00096 {
00097 p2 = data[i+1];
00098 if (Double.IsNaN(p2.X) || Double.IsNaN(p2.Y))
00099 {
00100 continue;
00101 }
00102 p2.Y = p1.Y;
00103 p3 = data[i+1];
00104 }
00105 else
00106 {
00107 p2 = data[i-1];
00108 double offset = p1.X - p2.X;
00109 p2.X = p1.X + offset;
00110 p2.Y = p1.Y;
00111 p3 = p2;
00112 }
00113
00114 if ( this.center_ )
00115 {
00116 double offset = ( p2.X - p1.X ) / 2.0f;
00117 p1.X -= offset;
00118 p2.X -= offset;
00119 p3.X -= offset;
00120 }
00121
00122 PointF xPos1 = xAxis.WorldToPhysical( p1.X, false );
00123 PointF yPos1 = yAxis.WorldToPhysical( p1.Y, false );
00124 PointF xPos2 = xAxis.WorldToPhysical( p2.X, false );
00125 PointF yPos2 = yAxis.WorldToPhysical( p2.Y, false );
00126 PointF xPos3 = xAxis.WorldToPhysical( p3.X, false );
00127 PointF yPos3 = yAxis.WorldToPhysical( p3.Y, false );
00128
00129 if (!this.hideHorizontalSegments_)
00130 {
00131 if (scale_ != 1.0f)
00132 {
00133 float middle = (xPos2.X + xPos1.X) / 2.0f;
00134 float width = xPos2.X - xPos1.X;
00135 width *= this.scale_;
00136 g.DrawLine( Pen, (int)(middle-width/2.0f), yPos1.Y, (int)(middle+width/2.0f), yPos2.Y );
00137 }
00138 else
00139 {
00140 g.DrawLine( Pen, xPos1.X, yPos1.Y, xPos2.X, yPos2.Y );
00141 }
00142 }
00143
00144 if (!this.hideVerticalSegments_)
00145 {
00146 g.DrawLine( Pen, xPos2.X, yPos2.Y, xPos3.X, yPos3.Y );
00147 }
00148
00149 }
00150
00151 }
00152
00153
00159 public Axis SuggestXAxis()
00160 {
00161 SequenceAdapter data =
00162 new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData );
00163
00164 if (data.Count < 2)
00165 {
00166 return data.SuggestXAxis();
00167 }
00168
00169
00170
00171 Axis a = data.SuggestXAxis();
00172
00173 PointD p1 = data[0];
00174 PointD p2 = data[1];
00175 PointD p3 = data[data.Count-2];
00176 PointD p4 = data[data.Count-1];
00177
00178 double offset1;
00179 double offset2;
00180
00181 if (!center_)
00182 {
00183 offset1 = 0.0f;
00184 offset2 = p4.X - p3.X;
00185 }
00186 else
00187 {
00188 offset1 = (p2.X - p1.X)/2.0f;
00189 offset2 = (p4.X - p3.X)/2.0f;
00190 }
00191
00192 a.WorldMin -= offset1;
00193 a.WorldMax += offset2;
00194
00195 return a;
00196 }
00197
00198
00204 public Axis SuggestYAxis()
00205 {
00206 SequenceAdapter data =
00207 new SequenceAdapter( this.DataSource, this.DataMember, this.OrdinateData, this.AbscissaData );
00208
00209 return data.SuggestYAxis();
00210 }
00211
00212
00218 public bool Center
00219 {
00220 set
00221 {
00222 center_ = value;
00223 }
00224 get
00225 {
00226 return center_;
00227 }
00228 }
00229 private bool center_;
00230
00231
00237 public virtual void DrawInLegend(Graphics g, Rectangle startEnd)
00238 {
00239 g.DrawLine(pen_, startEnd.Left, (startEnd.Top + startEnd.Bottom) / 2,
00240 startEnd.Right, (startEnd.Top + startEnd.Bottom) / 2);
00241 }
00242
00243
00247 public System.Drawing.Pen Pen
00248 {
00249 get
00250 {
00251 return pen_;
00252 }
00253 set
00254 {
00255 pen_ = value;
00256 }
00257 }
00258 private System.Drawing.Pen pen_ = new Pen(Color.Black);
00259
00260
00264 public System.Drawing.Color Color
00265 {
00266 set
00267 {
00268 if (pen_ != null)
00269 {
00270 pen_.Color = value;
00271 }
00272 else
00273 {
00274 pen_ = new Pen(value);
00275 }
00276 }
00277 get
00278 {
00279 return pen_.Color;
00280 }
00281 }
00282
00283
00287 public bool HideVerticalSegments
00288 {
00289 get
00290 {
00291 return hideVerticalSegments_;
00292 }
00293 set
00294 {
00295 hideVerticalSegments_ = value;
00296 }
00297 }
00298 bool hideVerticalSegments_ = false;
00299
00300
00304 public bool HideHorizontalSegments
00305 {
00306 get
00307 {
00308 return hideHorizontalSegments_;
00309 }
00310 set
00311 {
00312 hideHorizontalSegments_ = value;
00313 }
00314 }
00315 bool hideHorizontalSegments_ = false;
00316
00317
00322 public float WidthScale
00323 {
00324 get
00325 {
00326 return scale_;
00327 }
00328 set
00329 {
00330 scale_ = value;
00331 }
00332 }
00333 private float scale_ = 1.0f;
00334
00335 }
00336 }