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.Collections;
00054 using System.Drawing;
00055
00056 namespace NPlot
00057 {
00058
00063 public class LabelAxis : Axis
00064 {
00065
00070 public override object Clone()
00071 {
00072 LabelAxis a = new LabelAxis();
00073
00074 if (this.GetType() != a.GetType())
00075 {
00076 throw new NPlotException( "Error. Clone method is not defined in derived type." );
00077 }
00078 DoClone( this, a );
00079 return a;
00080 }
00081
00087 protected static void DoClone( LabelAxis b, LabelAxis a )
00088 {
00089 Axis.DoClone( b, a );
00090
00091 a.labels_ = (ArrayList)b.labels_.Clone();
00092 a.numbers_ = (ArrayList)b.numbers_.Clone();
00093
00094 a.ticksBetweenText_ = b.ticksBetweenText_;
00095 a.sortDataIfNecessary_ = b.sortDataIfNecessary_;
00096 }
00097
00098
00102 private void Init()
00103 {
00104 labels_ = new ArrayList();
00105 numbers_ = new ArrayList();
00106 }
00107
00108
00114 public LabelAxis( Axis a )
00115 : base( a )
00116 {
00117 Init();
00118 }
00119
00123 public LabelAxis()
00124 : base()
00125 {
00126 Init();
00127 }
00128
00134 public LabelAxis( double worldMin, double worldMax )
00135 : base( worldMin, worldMax )
00136 {
00137 Init();
00138 }
00139
00140
00146 public void AddLabel( string name, double val )
00147 {
00148 labels_.Add( name );
00149 numbers_.Add( val );
00150 }
00151
00152
00162 protected override void DrawTicks(
00163 Graphics g,
00164 Point physicalMin,
00165 Point physicalMax,
00166 out object labelOffset,
00167 out object boundingBox )
00168 {
00169
00170 Point tLabelOffset;
00171 Rectangle tBoundingBox;
00172
00173 labelOffset = this.getDefaultLabelOffset( physicalMin, physicalMax );
00174 boundingBox = null;
00175
00176
00177 PointF lastPos = WorldToPhysical( (double)numbers_[0], physicalMin, physicalMax, true );
00178 for (int i=0; i<labels_.Count; ++i)
00179 {
00180
00181 if ((double)numbers_[i] > WorldMin && (double)numbers_[i] < WorldMax)
00182 {
00183
00184
00185 PointF thisPos = WorldToPhysical( (double)numbers_[i], physicalMin, physicalMax, true );
00186 float dist = Utils.Distance( thisPos, lastPos );
00187
00188 if ( i==0 || (dist > this.PhysicalSpacingMin) )
00189 {
00190 lastPos = thisPos;
00191
00192 this.DrawTick( g, (double)numbers_[i], 0,
00193 (string)labels_[i],
00194 new Point(0,0),
00195 physicalMin, physicalMax,
00196 out tLabelOffset, out tBoundingBox );
00197
00198 Axis.UpdateOffsetAndBounds(
00199 ref labelOffset, ref boundingBox,
00200 tLabelOffset, tBoundingBox );
00201 }
00202 }
00203 }
00204
00205
00206 ArrayList largeTickPositions;
00207 ArrayList smallTickPositions;
00208 WorldTickPositions_FirstPass( physicalMin, physicalMax, out largeTickPositions, out smallTickPositions );
00209 lastPos = WorldToPhysical( (double)largeTickPositions[0], physicalMin, physicalMax, true );
00210 for (int i=0; i<largeTickPositions.Count; ++i)
00211 {
00212 double tickPos = (double)largeTickPositions[i];
00213
00214
00215 PointF thisPos = WorldToPhysical( tickPos, physicalMin, physicalMax, true );
00216 float dist = Utils.Distance( thisPos, lastPos );
00217 if ( (i==0) || (dist> this.PhysicalSpacingMin) )
00218 {
00219 lastPos = thisPos;
00220
00221 this.DrawTick( g, tickPos, LargeTickSize,
00222 "",
00223 new Point(0,0),
00224 physicalMin, physicalMax,
00225 out tLabelOffset, out tBoundingBox );
00226
00227 Axis.UpdateOffsetAndBounds(
00228 ref labelOffset, ref boundingBox,
00229 tLabelOffset, tBoundingBox );
00230 }
00231 }
00232
00233 }
00234
00235
00245 internal override void WorldTickPositions_FirstPass(
00246 Point physicalMin,
00247 Point physicalMax,
00248 out ArrayList largeTickPositions,
00249 out ArrayList smallTickPositions
00250 )
00251 {
00252 smallTickPositions = null;
00253 largeTickPositions = new ArrayList();
00254
00255
00256 if (!ticksBetweenText_)
00257 {
00258 for (int i=0; i<labels_.Count; ++i)
00259 {
00260 if ((double)numbers_[i] > WorldMin && (double)numbers_[i] < WorldMax)
00261 {
00262 largeTickPositions.Add( numbers_[i] );
00263 }
00264 }
00265 }
00266
00267
00268 else
00269 {
00270 ArrayList numbers_copy;
00271 if (sortDataIfNecessary_)
00272 {
00273 numbers_copy = (ArrayList)numbers_.Clone();
00274 numbers_copy.Sort();
00275 }
00276 else
00277 {
00278 numbers_copy = numbers_;
00279 }
00280
00281 for (int i=1; i<labels_.Count; ++i)
00282 {
00283 double worldPosition = ((double)numbers_copy[i] + (double)numbers_copy[i-1])/2.0;
00284 if (worldPosition > WorldMin && worldPosition < WorldMax)
00285 {
00286 largeTickPositions.Add( worldPosition );
00287 }
00288 }
00289 }
00290
00291 }
00292
00293
00298 public bool TicksBetweenText
00299 {
00300 get
00301 {
00302 return ticksBetweenText_;
00303 }
00304 set
00305 {
00306 ticksBetweenText_ = value;
00307 }
00308 }
00309 private bool ticksBetweenText_ = false;
00310
00311
00321 public bool SortDataIfNecessary
00322 {
00323 get
00324 {
00325 return sortDataIfNecessary_;
00326 }
00327 set
00328 {
00329 sortDataIfNecessary_ = value;
00330 }
00331 }
00332 private bool sortDataIfNecessary_ = true;
00333
00334
00339 public int PhysicalSpacingMin
00340 {
00341 get
00342 {
00343 return physicalSpacingMin_;
00344 }
00345 set
00346 {
00347 physicalSpacingMin_ = value;
00348 }
00349 }
00350 private int physicalSpacingMin_ = 0;
00351
00352
00353 private ArrayList labels_;
00354 private ArrayList numbers_;
00355 }
00356 }