/// /// This file is part of ILNumerics Community Edition. /// /// ILNumerics Community Edition - high performance computing for applications. /// Copyright (C) 2006 - 2012 Haymo Kutschbach, http://ilnumerics.net /// /// ILNumerics Community Edition is free software: you can redistribute it and/or modify /// it under the terms of the GNU General Public License version 3 as published by /// the Free Software Foundation. /// /// ILNumerics Community Edition is distributed in the hope that it will be useful, /// but WITHOUT ANY WARRANTY; without even the implied warranty of /// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the /// GNU General Public License for more details. /// /// You should have received a copy of the GNU General Public License /// along with ILNumerics Community Edition. See the file License.txt in the root /// of your distribution package. If not, see . /// /// In addition this software uses the following components and/or licenses: /// /// ================================================================================= /// The Open Toolkit Library License /// /// Copyright (c) 2006 - 2009 the Open Toolkit library. /// /// Permission is hereby granted, free of charge, to any person obtaining a copy /// of this software and associated documentation files (the "Software"), to deal /// in the Software without restriction, including without limitation the rights to /// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of /// the Software, and to permit persons to whom the Software is furnished to do /// so, subject to the following conditions: /// /// The above copyright notice and this permission notice shall be included in all /// copies or substantial portions of the Software. /// /// ================================================================================= /// using System; using System.Collections.Generic; using System.Text; using System.Drawing; using ILNumerics; using ILNumerics.Drawing; using ILNumerics.Exceptions; using ILNumerics.Drawing.Marker; using ILNumerics.Drawing.Interfaces; using ILNumerics.Drawing.Shapes; namespace ILNumerics.Drawing.Graphs { /// /// 2D line & point graph /// public abstract class ILPlot2DGraph : ILGraph, IILLegendRenderer, IILPanelConfigurator { #region attributes protected C4bV3f[] m_vertices; protected int m_vertexCount; protected ILLineProperties m_properties; protected ILMarker m_marker; int m_autoLimitsUpdateCount = 0; int m_updateCount = 0; protected int m_startID; #endregion #region properties /// /// number of subsequent updates ('Queue') before limits get recalculated. Default: 0 (recalculate on every update) /// public int AutoLimitsUpdateCount { get { return m_autoLimitsUpdateCount; } set { m_autoLimitsUpdateCount = value; } } /// /// Get properties of lines /// public ILLineProperties Line { get { return m_properties; } } /// /// Get properties of markers /// public ILMarker Marker { get { return m_marker; } } /// /// access to internal vertex array /// /// after altering vertex data, one must call /// Invalidate() to signal those changes. public C4bV3f[] Vertices { get { return m_vertices; } } /// /// Invalidate the graph after vertex data have been changed. /// public override void Invalidate() { base.Invalidate(); updateClipping(); OnChanged("Data"); } /// /// draws a small example of the visual output /// /// render properties /// area to draw the line + marker into /// area to draw corresponding label into /// derived classes implement this for current device contexts public virtual void DrawToLegend(ILRenderProperties p, Rectangle sampleArea, Rectangle labelArea) { //if (g == null) throw new ILArgumentException ("ILGraph: DrawIntoLegend: invalid graphics object (null)"); //throw new NotImplementedException ("ILGraph cannot draw to bitmap yet!"); } /// /// Size of label /// /// size public Size LabelSize { get { return m_label.Size; } } #endregion #region constructor /// /// [internal] constructor - do not use this! Use ILPanel.Graphs.Add...() instead! /// /// panel hosting the scene /// data array /// hosting panels clipping data public ILPlot2DGraph(ILPanel panel, ILArray sourceArray, ILClippingData clippingContainer) : base(panel, clippingContainer) { using (ILScope.Enter(sourceArray)) { if (object.Equals(sourceArray, null) || !sourceArray.IsVector || !sourceArray.IsNumeric) throw new ILArgumentException("Plot2D: supplied data must be numeric (real valued) vector!"); int pos = 0; ILArray data; C4bV3f vert = new C4bV3f(); data = (ILArray)sourceArray; m_vertices = new C4bV3f[data.Length + 1]; m_vertexCount = m_vertices.Length; m_updateCount = 0; m_startID = 0; m_properties = new ILLineProperties(); m_properties.Color = Color.DarkBlue; m_properties.Width = 2; //m_properties.Antialiasing = true; m_properties.Changed += new EventHandler(m_properties_Changed); foreach (float val in data) { vert.Position = new ILPoint3Df(pos, val, 0); vert.Color = Color.Red; m_vertices[pos++] = vert; } m_marker = new ILMarker(panel); m_marker.Changed += new EventHandler(m_properties_Changed); m_graphType = GraphType.Plot2D; m_localClipping.Set(new ILPoint3Df(0, data.MinValue, 0), new ILPoint3Df(data.Length - 1, data.MaxValue, 0)); } } /// /// [internal] constructor - do not use this! Use ILPanel.Graphs.Add...() instead! /// /// panel hosting the scene /// x data array /// y data array /// hosting panels clipping data internal ILPlot2DGraph(ILPanel panel, ILArray XData, ILArray YData, ILClippingData clippingContainer) : base (panel,clippingContainer) { using (ILScope.Enter(XData, YData)) { if (!XData.IsVector) throw new ILArgumentException("Plot2D: supplied data must be a real vector!"); if (!YData.IsVector) throw new ILArgumentException("Plot2D: XData and YData must be real vectors!"); if (YData.Length != XData.Length) throw new ILArgumentException("Plot2D: XData and YData must have the same length!"); int pos = 0; ILArray dataX, dataY; C4bV3f vert = new C4bV3f(); dataX = (ILArray)XData; dataY = (ILArray)YData; m_vertices = new C4bV3f[dataX.Length + 1]; m_vertexCount = m_vertices.Length; m_startID = m_vertexCount - 1; m_updateCount = 0; m_properties = new ILLineProperties(); m_properties.Color = Color.DarkBlue; m_properties.Changed += new EventHandler(m_properties_Changed); foreach (float val in dataX) { vert.Position = new ILPoint3Df(val, dataY.GetValue(pos), 0); vert.Color = m_properties.Color; m_vertices[pos++] = vert; } m_marker = new ILMarker(panel); m_marker.Changed += new EventHandler(m_marker_Changed); m_graphType = GraphType.Plot2D; updateClipping(); } } public void Queue(IILVertexDefinition vertex) { if (m_startID == 0) { SetVertex(m_vertexCount-1,vertex); m_startID = 1; } else { SetVertex(m_startID,vertex); m_vertices[0] = m_vertices[m_vertexCount-1]; m_startID++; } if (m_startID == m_vertexCount-1) { m_startID = 0; } if (m_updateCount++ < m_autoLimitsUpdateCount) { m_localClipping.Update(vertex.Position,vertex.Position); } else { m_updateCount = 0; Invalidate(); } } #endregion #region private helper public void SetVertex(int vertexID,IILVertexDefinition vertex) { C4bV3f curVert = m_vertices[vertexID]; if (vertex.StoresColor) { curVert.Color = vertex.Color; } curVert.Position = vertex.Position; m_vertices[vertexID] = curVert; } /// /// called, if a property for markers have changed /// /// this graph instance /// (no args) /// derived classes should override this function in order to /// (re-)configure vertex ressources etc. protected virtual void m_marker_Changed(object sender, EventArgs e) { m_isReady = false; } private void updateClipping() { ILPoint3Df max = ILPoint3Df.MinValue; ILPoint3Df min = ILPoint3Df.MaxValue; for (int i = 0; i < m_vertexCount; i++) { C4bV3f vert = m_vertices[i]; max = ILPoint3Df.Max(vert.Position,max); min = ILPoint3Df.Min(vert.Position,min); } m_localClipping.Set ( min, max ); } /// /// called, if a property for lines have changed /// /// this graph instance /// (no args) /// derived classes should override this function in order to /// (re-)configure vertex ressources etc. protected virtual void m_properties_Changed(object sender, EventArgs e) { m_isReady = false; } public override bool Is3DGraph() { return false; } #endregion #region IILPanelConfigurator public void ConfigurePanel(ILPanel panel) { panel.InteractiveMode = InteractiveModes.ZoomRectangle; panel.AspectRatio = AspectRatioMode.StretchToFill; panel.PlotBoxScreenSizeMode = PlotBoxScreenSizeMode.Optimal; panel.ClipViewData = true; panel.DefaultView.Set(0f, 0f, panel.DefaultView.Distance); } #endregion } }