Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 1688 was 1608, checked in by bspisic, 16 years ago

Model.Title bug fixed (#590)

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