LegendBase.cs

Go to the documentation of this file.
00001 /*
00002 NPlot - A charting library for .NET
00003 
00004 LegendBase.cs
00005 Copyright (C) 2003
00006 Matt Howlett
00007 
00008 Redistribution and use of NPlot or parts there-of in source and
00009 binary forms, with or without modification, are permitted provided
00010 that the following conditions are met:
00011 
00012 1. Re-distributions in source form must retain at the head of each
00013    source file the above copyright notice, this list of conditions
00014    and the following disclaimer.
00015 
00016 2. Any product ("the product") that makes use NPlot or parts 
00017    there-of must either:
00018   
00019     (a) allow any user of the product to obtain a complete machine-
00020         readable copy of the corresponding source code for the 
00021         product and the version of NPlot used for a charge no more
00022         than your cost of physically performing source distribution,
00023         on a medium customarily used for software interchange, or:
00024 
00025     (b) reproduce the following text in the documentation, about 
00026         box or other materials intended to be read by human users
00027         of the product that is provided to every human user of the
00028         product: 
00029    
00030               "This product includes software developed as 
00031               part of the NPlot library project available 
00032               from: http://www.nplot.com/" 
00033 
00034         The words "This product" may optionally be replace with 
00035         the actual name of the product.
00036 
00037 ------------------------------------------------------------------------
00038 
00039 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00040 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00041 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00042 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00043 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00044 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00045 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00046 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00047 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00048 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00049 
00050 */
00051 
00052 using System;
00053 using System.Collections;
00054 using System.Drawing;
00055 
00056 namespace NPlot
00057 {
00058 
00065         public class LegendBase
00066         {
00067 
00071                 public LegendBase()
00072                 {
00073                         this.Font = new Font( new FontFamily("Arial"), 10, FontStyle.Regular, GraphicsUnit.Pixel );
00074                         this.BackgroundColor = Color.White;
00075                         this.BorderColor = Color.Black;
00076                         this.TextColor = Color.Black;
00077                         this.borderStyle_ = BorderType.Shadow;
00078                         this.autoScaleText_ = false;
00079                 }
00080 
00081 
00090                 public Rectangle GetBoundingBox( Point position, ArrayList plots, float scale )
00091                 {
00092                         System.Drawing.Bitmap b = new System.Drawing.Bitmap(1,1);
00093                         Graphics g = Graphics.FromImage(b);
00094                         return this.Draw( g, position, plots, scale );
00095                 }
00096 
00097 
00106                 public Rectangle Draw( Graphics g, Point position, ArrayList plots, float scale )
00107                 {
00108 
00109                         // first of all determine the Font to use in the legend.
00110                         Font textFont;
00111                         if (this.AutoScaleText)
00112                         {
00113                                 textFont = Utils.ScaleFont( this.font_, scale );
00114                         }
00115                         else
00116                         {
00117                                 textFont = this.font_;
00118                         }
00119 
00120                         // determine max width and max height of label strings and
00121                         // count the labels. 
00122                         int labelCount = 0;
00123                         int maxHt = 0;
00124                         int maxWd = 0;
00125                         int unnamedCount = 0;
00126                         for (int i=0; i<plots.Count; ++i)
00127                         {
00128                                 if (!(plots[i] is IPlot))
00129                                 {
00130                                         continue;
00131                                 }
00132 
00133                                 IPlot p = (IPlot)plots[i];
00134 
00135                                 if (!p.ShowInLegend)
00136                                 {
00137                                         continue;
00138                                 }
00139                                 string label = p.Label;
00140                                 if (label == "")
00141                                 {
00142                                         unnamedCount += 1;
00143                                         label = "Series " + unnamedCount.ToString();
00144                                 }
00145                                 SizeF labelSize = g.MeasureString( label, textFont );
00146                                 if ( labelSize.Height > maxHt )
00147                                 {
00148                                         maxHt = (int)labelSize.Height;
00149                                 }
00150                                 if ( labelSize.Width > maxWd )
00151                                 {
00152                                         maxWd = (int)labelSize.Width;
00153                                 }
00154 
00155                                 ++labelCount;
00156                         }
00157 
00158                         bool extendingHorizontally = numberItemsHorizontally_ == -1;
00159                         bool extendingVertically = numberItemsVertically_ == -1;
00160 
00161 
00162                         // determine width in legend items count units.
00163                         int widthInItemCount = 0;
00164                         if (extendingVertically)
00165                         {
00166                                 if (labelCount >= numberItemsHorizontally_)
00167                                 {
00168                                         widthInItemCount = numberItemsHorizontally_;
00169                                 }
00170                                 else
00171                                 {
00172                                         widthInItemCount = labelCount;
00173                                 }
00174                         }
00175                         else if (extendingHorizontally)
00176                         {
00177                                 widthInItemCount = labelCount / numberItemsVertically_;
00178                                 if (labelCount % numberItemsVertically_ != 0)
00179                                         widthInItemCount += 1;
00180                         }
00181                         else
00182                         {
00183                                 throw new NPlotException( "logic error in legend base" );
00184                         }
00185 
00186 
00187                         // determine height of legend in items count units.
00188                         int heightInItemCount = 0;
00189                         if (extendingHorizontally)
00190                         {
00191                                 if (labelCount >= numberItemsVertically_)
00192                                 {
00193                                         heightInItemCount = numberItemsVertically_;
00194                                 }
00195                                 else
00196                                 {
00197                                         heightInItemCount = labelCount;
00198                                 }
00199                         }
00200                         else // extendingVertically
00201                         {
00202                                 heightInItemCount = labelCount / numberItemsHorizontally_;
00203                                 if (labelCount % numberItemsHorizontally_ != 0)
00204                                         heightInItemCount += 1;
00205                         }
00206 
00207                         int lineLength = 20;
00208                         int hSpacing = (int)(5.0f * scale);
00209                         int vSpacing = (int)(3.0f * scale);
00210                         int boxWidth = (int) ((float)widthInItemCount * (lineLength + maxWd + hSpacing * 2.0f ) + hSpacing); 
00211                         int boxHeight = (int)((float)heightInItemCount * (maxHt + vSpacing) + vSpacing);
00212 
00213                         int totalWidth = boxWidth;
00214                         int totalHeight = boxHeight;
00215 
00216                         // draw box around the legend.
00217 
00218                         if ( this.BorderStyle == BorderType.Line )
00219                         {
00220                                 g.FillRectangle( new SolidBrush( this.bgColor_ ), position.X, position.Y, boxWidth, boxHeight );
00221                                 g.DrawRectangle( new Pen( this.borderColor_ ), position.X, position.Y, boxWidth, boxHeight );
00222                         }
00223                         else if ( this.BorderStyle == BorderType.Shadow )
00224                         {
00225                                 int offset = (int)(4.0f * scale);
00226                                 g.FillRectangle( new SolidBrush( Color.LightGray ), position.X+offset, position.Y+offset, boxWidth, boxHeight );
00227                                 g.FillRectangle( new SolidBrush( this.bgColor_ ), position.X, position.Y, boxWidth, boxHeight );
00228                                 g.DrawRectangle( new Pen( this.borderColor_ ), position.X, position.Y, boxWidth, boxHeight );
00229 
00230                                 totalWidth += offset;
00231                                 totalHeight += offset;
00232                         }
00233 
00234                         /*
00235                            else if ( this.BorderStyle == BorderType.Curved )
00236                            {
00237                                    // TODO. make this nice.
00238                            }
00239                         */
00240 
00241                         else
00242                         {
00243                                 // do nothing.
00244                         }
00245 
00246                         // now draw entries in box..
00247                         labelCount = 0;
00248                         unnamedCount = 0;
00249 
00250                         int plotCount = -1;
00251                         for (int i=0; i<plots.Count; ++i)
00252                         {
00253                                 if (!(plots[i] is IPlot))
00254                                 {
00255                                         continue;
00256                                 }
00257 
00258                                 IPlot p = (IPlot)plots[i];
00259 
00260                                 if (!p.ShowInLegend)
00261                                 {
00262                                         continue;
00263                                 }
00264 
00265                                 plotCount += 1;
00266 
00267                                 int xpos, ypos;
00268                                 if (extendingVertically)
00269                                 {
00270                                         xpos = plotCount % numberItemsHorizontally_;
00271                                         ypos = plotCount / numberItemsHorizontally_;
00272                                 }
00273                                 else
00274                                 {
00275                                         xpos = plotCount / numberItemsVertically_;
00276                                         ypos = plotCount % numberItemsVertically_;
00277                                 }
00278 
00279                                 int lineXPos = (int)(position.X + hSpacing + xpos * (lineLength + maxWd + hSpacing * 2.0f));
00280                                 int lineYPos = (int)(position.Y + vSpacing + ypos * (vSpacing + maxHt));
00281                                 p.DrawInLegend( g, new Rectangle( lineXPos, lineYPos, lineLength, maxHt ) );
00282                                 
00283                                 int textXPos = lineXPos + hSpacing + lineLength;
00284                                 int textYPos = lineYPos;
00285                                 string label = p.Label;
00286                                 if (label == "")
00287                                 {
00288                                         unnamedCount += 1;
00289                                         label = "Series " + unnamedCount.ToString();
00290                                 }
00291 
00292                                 g.DrawString( label, textFont,
00293                                         new SolidBrush( this.textColor_ ), textXPos, textYPos );
00294 
00295                                 ++labelCount;
00296                         }
00297                         return new Rectangle( position.X, position.Y, totalWidth, totalHeight );
00298 
00299                 }
00300 
00301 
00305                 public Font Font
00306                 {
00307                         get
00308                         {
00309                                 return this.font_;
00310                         }
00311                         set
00312                         {
00313                                 this.font_ = value;
00314                         }
00315                 }
00316                 private Font font_;
00317 
00318 
00322                 public Color TextColor
00323                 {
00324                         get
00325                         {
00326                                 return this.textColor_;
00327                         }
00328                         set
00329                         {
00330                                 this.textColor_ = value;
00331                         }
00332                 }
00333                 Color textColor_;
00334 
00335 
00339                 public Color BackgroundColor
00340                 {
00341                         get
00342                         {
00343                                 return bgColor_;
00344                         }
00345                         set
00346                         {
00347                                 bgColor_ = value;
00348                         }
00349                 }
00350                 Color bgColor_;
00351 
00352 
00356                 public Color BorderColor
00357                 {
00358                         get
00359                         {
00360                                 return borderColor_;
00361                         }
00362                         set
00363                         {
00364                                 borderColor_ = value;
00365                         }
00366                 }
00367                 Color borderColor_;
00368 
00369 
00373                 public enum BorderType
00374                 {
00378                         None = 0,
00382                         Line = 1,
00386                         Shadow = 2
00387                         //Curved = 3
00388                 }
00389 
00390 
00394                 public Legend.BorderType BorderStyle
00395                 {
00396                         get
00397                         {
00398                                 return borderStyle_;
00399                         }
00400                         set
00401                         {
00402                                 borderStyle_ = value;
00403                         }
00404                 }
00405                 private NPlot.Legend.BorderType borderStyle_;
00406 
00407 
00412                 public bool AutoScaleText
00413                 {
00414                         get
00415                         {
00416                                 return autoScaleText_;
00417                         }
00418                         set
00419                         {
00420                                 autoScaleText_ = value;
00421                         }
00422                 }
00423                 bool autoScaleText_;
00424 
00425 
00431                 public int NumberItemsVertically
00432                 {
00433                         set
00434                         {
00435                                 this.numberItemsVertically_ = value;
00436                                 this.numberItemsHorizontally_ = -1;
00437                         }
00438                 }
00439                 int numberItemsVertically_ = -1;
00440 
00441 
00447                 public int NumberItemsHorizontally
00448                 {
00449                         set
00450                         {
00451                                 this.numberItemsHorizontally_ = value;
00452                                 this.numberItemsVertically_ = -1;
00453                         }
00454                 }
00455                 int numberItemsHorizontally_ = 1;
00456 
00457         }
00458 
00459 }

Generated on Sat Nov 5 01:04:06 2005 for NPlot by  doxygen 1.4.5