Free cookie consent management tool by TermsFeed Policy Generator

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

Last change on this file since 1880 was 1880, checked in by mstoeger, 15 years ago

Moved X-Axis settings from model to model.XAxis. Fixed UpdateLayout and invalidating. #498

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