/// <summary> /// Base class for two-dimensional graphs. /// </summary> /// <param name="X">X-axis</param> /// <param name="Y">Y-axis</param> /// <param name="PlotCallback">Callback method that performs the plotting.</param> /// <param name="ShowZeroX">If the y-axis (x=0) should always be shown.</param> /// <param name="ShowZeroY">If the x-axis (y=0) should always be shown.</param> /// <param name="Node">Node creating the graph.</param> /// <param name="Parameters">Graph-specific parameters.</param> public Graph2D(IVector X, IVector Y, DrawCallback PlotCallback, bool ShowZeroX, bool ShowZeroY, ScriptNode Node, params object[] Parameters) : base() { int i, c = X.Dimension; bool HasNull = false; IElement ex, ey; if (c != Y.Dimension) { throw new ScriptException("X and Y series must be equally large."); } if (X is Interval XI) { X = new DoubleVector(XI.GetArray()); } if (Y is Interval YI) { Y = new DoubleVector(YI.GetArray()); } for (i = 0; i < c; i++) { ex = X.GetElement(i); ey = Y.GetElement(i); if (ex.AssociatedObjectValue == null || ey.AssociatedObjectValue == null) { HasNull = true; break; } } this.showZeroX = ShowZeroX; this.showZeroY = ShowZeroY; this.minX = Min.CalcMin(X, null); this.maxX = Max.CalcMax(X, null); this.minY = Min.CalcMin(Y, null); this.maxY = Max.CalcMax(Y, null); if (HasNull) { LinkedList <IElement> X2 = new LinkedList <IElement>(); LinkedList <IElement> Y2 = new LinkedList <IElement>(); this.axisTypeX = null; this.axisTypeY = null; for (i = 0; i < c; i++) { ex = X.GetElement(i); ey = Y.GetElement(i); if (ex.AssociatedObjectValue == null || ey.AssociatedObjectValue == null) { if (X2.First != null) { this.AddSegment(X, Y, X2, Y2, Node, PlotCallback, Parameters); X2 = new LinkedList <IElement>(); Y2 = new LinkedList <IElement>(); } } else { X2.AddLast(ex); Y2.AddLast(ey); } } if (X2.First != null) { this.AddSegment(X, Y, X2, Y2, Node, PlotCallback, Parameters); } } else { this.axisTypeX = X.GetType(); this.axisTypeY = Y.GetType(); if (c > 0) { this.x.AddLast(X); this.y.AddLast(Y); this.callbacks.AddLast(PlotCallback); this.parameters.AddLast(Parameters); } } IElement Zero = null; if (ShowZeroX && c > 0 && this.minX.AssociatedSet is IAbelianGroup AG) { Zero = AG.AdditiveIdentity; this.minX = Min.CalcMin(new ObjectVector(this.minX, Zero), null); this.maxX = Max.CalcMax(new ObjectVector(this.maxX, Zero), null); } if (ShowZeroY && c > 0 && this.minY.AssociatedSet is IAbelianGroup AG2) { Zero = AG2.AdditiveIdentity; this.minY = Min.CalcMin(new ObjectVector(this.minY, Zero), null); this.maxY = Max.CalcMax(new ObjectVector(this.maxY, Zero), null); } }
/// <summary> /// Base class for two-dimensional graphs. /// </summary> /// <param name="X">X-axis</param> /// <param name="Y">Y-axis</param> /// <param name="PlotCallback">Callback method that performs the plotting.</param> /// <param name="ShowZeroX">If the y-axis (x=0) should always be shown.</param> /// <param name="ShowZeroY">If the x-axis (y=0) should always be shown.</param> /// <param name="Node">Node creating the graph.</param> /// <param name="Parameters">Graph-specific parameters.</param> public Graph2D(IVector X, IVector Y, DrawCallback PlotCallback, bool ShowZeroX, bool ShowZeroY, ScriptNode Node, params object[] Parameters) : base() { if (X is Interval XI) { X = new DoubleVector(XI.GetArray()); } if (Y is Interval YI) { Y = new DoubleVector(YI.GetArray()); } int i, c = X.Dimension; bool HasNull = false; IElement ex, ey; if (c != Y.Dimension) { throw new ScriptException("X and Y series must be equally large."); } for (i = 0; i < c; i++) { ex = X.GetElement(i); ey = Y.GetElement(i); if (ex.AssociatedObjectValue is null || ey.AssociatedObjectValue is null) { HasNull = true; break; } } this.showZeroX = ShowZeroX; this.showZeroY = ShowZeroY; this.minX = Min.CalcMin(X, null); this.maxX = Max.CalcMax(X, null); if (this.showZeroX && this.minX is AbelianGroup Gx) { List <IElement> Elements = new List <IElement> { this.minX, Gx.Zero }; this.minX = Min.CalcMin(X.Encapsulate(Elements, null) as IVector, null); Elements = new List <IElement> { this.maxX, Gx.Zero }; this.maxX = Max.CalcMax(X.Encapsulate(Elements, null) as IVector, null); } this.minY = Min.CalcMin(Y, null); this.maxY = Max.CalcMax(Y, null); if (this.showZeroY && this.minY is AbelianGroup Gy) { List <IElement> Elements = new List <IElement> { this.minY, Gy.Zero }; this.minY = Min.CalcMin(Y.Encapsulate(Elements, null) as IVector, null); Elements = new List <IElement> { this.maxY, Gy.Zero }; this.maxY = Max.CalcMax(Y.Encapsulate(Elements, null) as IVector, null); } if (HasNull) { LinkedList <IElement> X2 = new LinkedList <IElement>(); LinkedList <IElement> Y2 = new LinkedList <IElement>(); this.axisTypeX = null; this.axisTypeY = null; for (i = 0; i < c; i++) { ex = X.GetElement(i); ey = Y.GetElement(i); if (ex.AssociatedObjectValue is null || ey.AssociatedObjectValue is null) { if (X2.First != null) { this.AddSegment(X, Y, X2, Y2, Node, PlotCallback, Parameters); X2 = new LinkedList <IElement>(); Y2 = new LinkedList <IElement>(); } } else { X2.AddLast(ex); Y2.AddLast(ey); } }
/// <summary> /// Tries to add an element to the current element, from the right. /// </summary> /// <param name="Element">Element to add.</param> /// <returns>Result, if understood, null otherwise.</returns> public override ISemiGroupElement AddRight(ISemiGroupElement Element) { if (this.x.First == null) { return(Element); } Graph2D G = Element as Graph2D; if (G == null) { return(null); } if (G.x.First == null) { return(this); } Graph2D Result = new Graph2D() { axisTypeX = this.axisTypeX, axisTypeY = this.axisTypeY }; foreach (IVector v in this.x) { Result.x.AddLast(v); } foreach (IVector v in this.y) { Result.y.AddLast(v); } foreach (DrawCallback Callback in this.callbacks) { Result.callbacks.AddLast(Callback); } foreach (object[] P in this.parameters) { Result.parameters.AddLast(P); } foreach (IVector v in G.x) { if (v.GetType() != this.axisTypeX) { throw new ScriptException("Incompatible types of series."); } Result.x.AddLast(v); } foreach (IVector v in G.y) { if (v.GetType() != this.axisTypeY) { throw new ScriptException("Incompatible types of series."); } Result.y.AddLast(v); } foreach (DrawCallback Callback in G.callbacks) { Result.callbacks.AddLast(Callback); } foreach (object[] P in G.parameters) { Result.parameters.AddLast(P); } Result.minX = Min.CalcMin((IVector)VectorDefinition.Encapsulate(new IElement[] { this.minX, G.minX }, false, null), null); Result.maxX = Max.CalcMax((IVector)VectorDefinition.Encapsulate(new IElement[] { this.maxX, G.maxX }, false, null), null); Result.minY = Min.CalcMin((IVector)VectorDefinition.Encapsulate(new IElement[] { this.minY, G.minY }, false, null), null); Result.maxY = Max.CalcMax((IVector)VectorDefinition.Encapsulate(new IElement[] { this.maxY, G.maxY }, false, null), null); Result.showXAxis |= G.showXAxis; Result.showYAxis |= G.showYAxis; return(Result); }