using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Drawing; using System.Linq; using System.Windows.Forms; using Core.Common.Base; using Core.Components.Charting; using Core.Components.Charting.Data; using Core.Components.OxyPlot.Converter; using OxyPlot.WindowsForms; namespace Core.Components.OxyPlot.Forms { /// /// This class describes a plot view with configured representation of axes. /// public sealed class BaseChart : Control, IObserver, IChart { private readonly ICollection observers = new Collection(); private readonly SeriesFactory seriesFactory = new SeriesFactory(); private ChartData data; private LinearPlotView view; private DynamicPlotController controller; /// /// Creates a new instance of . /// public BaseChart() { InitializePlotView(); MinimumSize = new Size(50, 75); } /// /// Attaches the to the currently set , if there is any. /// private void AttachToData() { if (data != null) { data.Attach(this); } } /// /// Detaches the to the currently set , if there is any. /// private void DetachFromData() { if (data != null) { data.Detach(this); } } /// /// Initialize the for the . /// private void InitializePlotView() { view = new LinearPlotView(); controller = new DynamicPlotController(); view.Controller = controller; Controls.Add(view); } /// /// Draws series based on the currently set . /// private void DrawSeries() { view.Model.Series.Clear(); if (data != null) { foreach (var series in seriesFactory.Create(data)) { view.Model.Series.Add(series); } } } #region IChart public bool IsPanningEnabled { get { return controller.IsPanningEnabled; } } public bool IsRectangleZoomingEnabled { get { return controller.IsRectangleZoomingEnabled; } } [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] public ChartData Data { get { return data; } set { DetachFromData(); data = value; AttachToData(); DrawSeries(); } } public void TogglePanning() { controller.TogglePanning(); } public void ToggleRectangleZooming() { controller.ToggleRectangleZooming(); } public void ZoomToAll() { view.ZoomToAll(); } public void UpdateObserver() { DrawSeries(); view.InvalidatePlot(true); } #endregion #region IObservable public void Attach(IObserver observer) { observers.Add(observer); } public void Detach(IObserver observer) { observers.Remove(observer); } public void NotifyObservers() { // Iterate through a copy of the list of observers; an update of one observer might result in detaching // another observer (which will result in a "list modified" exception over here otherwise) foreach (var observer in observers.ToArray()) { // Ensure the observer is still part of the original list of observers if (!observers.Contains(observer)) { continue; } observer.UpdateObserver(); } } #endregion } }