Free cookie consent management tool by TermsFeed Policy Generator

source: trunk/sources/HeuristicLab.Visualization/3.2/LineChart.cs @ 1530

Last change on this file since 1530 was 1530, checked in by gkronber, 15 years ago

Moved source files of plugins Hive ... Visualization.Test into version-specific sub-folders. #576

File size: 21.1 KB
RevLine 
[683]1using System;
[861]2using System.Collections.Generic;
[928]3using System.Drawing;
4using System.Windows.Forms;
[697]5using HeuristicLab.Core;
[1233]6using HeuristicLab.Visualization.Legend;
[1195]7using HeuristicLab.Visualization.Options;
[1457]8using HeuristicLab.Visualization.Test;
[683]9
[861]10namespace HeuristicLab.Visualization {
[1187]11  public partial class LineChart : ViewBase {
[697]12    private readonly IChartDataRowsModel model;
[1240]13    private readonly Canvas canvas;
14
[1285]15    private readonly TextShape titleShape = new TextShape("Title");
16    private readonly LegendShape legendShape = new LegendShape();
17    private readonly XAxis xAxis = new XAxis();
18    private readonly List<RowEntry> rowEntries = new List<RowEntry>();
[684]19
[1285]20    private readonly Dictionary<IDataRow, RowEntry> rowToRowEntry = new Dictionary<IDataRow, RowEntry>();
[1038]21
[1341]22    private readonly ViewSettings viewSettings;
23
[1285]24    private readonly WorldShape userInteractionShape = new WorldShape();
25    private readonly RectangleShape rectangleShape = new RectangleShape(0, 0, 0, 0, Color.FromArgb(50, 0, 0, 255));
26    private IMouseEventListener mouseEventListener;
[983]27
[1285]28    private const int YAxisWidth = 100;
[1462]29    private const int XAxisHeight = 40;
[1285]30
[697]31    /// <summary>
32    /// This constructor shouldn't be called. Only required for the designer.
33    /// </summary>
[861]34    public LineChart() {
[684]35      InitializeComponent();
36    }
37
[697]38    /// <summary>
39    /// Initializes the chart.
40    /// </summary>
[754]41    /// <param name="model">Referenz to the model, for data</param>
[861]42    public LineChart(IChartDataRowsModel model) : this() {
[1045]43      if (model == null) {
[697]44        throw new NullReferenceException("Model cannot be null.");
[1045]45      }
[684]46
[1240]47      canvas = canvasUI.Canvas;
[983]48
[1285]49      this.model = model;
[1341]50      viewSettings = model.ViewSettings;
[1342]51      viewSettings.OnUpdateSettings += UpdateViewSettings;
[1038]52
[983]53      Item = model;
[1038]54
[1240]55      UpdateLayout();
56      canvasUI.Resize += delegate { UpdateLayout(); };
[1187]57
[1285]58      ZoomToFullView();
[697]59    }
[684]60
[1346]61    /// <summary>
62    /// updates the view settings
63    /// </summary>
[1342]64    private void UpdateViewSettings() {
[1341]65      titleShape.Font = viewSettings.TitleFont;
66      titleShape.Color = viewSettings.TitleColor;
[1337]67
[1341]68      legendShape.Font = viewSettings.LegendFont;
69      legendShape.Color = viewSettings.LegendColor;
[1337]70
[1341]71      xAxis.Font = viewSettings.XAxisFont;
72      xAxis.Color = viewSettings.XAxisColor;
[1337]73
[1345]74      SetLegendPosition();
[1342]75
[1337]76      canvasUI.Invalidate();
77    }
78
[1038]79    /// <summary>
80    /// Layout management - arranges the inner shapes.
81    /// </summary>
82    private void UpdateLayout() {
[1285]83      canvas.ClearShapes();
84
[1350]85      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
86        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
[1458]87        if (yAxisDescriptor.ShowGrid) {
88          info.Grid.Color = yAxisDescriptor.GridColor;
89          canvas.AddShape(info.Grid);
90        }
[1285]91      }
92
93      foreach (RowEntry rowEntry in rowEntries) {
94        canvas.AddShape(rowEntry.LinesShape);
95      }
96
[1462]97      xAxis.ShowLabel = model.ShowXAxisLabel;
98      xAxis.Label = model.XAxisLabel;
99
[1285]100      canvas.AddShape(xAxis);
101
[1457]102      int yAxesWidthLeft = 0;
103      int yAxesWidthRight = 0;
[1343]104
[1350]105      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
106        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
107        if (yAxisDescriptor.ShowYAxis) {
108          canvas.AddShape(info.YAxis);
[1462]109          info.YAxis.ShowLabel = yAxisDescriptor.ShowYAxisLabel;
110          info.YAxis.Label = yAxisDescriptor.Label;
[1457]111          info.YAxis.Position = yAxisDescriptor.Position;
112          switch (yAxisDescriptor.Position) {
113            case AxisPosition.Left:
114              yAxesWidthLeft += YAxisWidth;
115              break;
116            case AxisPosition.Right:
117              yAxesWidthRight += YAxisWidth;
118              break;
119            default:
120              throw new NotImplementedException();
121          }
[1343]122        }
[1285]123      }
124
125      canvas.AddShape(titleShape);
126      canvas.AddShape(legendShape);
127
128      canvas.AddShape(userInteractionShape);
129
[1038]130      titleShape.X = 10;
[1240]131      titleShape.Y = canvasUI.Height - 10;
[1038]132
[1457]133      RectangleD linesAreaBoundingBox = new RectangleD(yAxesWidthLeft,
[1285]134                                                       XAxisHeight,
[1457]135                                                       canvasUI.Width - yAxesWidthRight,
[1285]136                                                       canvasUI.Height);
[1240]137
[1285]138      foreach (RowEntry rowEntry in rowEntries) {
139        rowEntry.LinesShape.BoundingBox = linesAreaBoundingBox;
140      }
[1182]141
[1350]142      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
143        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
144        info.Grid.BoundingBox = linesAreaBoundingBox;
145      }
146
[1285]147      int yAxisLeft = 0;
[1457]148      int yAxisRight = (int)linesAreaBoundingBox.X2;
149
[1350]150      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
151        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
152        if (yAxisDescriptor.ShowYAxis) {
[1457]153          switch (yAxisDescriptor.Position) {
154            case AxisPosition.Left:
155              info.YAxis.BoundingBox = new RectangleD(yAxisLeft,
156                                                      linesAreaBoundingBox.Y1,
157                                                      yAxisLeft + YAxisWidth,
158                                                      linesAreaBoundingBox.Y2);
159              yAxisLeft += YAxisWidth;
160              break;
161            case AxisPosition.Right:
162              info.YAxis.BoundingBox = new RectangleD(yAxisRight,
163                                                      linesAreaBoundingBox.Y1,
164                                                      yAxisRight + YAxisWidth,
165                                                      linesAreaBoundingBox.Y2);
166              yAxisRight += YAxisWidth;
167              break;
168            default:
169              throw new NotImplementedException();
170          }
[1343]171        }
[1285]172      }
[1187]173
[1285]174      userInteractionShape.BoundingBox = linesAreaBoundingBox;
175      userInteractionShape.ClippingArea = new RectangleD(0, 0, userInteractionShape.BoundingBox.Width, userInteractionShape.BoundingBox.Height);
[1182]176
[1285]177      xAxis.BoundingBox = new RectangleD(linesAreaBoundingBox.X1,
[1038]178                                         0,
[1285]179                                         linesAreaBoundingBox.X2,
180                                         linesAreaBoundingBox.Y1);
[1049]181
[1345]182      SetLegendPosition();
[1342]183    }
184
[1350]185    private readonly Dictionary<YAxisDescriptor, YAxisInfo> yAxisInfos = new Dictionary<YAxisDescriptor, YAxisInfo>();
186
187    private YAxisInfo GetYAxisInfo(YAxisDescriptor yAxisDescriptor) {
188      YAxisInfo info;
189
190      if (!yAxisInfos.TryGetValue(yAxisDescriptor, out info)) {
191        info = new YAxisInfo();
192        yAxisInfos[yAxisDescriptor] = info;
193      }
194
195      return info;
196    }
197
[1346]198    /// <summary>
199    /// sets the legend position
200    /// </summary>
[1345]201    private void SetLegendPosition() {
202      switch (viewSettings.LegendPosition) {
203        case LegendPosition.Bottom:
204          setLegendBottom();
205          break;
206
207        case LegendPosition.Top:
208          setLegendTop();
209          break;
210
211        case LegendPosition.Left:
212          setLegendLeft();
213          break;
214
215        case LegendPosition.Right:
216          setLegendRight();
217          break;
218      }
219    }
220
[1342]221    public void setLegendRight() {
222      // legend right
[1388]223      legendShape.BoundingBox = new RectangleD(canvasUI.Width - legendShape.GetMaxLabelLength(), 10, canvasUI.Width, canvasUI.Height - 50);
[1342]224      legendShape.ClippingArea = new RectangleD(0, 0, legendShape.BoundingBox.Width, legendShape.BoundingBox.Height);
225      legendShape.Row = false;
226      legendShape.CreateLegend();
227    }
228
229    public void setLegendLeft() {
230      // legend left
[1388]231      legendShape.BoundingBox = new RectangleD(10, 10, canvasUI.Width, canvasUI.Height - 50);
[1342]232      legendShape.ClippingArea = new RectangleD(0, 0, legendShape.BoundingBox.Width, legendShape.BoundingBox.Height);
233      legendShape.Row = false;
234      legendShape.CreateLegend();
[1285]235
236      canvasUI.Invalidate();
[1038]237    }
238
[1342]239    public void setLegendTop() {
240      // legend top
241      legendShape.BoundingBox = new RectangleD(100, canvasUI.Height - canvasUI.Height, canvasUI.Width, canvasUI.Height - 10);
242      legendShape.ClippingArea = new RectangleD(0, 0, legendShape.BoundingBox.Width, legendShape.BoundingBox.Height);
243      legendShape.Row = true;
244      legendShape.Top = true;
245      legendShape.CreateLegend();
246    }
247
248    public void setLegendBottom() {
249      // legend bottom
[1388]250      legendShape.BoundingBox = new RectangleD(100, 10, canvasUI.Width, canvasUI.Height/*legendShape.GetHeight4Rows()*/);
[1342]251      legendShape.ClippingArea = new RectangleD(0, 0, legendShape.BoundingBox.Width, legendShape.BoundingBox.Height);
252      legendShape.Row = true;
253      legendShape.Top = false;
254      legendShape.CreateLegend();
255    }
256
[1242]257    private void optionsToolStripMenuItem_Click(object sender, EventArgs e) {
[1341]258      OptionsDialog optionsdlg = new OptionsDialog(model);
[1459]259      optionsdlg.Show();
[1242]260    }
261
262    public void OnDataRowChanged(IDataRow row) {
[1285]263      RowEntry rowEntry = rowToRowEntry[row];
264
265      rowEntry.LinesShape.UpdateStyle(row);
266
[1343]267      UpdateLayout();
268
[1242]269      canvasUI.Invalidate();
270    }
271
[861]272    #region Add-/RemoveItemEvents
273
274    protected override void AddItemEvents() {
275      base.AddItemEvents();
276
277      model.DataRowAdded += OnDataRowAdded;
278      model.DataRowRemoved += OnDataRowRemoved;
279      model.ModelChanged += OnModelChanged;
[869]280
[1045]281      foreach (IDataRow row in model.Rows) {
[869]282        OnDataRowAdded(row);
[1045]283      }
[683]284    }
[684]285
[861]286    protected override void RemoveItemEvents() {
287      base.RemoveItemEvents();
288
289      model.DataRowAdded -= OnDataRowAdded;
290      model.DataRowRemoved -= OnDataRowRemoved;
291      model.ModelChanged -= OnModelChanged;
[697]292    }
293
[861]294    private void OnDataRowAdded(IDataRow row) {
295      row.ValueChanged += OnRowValueChanged;
296      row.ValuesChanged += OnRowValuesChanged;
[1237]297      row.DataRowChanged += OnDataRowChanged;
298
[1049]299      legendShape.AddLegendItem(new LegendItem(row.Label, row.Color, row.Thickness));
300      legendShape.CreateLegend();
[1285]301
[987]302      InitLineShapes(row);
[1285]303
304      UpdateLayout();
[684]305    }
[697]306
[1240]307    private void OnDataRowRemoved(IDataRow row) {
308      row.ValueChanged -= OnRowValueChanged;
309      row.ValuesChanged -= OnRowValuesChanged;
310      row.DataRowChanged -= OnDataRowChanged;
[1285]311
312      rowToRowEntry.Remove(row);
313      rowEntries.RemoveAll(delegate(RowEntry rowEntry) { return rowEntry.DataRow == row; });
314
315      UpdateLayout();
[1240]316    }
317
318    #endregion
319
[1249]320    public void ZoomToFullView() {
[1285]321      SetClipX(-0.1, model.MaxDataRowValues - 0.9);
[987]322
[1285]323      foreach (RowEntry rowEntry in rowEntries) {
[1350]324        YAxisDescriptor yAxisDescriptor = rowEntry.DataRow.YAxis;
[1249]325
[1285]326        SetClipY(rowEntry,
[1350]327                 yAxisDescriptor.MinValue - ((yAxisDescriptor.MaxValue - yAxisDescriptor.MinValue)*0.05),
328                 yAxisDescriptor.MaxValue + ((yAxisDescriptor.MaxValue - yAxisDescriptor.MinValue)*0.05));
[1285]329      }
330
331      canvasUI.Invalidate();
[987]332    }
333
[1285]334    private void SetClipX(double x1, double x2) {
335      xAxis.ClippingArea = new RectangleD(x1,
336                                          0,
337                                          x2,
338                                          XAxisHeight);
[1249]339
[1285]340      foreach (RowEntry rowEntry in rowEntries) {
341        rowEntry.LinesShape.ClippingArea = new RectangleD(x1,
342                                                          rowEntry.LinesShape.ClippingArea.Y1,
343                                                          x2,
344                                                          rowEntry.LinesShape.ClippingArea.Y2);
[1249]345      }
[1350]346
347      foreach (YAxisDescriptor yAxisDescriptor in model.YAxes) {
348        YAxisInfo info = GetYAxisInfo(yAxisDescriptor);
349        info.Grid.ClippingArea = new RectangleD(x1,
350                                                info.Grid.ClippingArea.Y1,
351                                                x2,
352                                                info.Grid.ClippingArea.Y2);
353        info.YAxis.ClippingArea = new RectangleD(0,
354                                                 info.YAxis.ClippingArea.Y1,
355                                                 YAxisWidth,
356                                                 info.YAxis.ClippingArea.Y2);
357      }
[1285]358    }
[1249]359
[1350]360    private void SetClipY(RowEntry rowEntry, double y1, double y2) {
[1285]361      rowEntry.LinesShape.ClippingArea = new RectangleD(rowEntry.LinesShape.ClippingArea.X1,
362                                                        y1,
363                                                        rowEntry.LinesShape.ClippingArea.X2,
364                                                        y2);
[1350]365
366      YAxisInfo info = GetYAxisInfo(rowEntry.DataRow.YAxis);
367
368      info.Grid.ClippingArea = new RectangleD(info.Grid.ClippingArea.X1,
369                                              y1,
370                                              info.Grid.ClippingArea.X2,
371                                              y2);
372      info.YAxis.ClippingArea = new RectangleD(info.YAxis.ClippingArea.X1,
373                                               y1,
374                                               info.YAxis.ClippingArea.X2,
375                                               y2);
[981]376    }
377
[987]378    private void InitLineShapes(IDataRow row) {
[1285]379      RowEntry rowEntry = new RowEntry(row);
380      rowEntries.Add(rowEntry);
381      rowToRowEntry[row] = rowEntry;
382
[1242]383      if ((row.LineType == DataRowType.SingleValue)) {
384        if (row.Count > 0) {
385          LineShape lineShape = new HorizontalLineShape(0, row[0], double.MaxValue, row[0], row.Color, row.Thickness,
386                                                        row.Style);
[1285]387          rowEntry.LinesShape.AddShape(lineShape);
[1242]388        }
[1249]389      } else {
[1242]390        for (int i = 1; i < row.Count; i++) {
[1283]391          LineShape lineShape = new LineShape(i - 1, row[i - 1], i, row[i], row.Color, row.Thickness, row.Style);
[1285]392          rowEntry.LinesShape.AddShape(lineShape);
[1242]393        }
394      }
[1249]395
[981]396      ZoomToFullView();
[697]397    }
398
[869]399    private void OnRowValueChanged(IDataRow row, double value, int index, Action action) {
[1285]400      RowEntry rowEntry = rowToRowEntry[row];
401
[1242]402      if (row.LineType == DataRowType.SingleValue) {
403        if (action == Action.Added) {
404          LineShape lineShape = new HorizontalLineShape(0, row[0], double.MaxValue, row[0], row.Color, row.Thickness,
405                                                        row.Style);
[1285]406          rowEntry.LinesShape.AddShape(lineShape);
[1249]407        } else {
[1285]408          LineShape lineShape = rowEntry.LinesShape.GetShape(0);
409          lineShape.Y1 = value;
410          lineShape.Y2 = value;
[1242]411        }
[1249]412      } else {
[1285]413        if (index > rowEntry.LinesShape.Count + 1) {
[1242]414          throw new NotImplementedException();
415        }
[861]416
[1242]417        // new value was added
[1285]418        if (index > 0 && index == rowEntry.LinesShape.Count + 1) {
419          LineShape lineShape = new LineShape(index - 1, row[index - 1], index, row[index], row.Color, row.Thickness, row.Style);
420          rowEntry.LinesShape.AddShape(lineShape);
[1045]421        }
[861]422
[1242]423        // not the first value
424        if (index > 0) {
[1285]425          rowEntry.LinesShape.GetShape(index - 1).Y2 = value;
[1242]426        }
427
428        // not the last value
429        if (index > 0 && index < row.Count - 1) {
[1285]430          rowEntry.LinesShape.GetShape(index).Y1 = value;
[1242]431        }
[1045]432      }
[861]433
[981]434      ZoomToFullView();
[697]435    }
436
[869]437    private void OnRowValuesChanged(IDataRow row, double[] values, int index, Action action) {
[1045]438      foreach (double value in values) {
[869]439        OnRowValueChanged(row, value, index++, action);
[1045]440      }
[861]441    }
[761]442
[1182]443    private void OnModelChanged() {
444      titleShape.Text = model.Title;
[697]445
[1240]446      canvasUI.Invalidate();
[1182]447    }
448
[697]449    #region Begin-/EndUpdate
450
[1242]451    private int beginUpdateCount;
[697]452
[861]453    public void BeginUpdate() {
[697]454      beginUpdateCount++;
455    }
456
[861]457    public void EndUpdate() {
[1045]458      if (beginUpdateCount == 0) {
[697]459        throw new InvalidOperationException("Too many EndUpdates.");
[1045]460      }
[697]461
462      beginUpdateCount--;
463
[1045]464      if (beginUpdateCount == 0) {
[1240]465        canvasUI.Invalidate();
[1045]466      }
[697]467    }
468
469    #endregion
[928]470
[1059]471    #region Zooming / Panning
472
[1249]473    private void Pan(Point startPoint, Point endPoint) {
[1351]474      RectangleD clippingArea = Translate.ClippingArea(startPoint, endPoint, xAxis.ClippingArea, xAxis.Viewport);
[1285]475
[1351]476      SetClipX(clippingArea.X1, clippingArea.X2);
[1285]477
478      foreach (RowEntry rowEntry in rowEntries) {
[1390]479        if (rowEntry.DataRow.YAxis.ClipChangeable) {
480          clippingArea = Translate.ClippingArea(startPoint, endPoint, rowEntry.LinesShape.ClippingArea, rowEntry.LinesShape.Viewport);
481          SetClipY(rowEntry, clippingArea.Y1, clippingArea.Y2);
482        }
[1285]483      }
484
485      canvasUI.Invalidate();
[1249]486    }
487
[1351]488    private void PanEnd(Point startPoint, Point endPoint) {
489      Pan(startPoint, endPoint);
[1249]490    }
491
492    private void SetClippingArea(Rectangle rectangle) {
[1351]493      RectangleD clippingArea = Transform.ToWorld(rectangle, xAxis.Viewport, xAxis.ClippingArea);
494
495      SetClipX(clippingArea.X1, clippingArea.X2);
496
[1285]497      foreach (RowEntry rowEntry in rowEntries) {
[1390]498        if (rowEntry.DataRow.YAxis.ClipChangeable) {
499          clippingArea = Transform.ToWorld(rectangle, rowEntry.LinesShape.Viewport, rowEntry.LinesShape.ClippingArea);
[1249]500
[1390]501          SetClipY(rowEntry, clippingArea.Y1, clippingArea.Y2);
502        }
[1285]503      }
504
[1249]505      userInteractionShape.RemoveShape(rectangleShape);
[1285]506      canvasUI.Invalidate();
[1249]507    }
508
509    private void DrawRectangle(Rectangle rectangle) {
510      rectangleShape.Rectangle = Transform.ToWorld(rectangle, userInteractionShape.Viewport, userInteractionShape.ClippingArea);
511      canvasUI.Invalidate();
512    }
513
[1059]514    private void canvasUI1_KeyDown(object sender, KeyEventArgs e) {
515    }
516
[928]517    private void canvasUI1_MouseDown(object sender, MouseEventArgs e) {
[1058]518      Focus();
[1249]519
[1237]520      if (e.Button == MouseButtons.Right) {
[1242]521        contextMenuStrip1.Show(PointToScreen(e.Location));
[1249]522      } else if (e.Button == MouseButtons.Left) {
523        if (ModifierKeys == Keys.None) {
524          PanListener panListener = new PanListener(e.Location);
525          panListener.Pan += Pan;
526          panListener.PanEnd += PanEnd;
527
528          mouseEventListener = panListener;
529        } else if (ModifierKeys == Keys.Control) {
530          ZoomListener zoomListener = new ZoomListener(e.Location);
531          zoomListener.DrawRectangle += DrawRectangle;
532          zoomListener.SetClippingArea += SetClippingArea;
533
534          rectangleShape.Rectangle = RectangleD.Empty;
535          userInteractionShape.AddShape(rectangleShape);
536
537          mouseEventListener = zoomListener;
[1187]538        }
539      }
[928]540    }
541
[1249]542    private void canvasUI_MouseMove(object sender, MouseEventArgs e) {
543      if (mouseEventListener != null) {
544        mouseEventListener.MouseMove(sender, e);
545      }
546    }
[1244]547
[1249]548    private void canvasUI_MouseUp(object sender, MouseEventArgs e) {
549      if (mouseEventListener != null) {
550        mouseEventListener.MouseUp(sender, e);
551      }
[1240]552
[1249]553      mouseEventListener = null;
[1240]554    }
555
[1058]556    private void canvasUI1_MouseWheel(object sender, MouseEventArgs e) {
557      if (ModifierKeys == Keys.Control) {
[1351]558        double zoomFactor = (e.Delta > 0) ? 0.7 : 1.3;
[1058]559
[1351]560        PointD world;
561
562        world = Transform.ToWorld(e.Location, xAxis.Viewport, xAxis.ClippingArea);
563
564        double x1 = world.X - (world.X - xAxis.ClippingArea.X1)*zoomFactor;
565        double x2 = world.X + (xAxis.ClippingArea.X2 - world.X)*zoomFactor;
566
567        SetClipX(x1, x2);
568
[1285]569        foreach (RowEntry rowEntry in rowEntries) {
[1351]570          world = Transform.ToWorld(e.Location, rowEntry.LinesShape.Viewport, rowEntry.LinesShape.ClippingArea);
571
572          double y1 = world.Y - (world.Y - rowEntry.LinesShape.ClippingArea.Y1) * zoomFactor;
573          double y2 = world.Y + (rowEntry.LinesShape.ClippingArea.Y2 - world.Y)*zoomFactor;
574
575          SetClipY(rowEntry, y1, y2);
[1285]576        }
[1351]577
578        canvasUI.Invalidate();
[1058]579      }
580    }
581
[1249]582    #endregion
[928]583
[1285]584    private class LinesShape : WorldShape {
585      public void UpdateStyle(IDataRow row) {
586        foreach (IShape shape in shapes) {
587          LineShape lineShape = shape as LineShape;
588          if (lineShape != null) {
589            lineShape.LSColor = row.Color;
590            lineShape.LSDrawingStyle = row.Style;
591            lineShape.LSThickness = row.Thickness;
592          }
593        }
594      }
[928]595
[1285]596      public int Count {
597        get { return shapes.Count; }
598      }
[928]599
[1285]600      public LineShape GetShape(int index) {
601        return (LineShape)shapes[index];
602      }
603    }
604
605    private class RowEntry {
606      private readonly IDataRow dataRow;
607
608      private readonly LinesShape linesShape = new LinesShape();
609
610      public RowEntry(IDataRow dataRow) {
611        this.dataRow = dataRow;
612      }
613
614      public IDataRow DataRow {
615        get { return dataRow; }
616      }
617
[1350]618      public LinesShape LinesShape {
619        get { return linesShape; }
620      }
621    }
622
623    private class YAxisInfo {
624      private readonly Grid grid = new Grid();
625      private readonly YAxis yAxis = new YAxis();
626
[1285]627      public Grid Grid {
628        get { return grid; }
629      }
630
631      public YAxis YAxis {
632        get { return yAxis; }
633      }
634    }
[684]635  }
[1342]636}
Note: See TracBrowser for help on using the repository browser.