Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Visualization/3.2/Legend/LegendShape.cs @ 2491

Last change on this file since 2491 was 1964, checked in by mstoeger, 16 years ago

moved the canvas and the basic types of shapes to their own namespace. #498

File size: 6.0 KB
RevLine 
[873]1using System.Collections.Generic;
[1337]2using System.Drawing;
[1964]3using HeuristicLab.Visualization.Drawing;
[866]4
[1233]5namespace HeuristicLab.Visualization.Legend {
[1342]6  public enum LegendPosition {
7    Top,
8    Bottom,
9    Left,
10    Right
11  }
12
[1195]13  public class LegendShape : WorldShape {
[873]14    private readonly IList<LegendItem> legendItems = new List<LegendItem>();
[1342]15    // legend draw default value: column
[1337]16
17    private Color color = Color.Blue;
18    private Font font = new Font("Arial", 8);
19
[1877]20    public bool Row { get; set; }
21    public bool Top { get; set; }
22
[1195]23    public LegendShape() {
[1049]24      CreateLegend();
[866]25    }
26
[1388]27    private bool ExistsLegendItems() {
28      return legendItems.Count > 0;
29    }
30   
31    /// <summary>
32    /// paints the legend on the canvas
33    /// </summary>
[1049]34    public void CreateLegend() {
[1388]35      if (ExistsLegendItems()) {
36        ClearShapes();
37        double x = ClippingArea.X1;
38        double y = ClippingArea.Y2;
39
[1877]40        if (Row && !Top) {
[1665]41          y = GetOptimalBottomHeight();
[1342]42        }
[1665]43        int legendItemCounter = 1;
[1388]44        foreach (LegendItem item in legendItems) {
[1877]45          if (!Row) {
[1388]46            CreateColumn(item, y);
[1461]47            y -= Font.Height;
[1388]48          } else {
[1665]49            if (IsNewRow(legendItemCounter)) {
[1388]50              x = ClippingArea.X1;
[1461]51              y -= Font.Height+15;
[1388]52            }
53            CreateRow(item, x, y);
54            x += GetLabelLengthInPixel(item);
[1665]55            legendItemCounter++;
[1388]56          }
57        }
[1342]58      }
[1388]59    }
60
[1877]61    /// <summary>
62    /// calculates the optimal height, when the legend shall be draw at the bottom
63    /// </summary>
64    /// <returns>optimal bottom height</returns>
[1665]65    private double GetOptimalBottomHeight() {
[1388]66      int rowsToDraw = 1;
[1665]67      for (int i = 0; i < legendItems.Count; i++) {
68        if (IsNewRow(i + 1)) {
69          rowsToDraw++;
[1342]70        }
[866]71      }
[1665]72      return (Font.Height + 12) * rowsToDraw;
[866]73    }
74
[1342]75    /// <summary>
[1877]76    /// returns a boolean value, if the new legend item has to be paint in a
77    /// new row
[1388]78    /// </summary>
[1877]79    /// <returns>
80    ///   true, draw legend item in a new row
81    ///   false, draw the legend item in the current row
82    /// </returns>
[1665]83    private bool IsNewRow(int toCurrentItem) {
84      double sum = 0;
85      double caw = ClippingArea.Width;
86      for (int i = 0; i < toCurrentItem; i++) {
87        sum += GetLabelLengthInPixel(legendItems[i]);
88        if (sum > caw) {
89          return true;
90        }
91      }
92      return false;
[1388]93    }
94
95    /// <summary>
96    /// returns the length of the current legenditem in pixel
97    /// </summary>
[1877]98    /// <param name="item">legend item to calculate the length</param>
99    /// <returns>length of the legend item</returns>
[1461]100    private int GetLabelLengthInPixel(LegendItem item) {
101      int dummy = (int)(item.Label.Length*Font.Size + 20);
[1388]102      if (dummy < LegendItem.WIDTH) {
103        return LegendItem.WIDTH;
104      }
105      return dummy;
106    }
107
108    /// <summary>
[1342]109    /// draws the legend as a row at the top or bottom of the WorldShape
110    /// </summary>
[1346]111    /// <param name="item">the legenditem to draw</param>
112    /// <param name="x">x axis to draw the item</param>
113    /// <param name="y">y axis to draw the item</param>
[1342]114    private void CreateRow(LegendItem item, double x, double y) {
[1461]115      AddShape(new LineShape(x, y - (Font.Height / 2), x + 20, y - (Font.Height / 2), item.Color, item.Thickness, DrawingStyle.Solid));
[1342]116      AddShape(new TextShape(x + 25, y, item.Label, Font, Color));
117    }
118
119    /// <summary>
120    /// draws the legend as a column on the right or left side of the WorldShape
121    /// </summary>
[1346]122    /// <param name="item">the legenditem to draw</param>
123    /// <param name="y">y axis to draw the item</param>
[1342]124    private void CreateColumn(LegendItem item, double y) {
[1461]125      AddShape(new LineShape(10, y - (Font.Height / 2), 30, y - (Font.Height / 2), item.Color, item.Thickness, DrawingStyle.Solid));
[1877]126      AddShape(new TextShape(35, y, item.Label, Font, Color));//Font.Height+12
[1342]127    }
128
[1346]129    /// <summary>
130    /// adds a legenditem to the items list
131    /// </summary>
132    /// <param name="item">legenditem to add</param>
[873]133    public void AddLegendItem(LegendItem item) {
134      legendItems.Add(item);
135    }
136
[1346]137    /// <summary>
[1461]138    /// searches the longest label and returns it with factor of the the current font size
[1877]139    /// useful to set the width of the legend area on the left or right side
[1388]140    /// </summary>
[1461]141    /// <returns>max label length with factor of the current font size</returns>
[1388]142    public int GetMaxLabelLength() {
143      int maxLabelLength = 0;
144      if (ExistsLegendItems()) {
145        maxLabelLength = legendItems[0].Label.Length;
146        foreach (var item in legendItems) {
147          if (item.Label.Length > maxLabelLength) {
148            maxLabelLength = item.Label.Length;
149          }
150        }
[1461]151        maxLabelLength = (int)(maxLabelLength*Font.Size);
[1388]152      }
153      return maxLabelLength < LegendItem.WIDTH ? LegendItem.WIDTH : maxLabelLength;
154    }
155
156    /// <summary>
[1346]157    /// removes a legenditem from the items list
158    /// </summary>
159    /// <param name="item">legenditem to remove</param>
[873]160    public void RemoveLegendItem(LegendItem item) {
161      legendItems.Remove(item);
162    }
163
[1346]164    /// <summary>
165    /// deletes the legenditem list
166    /// </summary>
[873]167    public void ClearLegendItems() {
168      legendItems.Clear();
169    }
[1337]170
171    public Color Color {
172      get { return color; }
173      set {
174        color = value;
175        UpdateTextShapes();
176      }
177    }
178
179    public Font Font {
180      get { return font; }
181      set {
182        font = value;
183        UpdateTextShapes();
184      }
185    }
186
[1346]187    /// <summary>
188    /// updates the font settings of the legend
189    /// </summary>
[1337]190    private void UpdateTextShapes() {
191      foreach (IShape shape in shapes) {
192        TextShape textShape = shape as TextShape;
193
194        if (textShape != null) {
195          textShape.Font = font;
196          textShape.Color = color;
197        }
198      }
199    }
[866]200  }
[1342]201}
Note: See TracBrowser for help on using the repository browser.