Пример #1
0
            internal RedarwHelper(Rectangle clientRectangle)
            {
                this.currentMinute = -1;
                this.nextMinute    = -1;

                this.clientRectangle = clientRectangle;
                this.arcRect         = clientRectangle;

                this.brushX = new SolidBrushX(Color.Red);

                this.penX     = new PenX(Color.Gray, BORDER_WIDTH);
                this.linePenX = new PenX(Color.Black);

                this.gx           = new GraphicsX(arcRect.Width, arcRect.Height);
                this.gxNextMinute = new GraphicsX(arcRect.Width, arcRect.Height);

                this.arcRect.Width--;
                this.arcRect.Height--;
                this.arcRect.Inflate(-25, -25);

                int delta = BORDER_WIDTH / 2;

                boarderRect      = new Rectangle(arcRect.Left + delta, arcRect.Top + delta, arcRect.Width - BORDER_WIDTH, arcRect.Height - BORDER_WIDTH);
                this.boarderRect = this.arcRect;

                this.currentMinuteRedrawRect = clientRectangle;
            }
Пример #2
0
 protected override IEnumerable <Main.DocumentNodeAndName> GetDocumentNodeChildrenWithName()
 {
     if (null != _pen)
     {
         yield return(new DocumentNodeAndName(_pen, () => _pen = null, "Pen"));
     }
 }
Пример #3
0
        public void CopyFrom(ScatterPlotStyle from, bool suppressChangeEvent)
        {
            this._shape = from._shape;
            this._style = from._style;
            if (null == this._dropLine)
            {
                this._dropLine = new CSPlaneIDList();
            }
            else
            {
                this._dropLine.Clear();
            }
            this._dropLine.AddClonedRange(from._dropLine);
            this._pen = null == from._pen ? null : (PenX)from._pen.Clone();
            this._independentColor      = from._independentColor;
            this._independentSymbolSize = from._independentSymbolSize;


            this._symbolSize       = from._symbolSize;
            this._relativePenWidth = from._relativePenWidth;
            this._skipFreq         = from._skipFreq;

            this._cachedPath      = null == from._cachedPath ? null : (GraphicsPath)from._cachedPath.Clone();
            this._cachedFillPath  = from._cachedFillPath;
            this._cachedFillBrush = null == from._cachedFillBrush ? null : (BrushX)from._cachedFillBrush.Clone();
            this._parent          = from._parent;

            if (!suppressChangeEvent)
            {
                OnChanged();
            }
        }
Пример #4
0
        public void CopyFrom(LinePlotStyle from, Main.EventFiring eventFiring)
        {
            if (object.ReferenceEquals(this, from))
            {
                return;
            }

            using (var suspendToken = SuspendGetToken())
            {
                _independentSkipFrequency = from._independentSkipFrequency;
                _skipFrequency            = from._skipFrequency;

                _ignoreMissingDataPoints          = from._ignoreMissingDataPoints;
                _independentOnShiftingGroupStyles = from._independentOnShiftingGroupStyles;

                _connectCircular = from._connectCircular;
                _connectionStyle = from._connectionStyle;

                _linePen = null == from._linePen ? null : from._linePen.Clone();
                _independentDashStyle = from._independentDashStyle;
                _independentColor     = from._independentColor;

                _independentSymbolSize = from._independentSymbolSize;
                _symbolSize            = from._symbolSize;

                _useSymbolGap    = from._useSymbolGap;
                _symbolGapOffset = from._symbolGapOffset;
                _symbolGapFactor = from._symbolGapFactor;

                EhSelfChanged();

                suspendToken.Resume(eventFiring);
            }
        }
Пример #5
0
        /// <summary>
        /// Creates a default axis style.
        /// </summary>
        public AxisLineStyle(Main.Properties.IReadOnlyPropertyBag context)
        {
            double penWidth        = GraphDocument.GetDefaultPenWidth(context);
            double majorTickLength = GraphDocument.GetDefaultMajorTickLength(context);
            var    color           = GraphDocument.GetDefaultForeColor(context);

            _axisPen = new PenX(color, penWidth)
            {
                ParentObject = this
            };
            _majorTickPen = new PenX(color, penWidth)
            {
                ParentObject = this
            };
            _minorTickPen = new PenX(color, penWidth)
            {
                ParentObject = this
            };
            _majorTickLength         = majorTickLength;
            _minorTickLength         = majorTickLength / 2;
            _showFirstUpMajorTicks   = true; // true if right major ticks should be visible
            _showFirstDownMajorTicks = true; // true if left major ticks should be visible
            _showFirstUpMinorTicks   = true; // true if right minor ticks should be visible
            _showFirstDownMinorTicks = true; // true if left minor ticks should be visible
        }
Пример #6
0
 public ColorTypeThicknessPenController(PenX doc)
 {
     if (doc == null)
     {
         throw new ArgumentNullException("doc");
     }
     _doc     = doc;
     _tempDoc = (PenX)doc.Clone();
 }
Пример #7
0
		/// <summary>
		/// Template to make a line draw.
		/// </summary>
		/// <param name="g">Graphics context.</param>
		/// <param name="allLinePoints">The plot data. Don't use the Range property of the pdata, since it is overriden by the next argument.</param>
		/// <param name="range">The plot range to use.</param>
		/// <param name="layer">Graphics layer.</param>
		/// <param name="linePen">The pen to draw the line.</param>
		/// <param name="symbolGap">The size of the symbol gap. Argument is the original index of the data. The return value is the absolute symbol gap at this index.
		/// This function is null if no symbol gap is required.</param>
		/// <param name="skipFrequency">Skip frequency. Normally 1, thus all gaps are taken into account. If 2, only every 2nd gap is taken into account, and so on.</param>
		/// <param name="connectCircular">If true, there is a line connecting the start and the end of the range.</param>
		/// <param name="linePlotStyle">The line plot style.</param>
		public override void PaintOneRange(
			Graphics g,
			PointF[] allLinePoints,
			IPlotRange range,
			IPlotArea layer,
			PenX linePen,
			Func<int, double> symbolGap,
			int skipFrequency,
			bool connectCircular,
			LinePlotStyle linePlotStyle)
		{
			if (range.Length < 2)
				return;

			int lastIdx;
			int numberOfPointsPerOriginalPoint;
			PointF[] stepPolylinePoints = GetStepPolylinePoints(allLinePoints, range, layer, connectCircular, out numberOfPointsPerOriginalPoint, out lastIdx);

			GraphicsPath gp = new GraphicsPath();

			if (null != symbolGap)
			{
				int end = range.UpperBound - 1;

				var subPointsLength = skipFrequency * numberOfPointsPerOriginalPoint + 1;
				for (int i = 0; i < range.Length; i += skipFrequency)
				{

					int partialPolylineLength = Math.Min(subPointsLength, stepPolylinePoints.Length - numberOfPointsPerOriginalPoint * i);
					if (partialPolylineLength < 2)
						continue; // happens probably at the end of the range if there are not enough points to draw

					double gapAtStart = symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i));
					double gapAtEnd;
					if (connectCircular && skipFrequency >= (range.Length - i))
						gapAtEnd = symbolGap(range.OriginalFirstPoint);
					else if (skipFrequency <= (range.Length - 1 - i))
						gapAtEnd = symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i + skipFrequency));
					else
						gapAtEnd = 0;

					int startOfPartialPolyline = numberOfPointsPerOriginalPoint * i;
					var shortenedPolyline = stepPolylinePoints.ShortenPartialPolylineByDistanceFromStartAndEnd(startOfPartialPolyline, startOfPartialPolyline + partialPolylineLength - 1, gapAtStart / 2, gapAtEnd / 2);

					if (null != shortenedPolyline)
						g.DrawLines(linePen, shortenedPolyline);
				}
			}
			else
			{
				if (connectCircular)
					g.DrawPolygon(linePen, stepPolylinePoints);
				else
					g.DrawLines(linePen, stepPolylinePoints);
			}
		}
Пример #8
0
		protected OpenPathShapeBase(ItemLocationDirect location, Altaxo.Main.Properties.IReadOnlyPropertyBag context)
			: base(location)
		{
			if (null == context)
				context = PropertyExtensions.GetPropertyContextOfProject();

			var penWidth = GraphDocument.GetDefaultPenWidth(context);
			var foreColor = context.GetValue(GraphDocument.PropertyKeyDefaultForeColor);
			Pen = new PenX(foreColor, penWidth);
		}
Пример #9
0
 /// <summary>
 /// Template to make a line draw.
 /// </summary>
 /// <param name="g">Graphics context.</param>
 /// <param name="allLinePoints">The plot data. Don't use the Range property of the pdata, since it is overriden by the next argument.</param>
 /// <param name="range">The plot range to use.</param>
 /// <param name="layer">Graphics layer.</param>
 /// <param name="pen">The pen to draw the line.</param>
 /// <param name="symbolGap">The size of the symbol gap. Argument is the original index of the data. The return value is the absolute symbol gap at this index.
 /// This function is null if no symbol gap is required.</param>
 /// <param name="skipFrequency">Skip frequency. Normally 1, thus all gaps are taken into account. If 2, only every 2nd gap is taken into account, and so on.</param>
 /// <param name="connectCircular">If true, the line is connected circular, and the area is the polygon inside of that circular connection.</param>
 /// <param name="linePlotStyle">The line plot style.</param>
 public abstract void PaintOneRange(
     Graphics g,
     PointF[] allLinePoints,
     IPlotRange range,
     IPlotArea layer,
     PenX pen,
     Func <int, double> symbolGap,
     int skipFrequency,
     bool connectCircular,
     LinePlotStyle linePlotStyle
     );
Пример #10
0
        protected override void CopyFrom(GraphicBase bfrom)
        {
            ShapeGraphic from = bfrom as ShapeGraphic;

            if (from != null)
            {
                this._fillBrush = (BrushX)from._fillBrush.Clone();
                this._linePen   = (PenX)from._linePen.Clone();
            }
            base.CopyFrom(bfrom);
        }
Пример #11
0
		/// <summary>
		/// Template to make a line draw.
		/// </summary>
		/// <param name="g">Graphics context.</param>
		/// <param name="allLinePoints">The plot data. Don't use the Range property of the pdata, since it is overriden by the next argument.</param>
		/// <param name="range">The plot range to use.</param>
		/// <param name="layer">Graphics layer.</param>
		/// <param name="pen">The pen to draw the line.</param>
		/// <param name="symbolGap">The size of the symbol gap. Argument is the original index of the data. The return value is the absolute symbol gap at this index.
		/// This function is null if no symbol gap is required.</param>
		/// <param name="skipFrequency">Skip frequency. Normally 1, thus all gaps are taken into account. If 2, only every 2nd gap is taken into account, and so on.</param>
		/// <param name="connectCircular">If true, the line is connected circular, and the area is the polygon inside of that circular connection.</param>
		/// <param name="linePlotStyle">The line plot style.</param>
		public abstract void PaintOneRange(
			Graphics g,
			PointF[] allLinePoints,
			IPlotRange range,
			IPlotArea layer,
			PenX pen,
			Func<int, double> symbolGap,
			int skipFrequency,
			bool connectCircular,
			LinePlotStyle linePlotStyle
);
Пример #12
0
        private IEnumerable <Main.DocumentNodeAndName> GetMyDocumentNodeChildrenWithName()
        {
            if (null != _linePen)
            {
                yield return(new Main.DocumentNodeAndName(_linePen, () => _linePen = null, "LinePen"));
            }

            if (null != _fillBrush)
            {
                yield return(new Main.DocumentNodeAndName(_fillBrush, () => _fillBrush = null, "FillBrush"));
            }
        }
Пример #13
0
        private IEnumerable <Main.DocumentNodeAndName> GetMyDocumentNodeChildrenWithName()
        {
            if (null != _linePen)
            {
                yield return(new Main.DocumentNodeAndName(_linePen, () => _linePen = null, "LinePen"));
            }

            if (null != _outlinePen)
            {
                yield return(new Main.DocumentNodeAndName(_outlinePen, () => _outlinePen = null, "OutlinePen"));
            }
        }
Пример #14
0
        public bool CopyFrom(object obj, bool copyWithDataReferences)
        {
            if (object.ReferenceEquals(this, obj))
            {
                return(true);
            }
            var from = obj as VectorCartesicPlotStyle;

            if (null != from)
            {
                _meaningOfValues          = from._meaningOfValues;
                _independentSkipFrequency = from._independentSkipFrequency;
                _skipFrequency            = from._skipFrequency;
                _ignoreMissingDataPoints  = from._ignoreMissingDataPoints;
                _useManualVectorLength    = from._useManualVectorLength;
                _vectorLengthOffset       = from._vectorLengthOffset;
                _vectorLengthFactor       = from._vectorLengthFactor;

                _independentSymbolSize = from._independentSymbolSize;
                _symbolSize            = from._symbolSize;

                _strokePen        = from._strokePen;
                _independentColor = from._independentColor;

                _lineWidth1Offset = from._lineWidth1Offset;
                _lineWidth1Factor = from._lineWidth1Factor;

                _endCapSizeFactor = from._endCapSizeFactor;
                _endCapSizeOffset = from._endCapSizeOffset;

                _useSymbolGap    = from._useSymbolGap;
                _symbolGapFactor = from._symbolGapFactor;
                _symbolGapOffset = from._symbolGapOffset;

                _independentSkipFrequency         = from._independentSkipFrequency;
                _skipFrequency                    = from._skipFrequency;
                _independentOnShiftingGroupStyles = from._independentOnShiftingGroupStyles;

                _cachedLogicalShiftX = from._cachedLogicalShiftX;
                _cachedLogicalShiftY = from._cachedLogicalShiftY;

                if (copyWithDataReferences)
                {
                    ChildCloneToMember(ref _columnX, from._columnX);
                    ChildCloneToMember(ref _columnY, from._columnY);
                }

                EhSelfChanged();
                return(true);
            }
            return(false);
        }
Пример #15
0
        public DropLinePlotStyle(IEnumerable <CSPlaneID> planeIDs, PenX pen)
        {
            if (null == pen)
            {
                throw new ArgumentNullException(nameof(pen));
            }

            ChildSetMember(ref _pen, pen);
            _dropTargets = new CSPlaneIDList(planeIDs);

            // Cached values
            SetCachedValues();
        }
Пример #16
0
        protected OpenPathShapeBase(ItemLocationDirect location, Altaxo.Main.Properties.IReadOnlyPropertyBag context)
            : base(location)
        {
            if (null == context)
            {
                context = PropertyExtensions.GetPropertyContextOfProject();
            }

            var penWidth  = GraphDocument.GetDefaultPenWidth(context);
            var foreColor = context.GetValue(GraphDocument.PropertyKeyDefaultForeColor);

            Pen = new PenX(foreColor, penWidth);
        }
Пример #17
0
        /// <summary>
        /// Template to make a line draw.
        /// </summary>
        /// <param name="g">Graphics context.</param>
        /// <param name="allLinePoints">The plot data. Don't use the Range property of the pdata, since it is overriden by the next argument.</param>
        /// <param name="range">The plot range to use.</param>
        /// <param name="layer">Graphics layer.</param>
        /// <param name="linePen">The pen to draw the line.</param>
        /// <param name="symbolGap">The size of the symbol gap. Argument is the original index of the data. The return value is the absolute symbol gap at this index.
        /// This function is null if no symbol gap is required.</param>
        /// <param name="skipFrequency">Skip frequency. Normally 1, thus all gaps are taken into account. If 2, only every 2nd gap is taken into account, and so on.</param>
        /// <param name="connectCircular">If true, there is a line connecting the start and the end of the range.</param>
        /// <param name="linePlotStyle">The line plot style.</param>
        public override void PaintOneRange(
            Graphics g,
            PointF[] allLinePoints,
            IPlotRange range,
            IPlotArea layer,
            PenX linePen,
            Func <int, double> symbolGap,
            int skipFrequency,
            bool connectCircular,
            LinePlotStyle linePlotStyle)
        {
            if (range.Length <= 1)
            {
                return; // seems to be only a single point, thus no connection possible
            }
            PointF[] stepPolylinePoints = GetStepPolylinePoints(allLinePoints, range, layer, connectCircular, out var numberOfPointsPerOriginalPoint, out var lastIdx);

            if (null != symbolGap)
            {
                foreach (var segmentRange in GetSegmentRanges(range, symbolGap, skipFrequency, connectCircular))
                {
                    if (segmentRange.IsFullRangeClosedCurve) // test if this is a closed polygon without any gaps -> draw a closed polygon and return
                    {
                        // use the whole circular arry to draw a closed polygon without any gaps
                        g.DrawPolygon(linePen, stepPolylinePoints);
                    }
                    else
                    {
                        int plotIndexAtStart  = segmentRange.IndexAtSubRangeStart * numberOfPointsPerOriginalPoint;
                        int plotIndexAtEnd    = segmentRange.IndexAtSubRangeEnd * numberOfPointsPerOriginalPoint;
                        var shortenedPolyline = stepPolylinePoints.ShortenPartialPolylineByDistanceFromStartAndEnd(plotIndexAtStart, plotIndexAtEnd, segmentRange.GapAtSubRangeStart / 2, segmentRange.GapAtSubRangeEnd / 2);

                        if (null != shortenedPolyline)
                        {
                            g.DrawLines(linePen, shortenedPolyline);
                        }
                    }
                }
            }
            else
            {
                if (connectCircular)
                {
                    g.DrawPolygon(linePen, stepPolylinePoints);
                }
                else
                {
                    g.DrawLines(linePen, stepPolylinePoints);
                }
            }
        }
Пример #18
0
 void CopyFrom(ErrorBarPlotStyle from)
 {
     this._independentSymbolSize           = from._independentSymbolSize;
     this._symbolSize                      = from._symbolSize;
     this._symbolGap                       = from._symbolGap;
     this._independentColor                = from._independentColor;
     this._showEndBars                     = from._showEndBars;
     this._isHorizontalStyle               = from._isHorizontalStyle;
     this._doNotShiftHorizontalPosition    = from._doNotShiftHorizontalPosition;
     this._strokePen                       = (PenX)from._strokePen.Clone();
     this._positiveErrorColumn             = (NumericColumnProxy)from._positiveErrorColumn.Clone();
     this._negativeErrorColumn             = (NumericColumnProxy)from._negativeErrorColumn.Clone();
     this._cachedLogicalShiftOfIndependent = from._cachedLogicalShiftOfIndependent;
 }
Пример #19
0
 protected override System.Collections.Generic.IEnumerable <Main.DocumentNodeAndName> GetDocumentNodeChildrenWithName()
 {
     if (null != _cellPen)
     {
         yield return(new Main.DocumentNodeAndName(_cellPen, () => _cellPen = null, "CellPen"));
     }
     if (null != _textBrush)
     {
         yield return(new Main.DocumentNodeAndName(_textBrush, () => _textBrush = null, "TextBrush"));
     }
     if (null != _backgroundBrush)
     {
         yield return(new Main.DocumentNodeAndName(_backgroundBrush, () => _backgroundBrush = null, "BackgroundBrush"));
     }
 }
Пример #20
0
        public ScatterPlotStyle(XYPlotScatterStyles.Shape shape, XYPlotScatterStyles.Style style, float size, float penWidth, Color penColor)
        {
            _shape      = shape;
            _style      = style;
            _dropLine   = new CSPlaneIDList();
            _pen        = new PenX(penColor, penWidth);
            _symbolSize = size;

            _relativePenWidth = penWidth / size;
            _skipFreq         = 1;

            // Cached values
            SetCachedValues();
            CreateEventChain();
        }
Пример #21
0
        public LinePlotStyle(Altaxo.Main.Properties.IReadOnlyPropertyBag context)
        {
            var penWidth = GraphDocument.GetDefaultPenWidth(context);
            var color    = GraphDocument.GetDefaultPlotColor(context);

            _linePen = new PenX(color, penWidth)
            {
                LineJoin = LineJoin.Bevel
            };
            _ignoreMissingDataPoints = false;
            _connectionStyle         = LineConnectionStyles.StraightConnection.Instance;
            _independentColor        = false;

            CreateEventChain();
        }
Пример #22
0
        public DropLinePlotStyle(Altaxo.Main.Properties.IReadOnlyPropertyBag context)
        {
            _dropTargets = new CSPlaneIDList(new[] { new CSPlaneID(1, 0) });

            var    color    = GraphDocument.GetDefaultPlotColor(context);
            double penWidth = GraphDocument.GetDefaultPenWidth(context);

            _pen = new PenX(color, penWidth)
            {
                ParentObject = this
            };

            _lineWidth1Offset = penWidth;
            _lineWidth1Factor = 0;
        }
Пример #23
0
        public ColumnStyle(ColumnStyle s)
        {
            _columnStyleType = s._columnStyleType;
            m_Size           = s.m_Size;

            _isCellPenCustom = s._isCellPenCustom;
            m_CellPen        = (PenX)s.m_CellPen.Clone();
            m_TextFormat     = (StringFormat)s.m_TextFormat.Clone();
            m_TextFont       = (Font)s.m_TextFont.Clone();

            _isTextBrushCustom = s._isTextBrushCustom;
            m_TextBrush        = (BrushX)s.m_TextBrush.Clone();

            _isBackgroundBrushCustom = s._isBackgroundBrushCustom;
            m_BackgroundBrush        = (BrushX)s.m_BackgroundBrush.Clone();
        }
Пример #24
0
        public BarGraphPlotStyle(BarGraphPlotStyle from)
        {
            this._relInnerGapWidth     = from._relInnerGapWidth;
            this._relOuterGapWidth     = from._relOuterGapWidth;
            this._width                = from._width;
            this._position             = from._position;
            this._independentColor     = from._independentColor;
            this._fillBrush            = from._fillBrush.Clone();
            this._framePen             = from._framePen == null ? null : (PenX)from._framePen.Clone();
            this._startAtPreviousItem  = from._startAtPreviousItem;
            this._previousItemYGap     = from._previousItemYGap;
            this._usePhysicalBaseValue = from._usePhysicalBaseValue;
            this._baseValue            = from._baseValue;

            this._parent = from._parent;
        }
Пример #25
0
        internal LinePlotStyle(Altaxo.Serialization.Xml.IXmlDeserializationInfo info, bool oldDeserializationRequiresFullConstruction)
        {
            var penWidth = 1;
            var color    = ColorSetManager.Instance.BuiltinDarkPlotColors[0];

            _linePen = new PenX(color, penWidth)
            {
                LineJoin = LineJoin.Bevel
            };
            _useSymbolGap            = true;
            _ignoreMissingDataPoints = false;
            _connectionStyle         = LineConnectionStyles.StraightConnection.Instance;
            _independentColor        = false;

            CreateEventChain();
        }
Пример #26
0
        public ScatterPlotStyle()
        {
            this._shape            = XYPlotScatterStyles.Shape.Square;
            this._style            = XYPlotScatterStyles.Style.Solid;
            this._dropLine         = new CSPlaneIDList();
            this._pen              = new PenX(Color.Black);
            this._independentColor = false;

            this._symbolSize = 8;

            this._relativePenWidth = 0.1f;
            this._skipFreq         = 1;
            this._cachedFillPath   = true; // since default is solid
            this._cachedFillBrush  = new BrushX(Color.Black);
            this._cachedPath       = GetPath(_shape, _style, _symbolSize);
            CreateEventChain();
        }
Пример #27
0
        public ColumnStyle(ColumnStyleType type)
        {
            _cellPen = new PenX(GdiColorHelper.ToNamedColor(SystemColors.InactiveBorder), 1)
            {
                ParentObject = this
            };
            _textBrush = new BrushX(GdiColorHelper.ToNamedColor(SystemColors.WindowText))
            {
                ParentObject = this
            };
            _backgroundBrush = new BrushX(GdiColorHelper.ToNamedColor(SystemColors.Window))
            {
                ParentObject = this
            };

            _columnStyleType = type;

            SetDefaultCellBorder();
            SetDefaultBackgroundBrush();
            SetDefaultTextBrush();
            SetDefaultTextFont();
        }
Пример #28
0
        public void ApplyGroupStyles(PlotGroupStyleCollection externalGroups, PlotGroupStyleCollection localGroups)
        {
            _cachedColorForIndexFunction = null;

            BarSizePosition2DGroupStyle bwp = PlotGroupStyle.GetStyleToApply <BarSizePosition2DGroupStyle>(externalGroups, localGroups);

            if (null != bwp)
            {
                bwp.Apply(out _relInnerGapX, out _relOuterGapX, out _xSizeLogical, out _xOffsetLogical);
            }

            if (!_independentFillColor)
            {
                if (null == _fillBrush)
                {
                    _fillBrush = new BrushX(Drawing.ColorManagement.ColorSetManager.Instance.BuiltinDarkPlotColors[0]);
                }
                ColorGroupStyle.ApplyStyle(externalGroups, localGroups, delegate(NamedColor c)
                                           { _fillBrush.Color = c; });

                // but if there is a color evaluation function, then use that function with higher priority
                VariableColorGroupStyle.ApplyStyle(externalGroups, localGroups, delegate(Func <int, Color> evalFunc)
                                                   { _cachedColorForIndexFunction = evalFunc; });
            }

            if (!_independentFrameColor)
            {
                if (null == _framePen)
                {
                    _framePen = new PenX(Drawing.ColorManagement.ColorSetManager.Instance.BuiltinDarkPlotColors[0]);
                }
                ColorGroupStyle.ApplyStyle(externalGroups, localGroups, delegate(NamedColor c)
                                           { _framePen.Color = c; });

                // but if there is a color evaluation function, then use that function with higher priority
                VariableColorGroupStyle.ApplyStyle(externalGroups, localGroups, delegate(Func <int, Color> evalFunc)
                                                   { _cachedColorForIndexFunction = evalFunc; });
            }
        }
Пример #29
0
        public void CopyFrom(FillToCurvePlotStyle from, bool copyWithDataReferences, Main.EventFiring eventFiring)
        {
            if (object.ReferenceEquals(this, from))
            {
                return;
            }

            using (var suspendToken = SuspendGetToken())
            {
                _independentFillColor = from._independentFillColor;
                FillBrush             = null == from._fillBrush ? null : from._fillBrush.Clone();

                _independentFrameColor = from._independentFrameColor;
                _framePen = null == from._framePen ? null : from._framePen.Clone();

                _fillToPrevPlotItem = from._fillToPrevPlotItem;
                _fillToNextPlotItem = from._fillToNextPlotItem;

                //this._parent = from._parent;

                suspendToken.Resume(eventFiring);
            }
        }
Пример #30
0
        /// <summary>
        /// Copy operation.
        /// </summary>
        /// <param name="from">The AxisStyle to copy from</param>
        public void CopyFrom(AxisLineStyle from)
        {
            if (_axisPen != null)
            {
                WireEventChain(false);
            }

            this._axisPen                 = null == from._axisPen ? null : (PenX)from._axisPen.Clone();
            this._axisPosition            = from._axisPosition;
            this._showFirstDownMajorTicks = from._showFirstDownMajorTicks;
            this._showFirstDownMinorTicks = from._showFirstDownMinorTicks;
            this._showFirstUpMajorTicks   = from._showFirstUpMajorTicks;
            this._showFirstUpMinorTicks   = from._showFirstUpMinorTicks;
            this._majorTickLength         = from._majorTickLength;
            this._majorTickPen            = null == from._majorTickPen ? null : (PenX)from._majorTickPen;
            this._minorTickLength         = from._minorTickLength;
            this._minorTickPen            = (null == from._minorTickPen) ? null : (PenX)from._minorTickPen;

            this._cachedAxisStyleInfo = from._cachedAxisStyleInfo;
            this._parent = from._parent;

            // Rewire the event chain
            WireEventChain(true);
        }
Пример #31
0
		internal LinePlotStyle(Altaxo.Serialization.Xml.IXmlDeserializationInfo info, bool oldDeserializationRequiresFullConstruction)
		{
			var penWidth = 1;
			var color = ColorSetManager.Instance.BuiltinDarkPlotColors[0];

			_linePen = new PenX(color, penWidth) { LineJoin = LineJoin.Bevel };
			_useSymbolGap = true;
			_ignoreMissingDataPoints = false;
			_connectionStyle = LineConnectionStyles.StraightConnection.Instance;
			_independentColor = false;

			CreateEventChain();
		}
Пример #32
0
		public void CopyFrom(LinePlotStyle from, Main.EventFiring eventFiring)
		{
			if (object.ReferenceEquals(this, from))
				return;

			using (var suspendToken = SuspendGetToken())
			{
				this._independentSkipFrequency = from._independentSkipFrequency;
				this._skipFrequency = from._skipFrequency;

				this._ignoreMissingDataPoints = from._ignoreMissingDataPoints;
				this._independentOnShiftingGroupStyles = from._independentOnShiftingGroupStyles;

				this._connectCircular = from._connectCircular;
				this._connectionStyle = from._connectionStyle;

				this._linePen = null == from._linePen ? null : (PenX)from._linePen.Clone();
				this._independentDashStyle = from._independentDashStyle;
				this._independentColor = from._independentColor;

				this._independentSymbolSize = from._independentSymbolSize;
				this._symbolSize = from._symbolSize;

				this._useSymbolGap = from._useSymbolGap;
				this._symbolGapOffset = from._symbolGapOffset;
				this._symbolGapFactor = from._symbolGapFactor;

				EhSelfChanged();

				suspendToken.Resume(eventFiring);
			}
		}
Пример #33
0
		public void CopyFrom(FillToCurvePlotStyle from, bool copyWithDataReferences, Main.EventFiring eventFiring)
		{
			if (object.ReferenceEquals(this, from))
				return;

			using (var suspendToken = SuspendGetToken())
			{
				this._independentFillColor = from._independentFillColor;
				this.FillBrush = null == from._fillBrush ? null : from._fillBrush.Clone();

				this._independentFrameColor = from._independentFrameColor;
				this._framePen = null == from._framePen ? null : from._framePen.Clone();

				this._fillToPrevPlotItem = from._fillToPrevPlotItem;
				this._fillToNextPlotItem = from._fillToNextPlotItem;

				//this._parent = from._parent;

				suspendToken.Resume(eventFiring);
			}
		}
Пример #34
0
		/// <summary>
		/// Template to make a line draw.
		/// </summary>
		/// <param name="g">Graphics context.</param>
		/// <param name="allLinePoints">The plot data. Don't use the Range property of the pdata, since it is overriden by the next argument.</param>
		/// <param name="range">The plot range to use.</param>
		/// <param name="layer">Graphics layer.</param>
		/// <param name="linePen">The pen to draw the line.</param>
		/// <param name="symbolGap">The size of the symbol gap. Argument is the original index of the data. The return value is the absolute symbol gap at this index.
		/// This function is null if no symbol gap is required.</param>
		/// <param name="skipFrequency">Skip frequency. Normally 1, thus all gaps are taken into account. If 2, only every 2nd gap is taken into account, and so on.</param>
		/// <param name="connectCircular">If true, there is a line connecting the start and the end of the range.</param>
		/// <param name="linePlotStyle">The line plot style.</param>
		public override void PaintOneRange(
			Graphics g,
			PointF[] allLinePoints,
			IPlotRange range,
			IPlotArea layer,
			PenX linePen,
			Func<int, double> symbolGap,
			int skipFrequency,
			bool connectCircular,
			LinePlotStyle linePlotStyle)
		{
			PointF[] circularLinePoints;

			if (!connectCircular && range.LowerBound == 0 && range.UpperBound == allLinePoints.Length)
			{
				// under optimal conditions we can use allLinePoints directly
				circularLinePoints = allLinePoints;
			}
			else
			{
				// otherwise, make a new array
				circularLinePoints = new PointF[range.Length + (connectCircular ? 1 : 0)];
				Array.Copy(allLinePoints, range.LowerBound, circularLinePoints, 0, range.Length); // Extract
				if (connectCircular)
					circularLinePoints[circularLinePoints.Length - 1] = circularLinePoints[0];
			}

			int lastIdx = range.Length - 1 + (connectCircular ? 1 : 0);
			GraphicsPath gp = new GraphicsPath();
			var layerSize = layer.Size;
			var rangeLowerBound = range.LowerBound;

			// special efforts are necessary to realize a line/symbol gap
			// I decided to use a path for this
			// and hope that not so many segments are added to the path due
			// to the exclusion criteria that a line only appears between two symbols (rel<0.5)
			// if the symbols do not overlap. So for a big array of points it is very likely
			// that the symbols overlap and no line between the symbols needs to be plotted
			if (null != symbolGap)
			{
				float xdiff, ydiff, startx, starty, stopx, stopy;
				if (skipFrequency <= 1) // skip all scatter symbol gaps -> thus skipOffset can be ignored
				{
					for (int i = 0; i < lastIdx; i++)
					{
						xdiff = circularLinePoints[i + 1].X - circularLinePoints[i].X;
						ydiff = circularLinePoints[i + 1].Y - circularLinePoints[i].Y;
						var diffLength = System.Math.Sqrt(xdiff * xdiff + ydiff * ydiff);
						double gapAtStart = symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i));
						double gapAtEnd;
						if (connectCircular && skipFrequency >= (range.Length - i))
							gapAtEnd = symbolGap(range.OriginalFirstPoint);
						else if (skipFrequency <= (range.Length - 1 - i))
							gapAtEnd = symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i + skipFrequency));
						else
							gapAtEnd = 0;

						var relAtStart = (float)(0.5 * gapAtStart / diffLength); // 0.5 because symbolGap is the full gap between two lines, thus between the symbol center and the beginning of the line it is only 1/2
						var relAtEnd = (float)(0.5 * gapAtEnd / diffLength); // 0.5 because symbolGap is the full gap between two lines, thus between the symbol center and the beginning of the line it is only 1/2

						if ((relAtStart + relAtEnd) < 1) // a line only appears if sum of the gaps  is smaller than 1
						{
							startx = circularLinePoints[i].X + relAtStart * xdiff;
							starty = circularLinePoints[i].Y + relAtStart * ydiff;
							stopx = circularLinePoints[i + 1].X - relAtEnd * xdiff;
							stopy = circularLinePoints[i + 1].Y - relAtEnd * ydiff;

							gp.AddLine(startx, starty, stopx, stopy);
							gp.StartFigure();
						}
					} // end for
					g.DrawPath(linePen, gp);
					gp.Reset();
				}
				else // skipFrequency is > 1
				{
					for (int i = 0; i < lastIdx; i += skipFrequency)
					{
						int subPointLengthM1 = Math.Min(skipFrequency, circularLinePoints.Length - 1 - i);
						double gapAtStart = symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i));
						double gapAtEnd;
						if (connectCircular && skipFrequency >= (range.Length - i))
							gapAtEnd = symbolGap(range.OriginalFirstPoint);
						else if (skipFrequency <= (range.Length - 1 - i))
							gapAtEnd = symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i + skipFrequency));
						else
							gapAtEnd = 0;

						if (subPointLengthM1 >= 1)
						{
							var polyline = circularLinePoints.ShortenPartialPolylineByDistanceFromStartAndEnd(i, i + subPointLengthM1, gapAtStart / 2, gapAtEnd / 2);

							if (null != polyline)
								g.DrawLines(linePen, polyline);
						}
					} // end for
				}
			}
			else // no line symbol gap required, so we can use DrawLines to draw the lines
			{
				if (circularLinePoints.Length > 1) // we don't want to have a drawing exception if number of points is only one
				{
					g.DrawLines(linePen, circularLinePoints);
				}
			}
		}
Пример #35
0
 public ErrorBarPlotStyle()
 {
   this._strokePen = new PenX(Color.Black);
 }
Пример #36
0
        /// <summary>
        /// Template to make a line draw.
        /// </summary>
        /// <param name="g">Graphics context.</param>
        /// <param name="allLinePoints">The plot data. Don't use the Range property of the pdata, since it is overriden by the next argument.</param>
        /// <param name="range">The plot range to use.</param>
        /// <param name="layer">Graphics layer.</param>
        /// <param name="linePen">The pen to draw the line.</param>
        /// <param name="symbolGap">The size of the symbol gap. Argument is the original index of the data. The return value is the absolute symbol gap at this index.
        /// This function is null if no symbol gap is required.</param>
        /// <param name="skipFrequency">Skip frequency. Normally 1, thus all gaps are taken into account. If 2, only every 2nd gap is taken into account, and so on.</param>
        /// <param name="connectCircular">If true, there is a line connecting the start and the end of the range.</param>
        /// <param name="linePlotStyle">The line plot style.</param>
        public override void PaintOneRange(
            Graphics g,
            PointF[] allLinePoints,
            IPlotRange range,
            IPlotArea layer,
            PenX linePen,
            Func <int, double> symbolGap,
            int skipFrequency,
            bool connectCircular,
            LinePlotStyle linePlotStyle)
        {
            PointF[] subLinePoints = Segment2Connection_GetSubPoints(allLinePoints, range, layer, connectCircular, out var lastIdx);

            var gp = new GraphicsPath();
            int i;

            // special efforts are necessary to realize a line/symbol gap
            // I decided to use a path for this
            // and hope that not so many segments are added to the path due
            // to the exclusion criteria that a line only appears between two symbols (rel<0.5)
            // if the symbols do not overlap. So for a big array of points it is very likely
            // that the symbols overlap and no line between the symbols needs to be plotted
            if (null != symbolGap)
            {
                float startx, starty, stopx, stopy;
                for (i = 0; i < lastIdx; i += 2)
                {
                    var diff       = GdiExtensionMethods.Subtract(subLinePoints[i + 1], subLinePoints[i]);
                    var diffLength = GdiExtensionMethods.VectorLength(diff);

                    int    originalIndex = range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i);
                    double gapAtStart    = 0 == i % skipFrequency ? symbolGap(originalIndex) : 0;
                    double gapAtEnd;
                    if ((0 == (i + 1) % skipFrequency) || ((i + 1) == range.Length))
                    {
                        gapAtEnd = ((i + 1) != range.Length) ? symbolGap(originalIndex + 1) : symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound));
                    }
                    else
                    {
                        gapAtEnd = 0;
                    }

                    var relAtStart = (float)(0.5 * gapAtStart / diffLength); // 0.5 because symbolGap is the full gap between two lines, thus between the symbol center and the beginning of the line it is only 1/2
                    var relAtEnd   = (float)(0.5 * gapAtEnd / diffLength);   // 0.5 because symbolGap is the full gap between two lines, thus between the symbol center and the beginning of the line it is only 1/2
                    if ((relAtStart + relAtEnd) < 1)                         // a line only appears if sum of the gaps  is smaller than 1
                    {
                        startx = subLinePoints[i].X + relAtStart * diff.X;
                        starty = subLinePoints[i].Y + relAtStart * diff.Y;
                        stopx  = subLinePoints[i + 1].X - relAtEnd * diff.X;
                        stopy  = subLinePoints[i + 1].Y - relAtEnd * diff.Y;

                        gp.AddLine(startx, starty, stopx, stopy);
                        gp.StartFigure();
                    }
                } // end for
                g.DrawPath(linePen, gp);
                gp.Reset();
            }
            else // no line symbol gap required, so we can use DrawLines to draw the lines
            {
                for (i = 0; i < lastIdx; i += 2)
                {
                    gp.AddLine(subLinePoints[i].X, subLinePoints[i].Y, subLinePoints[i + 1].X, subLinePoints[i + 1].Y);
                    gp.StartFigure();
                } // end for
                g.DrawPath(linePen, gp);
                gp.Reset();
            }
        }
Пример #37
0
		public DropLinePlotStyle(Altaxo.Main.Properties.IReadOnlyPropertyBag context)
		{
			this._dropTargets = new CSPlaneIDList(new[] { new CSPlaneID(1, 0) });

			var color = GraphDocument.GetDefaultPlotColor(context);
			double penWidth = GraphDocument.GetDefaultPenWidth(context);
			_pen = new PenX(color, penWidth) { ParentObject = this };

			_lineWidth1Offset = penWidth;
			_lineWidth1Factor = 0;
		}
Пример #38
0
    public ScatterPlotStyle()
    {
      this._shape = XYPlotScatterStyles.Shape.Square;
      this._style = XYPlotScatterStyles.Style.Solid;
      this._dropLine = new CSPlaneIDList();
      this._pen = new PenX(Color.Black);
      this._independentColor = false;

      this._symbolSize = 8;

      this._relativePenWidth = 0.1f;
      this._skipFreq = 1;
      this._cachedFillPath = true; // since default is solid
      this._cachedFillBrush = new BrushX(Color.Black);
      this._cachedPath = GetPath(_shape, _style, _symbolSize);
      CreateEventChain();
    }
Пример #39
0
    public ScatterPlotStyle(XYPlotScatterStyles.Shape shape, XYPlotScatterStyles.Style style, float size, float penWidth, Color penColor)
    {
      _shape = shape;
      _style = style;
      _dropLine = new CSPlaneIDList();
      _pen = new PenX(penColor, penWidth);
      _symbolSize = size;

      _relativePenWidth = penWidth / size;
      _skipFreq = 1;

      // Cached values
      SetCachedValues();
      CreateEventChain();
    }
Пример #40
0
    public void CopyFrom(ScatterPlotStyle from, bool suppressChangeEvent)
    {
      this._shape = from._shape;
      this._style = from._style;
      if(null==this._dropLine)
        this._dropLine = new CSPlaneIDList();
      else 
        this._dropLine.Clear();
      this._dropLine.AddClonedRange(from._dropLine);
      this._pen = null == from._pen ? null : (PenX)from._pen.Clone();
      this._independentColor = from._independentColor;
      this._independentSymbolSize = from._independentSymbolSize;


      this._symbolSize = from._symbolSize;
      this._relativePenWidth = from._relativePenWidth;
      this._skipFreq = from._skipFreq;

      this._cachedPath = null == from._cachedPath ? null : (GraphicsPath)from._cachedPath.Clone();
      this._cachedFillPath = from._cachedFillPath;
      this._cachedFillBrush = null == from._cachedFillBrush ? null : (BrushX)from._cachedFillBrush.Clone();
      this._parent = from._parent;

      if (!suppressChangeEvent)
        OnChanged();
    }
Пример #41
0
        /// <summary>
        /// Template to make a line draw.
        /// </summary>
        /// <param name="g">Graphics context.</param>
        /// <param name="allLinePoints">The plot data. Don't use the Range property of the pdata, since it is overriden by the next argument.</param>
        /// <param name="range">The plot range to use.</param>
        /// <param name="layer">Graphics layer.</param>
        /// <param name="linePen">The pen to draw the line.</param>
        /// <param name="symbolGap">The size of the symbol gap. Argument is the original index of the data. The return value is the absolute symbol gap at this index.
        /// This function is null if no symbol gap is required.</param>
        /// <param name="skipFrequency">Skip frequency. Normally 1, thus all gaps are taken into account. If 2, only every 2nd gap is taken into account, and so on.</param>
        /// <param name="connectCircular">If true, there is a line connecting the start and the end of the range.</param>
        /// <param name="linePlotStyle">The line plot style.</param>
        public override void PaintOneRange(
            Graphics g,
            PointF[] allLinePoints,
            IPlotRange range,
            IPlotArea layer,
            PenX linePen,
            Func <int, double> symbolGap,
            int skipFrequency,
            bool connectCircular,
            LinePlotStyle linePlotStyle)
        {
            if (range.Length <= 1)
            {
                return; // seems to be only a single point, thus no connection possible
            }
            PointF[] circularLinePoints;
            int      indexBasePlotPoints; // index of the first plot point of this range in circularLinePoints array

            if (connectCircular)          // we have to copy the array in order to append the first point to the end
            {
                // otherwise, make a new array
                circularLinePoints = new PointF[range.Length + 1];
                Array.Copy(allLinePoints, range.LowerBound, circularLinePoints, 0, range.Length); // Extract
                circularLinePoints[circularLinePoints.Length - 1] = circularLinePoints[0];
                indexBasePlotPoints = 0;
            }
            else // use the array directly without copying
            {
                circularLinePoints  = allLinePoints;
                indexBasePlotPoints = range.LowerBound;
            }

            if (null != symbolGap)
            {
                foreach (var segmentRange in GetSegmentRanges(range, symbolGap, skipFrequency, connectCircular))
                {
                    if (segmentRange.IsFullRangeClosedCurve) // test if this is a closed polygon without any gaps -> draw a closed polygon and return
                    {
                        // use the whole circular arry to draw a closed polygon without any gaps
                        g.DrawPolygon(linePen, circularLinePoints);
                    }
                    else if (segmentRange.Length == 1) // special case only one line segment
                    {
                        int plotIndexAtStart = segmentRange.IndexAtSubRangeStart + indexBasePlotPoints;
                        int plotIndexAtEnd   = segmentRange.IndexAtSubRangeEnd + indexBasePlotPoints;

                        var xdiff      = circularLinePoints[plotIndexAtEnd].X - circularLinePoints[plotIndexAtStart].X;
                        var ydiff      = circularLinePoints[plotIndexAtEnd].Y - circularLinePoints[plotIndexAtStart].Y;
                        var diffLength = System.Math.Sqrt(xdiff * xdiff + ydiff * ydiff);

                        var relAtStart = (float)(0.5 * segmentRange.GapAtSubRangeStart / diffLength); // 0.5 because symbolGap is the full gap between two lines, thus between the symbol center and the beginning of the line it is only 1/2
                        var relAtEnd   = (float)(0.5 * segmentRange.GapAtSubRangeEnd / diffLength);   // 0.5 because symbolGap is the full gap between two lines, thus between the symbol center and the beginning of the line it is only 1/2

                        if ((relAtStart + relAtEnd) < 1)                                              // a line only appears if sum of the gaps  is smaller than 1
                        {
                            var startx = circularLinePoints[plotIndexAtStart].X + relAtStart * xdiff;
                            var starty = circularLinePoints[plotIndexAtStart].Y + relAtStart * ydiff;
                            var stopx  = circularLinePoints[plotIndexAtEnd].X - relAtEnd * xdiff;
                            var stopy  = circularLinePoints[plotIndexAtEnd].Y - relAtEnd * ydiff;

                            g.DrawLine(linePen, startx, starty, stopx, stopy);
                        }
                    }
                    else
                    {
                        int plotIndexAtStart  = segmentRange.IndexAtSubRangeStart + indexBasePlotPoints;
                        int plotIndexAtEnd    = segmentRange.IndexAtSubRangeEnd + indexBasePlotPoints;
                        var shortenedPolyline = circularLinePoints.ShortenPartialPolylineByDistanceFromStartAndEnd(plotIndexAtStart, plotIndexAtEnd, segmentRange.GapAtSubRangeStart / 2, segmentRange.GapAtSubRangeEnd / 2);

                        if (null != shortenedPolyline)
                        {
                            g.DrawLines(linePen, shortenedPolyline);
                        }
                    }
                } // end for
            }
            else  // no line symbol gap required, so we can use DrawLines or DrawPolygon to draw the lines
            {
                if (connectCircular) // array was already copied from original array
                {
                    g.DrawPolygon(linePen, circularLinePoints);
                }
                else if (indexBasePlotPoints == 0 && range.Length == circularLinePoints.Length) // can use original array directly
                {
                    g.DrawLines(linePen, circularLinePoints);
                }
                else
                {
                    circularLinePoints = new PointF[range.Length];
                    Array.Copy(allLinePoints, range.LowerBound, circularLinePoints, 0, range.Length);
                    g.DrawLines(linePen, circularLinePoints);
                }
            }
        }
Пример #42
0
		/// <summary>
		/// Creates a default axis style.
		/// </summary>
		public AxisLineStyle(Main.Properties.IReadOnlyPropertyBag context)
		{
			double penWidth = GraphDocument.GetDefaultPenWidth(context);
			double majorTickLength = GraphDocument.GetDefaultMajorTickLength(context);
			var color = GraphDocument.GetDefaultForeColor(context);

			_axisPen = new PenX(color, penWidth) { ParentObject = this };
			_majorTickPen = new PenX(color, penWidth) { ParentObject = this };
			_minorTickPen = new PenX(color, penWidth) { ParentObject = this };
			_majorTickLength = majorTickLength;
			_minorTickLength = majorTickLength / 2;
			_showFirstUpMajorTicks = true; // true if right major ticks should be visible
			_showFirstDownMajorTicks = true; // true if left major ticks should be visible
			_showFirstUpMinorTicks = true; // true if right minor ticks should be visible
			_showFirstDownMinorTicks = true; // true if left minor ticks should be visible
		}
Пример #43
0
		public LinePlotStyle(Altaxo.Main.Properties.IReadOnlyPropertyBag context)
		{
			var penWidth = GraphDocument.GetDefaultPenWidth(context);
			var color = GraphDocument.GetDefaultPlotColor(context);

			_linePen = new PenX(color, penWidth) { LineJoin = LineJoin.Bevel };
			_ignoreMissingDataPoints = false;
			_connectionStyle = LineConnectionStyles.StraightConnection.Instance;
			_independentColor = false;

			CreateEventChain();
		}
Пример #44
0
		private IEnumerable<Main.DocumentNodeAndName> GetMyDocumentNodeChildrenWithName()
		{
			if (null != _linePen)
				yield return new Main.DocumentNodeAndName(_linePen, () => _linePen = null, "LinePen");

			if (null != _outlinePen)
				yield return new Main.DocumentNodeAndName(_outlinePen, () => _outlinePen = null, "OutlinePen");
		}
Пример #45
0
		protected override IEnumerable<Main.DocumentNodeAndName> GetDocumentNodeChildrenWithName()
		{
			if (null != _pen)
				yield return new DocumentNodeAndName(_pen, () => _pen = null, "Pen");
		}
Пример #46
0
		public ErrorBarPlotStyle(Altaxo.Main.Properties.IReadOnlyPropertyBag context)
		{
			var penWidth = GraphDocument.GetDefaultPenWidth(context);
			var color = GraphDocument.GetDefaultPlotColor(context);

			_lineWidth1Offset = penWidth;
			_lineWidth1Factor = 0;

			this._pen = new PenX(color, penWidth) { EndCap = new Altaxo.Graph.Gdi.LineCaps.SymBarLineCap(), ParentObject = this };
		}
Пример #47
0
		public DropLinePlotStyle(IEnumerable<CSPlaneID> planeIDs, PenX pen)
		{
			if (null == pen)
				throw new ArgumentNullException(nameof(pen));

			ChildSetMember(ref _pen, pen);
			this._dropTargets = new CSPlaneIDList(planeIDs);

			// Cached values
			SetCachedValues();
		}
Пример #48
0
		public bool CopyFrom(object obj, bool copyWithDataReferences)
		{
			if (object.ReferenceEquals(this, obj))
				return true;
			var from = obj as VectorCartesicPlotStyle;
			if (null != from)
			{
				this._meaningOfValues = from._meaningOfValues;
				this._independentSkipFrequency = from._independentSkipFrequency;
				this._skipFrequency = from._skipFrequency;
				this._ignoreMissingDataPoints = from._ignoreMissingDataPoints;
				this._useManualVectorLength = from._useManualVectorLength;
				this._vectorLengthOffset = from._vectorLengthOffset;
				this._vectorLengthFactor = from._vectorLengthFactor;

				this._independentSymbolSize = from._independentSymbolSize;
				this._symbolSize = from._symbolSize;

				this._strokePen = from._strokePen;
				this._independentColor = from._independentColor;

				_lineWidth1Offset = from._lineWidth1Offset;
				_lineWidth1Factor = from._lineWidth1Factor;

				this._endCapSizeFactor = from._endCapSizeFactor;
				this._endCapSizeOffset = from._endCapSizeOffset;

				this._useSymbolGap = from._useSymbolGap;
				this._symbolGapFactor = from._symbolGapFactor;
				this._symbolGapOffset = from._symbolGapOffset;

				this._independentSkipFrequency = from._independentSkipFrequency;
				this._skipFrequency = from._skipFrequency;
				this._independentOnShiftingGroupStyles = from._independentOnShiftingGroupStyles;

				this._cachedLogicalShiftX = from._cachedLogicalShiftX;
				this._cachedLogicalShiftY = from._cachedLogicalShiftY;

				if (copyWithDataReferences)
				{
					ChildCloneToMember(ref _columnX, from._columnX);
					ChildCloneToMember(ref _columnY, from._columnY);
				}

				EhSelfChanged();
				return true;
			}
			return false;
		}
Пример #49
0
    /// <summary>
    /// Copy operation.
    /// </summary>
    /// <param name="from">The AxisStyle to copy from</param>
    public void CopyFrom(AxisLineStyle from)
    {
      if (_axisPen != null)
        WireEventChain(false);
     
      this._axisPen = null == from._axisPen ? null : (PenX)from._axisPen.Clone();
      this._axisPosition = from._axisPosition;
      this._showFirstDownMajorTicks = from._showFirstDownMajorTicks;
      this._showFirstDownMinorTicks = from._showFirstDownMinorTicks;
      this._showFirstUpMajorTicks = from._showFirstUpMajorTicks;
      this._showFirstUpMinorTicks = from._showFirstUpMinorTicks;
      this._majorTickLength  = from._majorTickLength;
      this._majorTickPen     = null==from._majorTickPen ? null : (PenX)from._majorTickPen;
      this._minorTickLength  = from._minorTickLength;
      this._minorTickPen     = (null==from._minorTickPen) ? null : (PenX)from._minorTickPen;

      this._cachedAxisStyleInfo = from._cachedAxisStyleInfo;
      this._parent = from._parent;

      // Rewire the event chain
      WireEventChain(true);
    }
Пример #50
0
		/// <summary>
		/// Template to make a line draw.
		/// </summary>
		/// <param name="g">Graphics context.</param>
		/// <param name="allLinePoints">The plot data. Don't use the Range property of the pdata, since it is overriden by the next argument.</param>
		/// <param name="range">The plot range to use.</param>
		/// <param name="layer">Graphics layer.</param>
		/// <param name="linePen">The pen to draw the line.</param>
		/// <param name="symbolGap">The size of the symbol gap. Argument is the original index of the data. The return value is the absolute symbol gap at this index.
		/// This function is null if no symbol gap is required.</param>
		/// <param name="skipFrequency">Skip frequency. Normally 1, thus all gaps are taken into account. If 2, only every 2nd gap is taken into account, and so on.</param>
		/// <param name="connectCircular">If true, there is a line connecting the start and the end of the range.</param>
		/// <param name="linePlotStyle">The line plot style.</param>
		public override void PaintOneRange(
			Graphics g,
			PointF[] allLinePoints,
			IPlotRange range,
			IPlotArea layer,
			PenX linePen,
			Func<int, double> symbolGap,
			int skipFrequency,
			bool connectCircular,
			LinePlotStyle linePlotStyle)
		{
			int lastIdx;
			PointF[] subLinePoints = Segment2Connection_GetSubPoints(allLinePoints, range, layer, connectCircular, out lastIdx);

			GraphicsPath gp = new GraphicsPath();
			int i;

			// special efforts are necessary to realize a line/symbol gap
			// I decided to use a path for this
			// and hope that not so many segments are added to the path due
			// to the exclusion criteria that a line only appears between two symbols (rel<0.5)
			// if the symbols do not overlap. So for a big array of points it is very likely
			// that the symbols overlap and no line between the symbols needs to be plotted
			if (null != symbolGap)
			{
				float startx, starty, stopx, stopy;
				for (i = 0; i < lastIdx; i += 2)
				{

					var diff = GdiExtensionMethods.Subtract(subLinePoints[i + 1], subLinePoints[i]);
					var diffLength = GdiExtensionMethods.VectorLength(diff);

					int originalIndex = range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i);
					double gapAtStart = 0 == i % skipFrequency ? symbolGap(originalIndex) : 0;
					double gapAtEnd;
					if ((0 == (i + 1) % skipFrequency) || ((i + 1) == range.Length))
					{
						gapAtEnd = ((i + 1) != range.Length) ? symbolGap(originalIndex + 1) : symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound));
					}
					else
					{
						gapAtEnd = 0;
					}

					var relAtStart = (float)(0.5 * gapAtStart / diffLength); // 0.5 because symbolGap is the full gap between two lines, thus between the symbol center and the beginning of the line it is only 1/2
					var relAtEnd = (float)(0.5 * gapAtEnd / diffLength); // 0.5 because symbolGap is the full gap between two lines, thus between the symbol center and the beginning of the line it is only 1/2
					if ((relAtStart + relAtEnd) < 1) // a line only appears if sum of the gaps  is smaller than 1
					{
						startx = subLinePoints[i].X + relAtStart * diff.X;
						starty = subLinePoints[i].Y + relAtStart * diff.Y;
						stopx = subLinePoints[i + 1].X - relAtEnd * diff.X;
						stopy = subLinePoints[i + 1].Y - relAtEnd * diff.Y;

						gp.AddLine(startx, starty, stopx, stopy);
						gp.StartFigure();
					}
				} // end for
				g.DrawPath(linePen, gp);
				gp.Reset();
			}
			else // no line symbol gap required, so we can use DrawLines to draw the lines
			{
				for (i = 0; i < lastIdx; i += 2)
				{
					gp.AddLine(subLinePoints[i].X, subLinePoints[i].Y, subLinePoints[i + 1].X, subLinePoints[i + 1].Y);
					gp.StartFigure();
				} // end for
				g.DrawPath(linePen, gp);
				gp.Reset();
			}
		}
Пример #51
0
 void CopyFrom(ErrorBarPlotStyle from)
 {
   this._independentSymbolSize = from._independentSymbolSize;
   this._symbolSize = from._symbolSize;
   this._symbolGap = from._symbolGap;
   this._independentColor = from._independentColor;
   this._showEndBars = from._showEndBars;
   this._isHorizontalStyle = from._isHorizontalStyle;
   this._doNotShiftHorizontalPosition = from._doNotShiftHorizontalPosition;
   this._strokePen = (PenX)from._strokePen.Clone();
   this._positiveErrorColumn = (NumericColumnProxy)from._positiveErrorColumn.Clone();
   this._negativeErrorColumn = (NumericColumnProxy)from._negativeErrorColumn.Clone();
   this._cachedLogicalShiftOfIndependent = from._cachedLogicalShiftOfIndependent;
 }
Пример #52
0
        /// <summary>
        /// Template to make a line draw.
        /// </summary>
        /// <param name="g">Graphics context.</param>
        /// <param name="allLinePoints">The plot data. Don't use the Range property of the pdata, since it is overriden by the next argument.</param>
        /// <param name="range">The plot range to use.</param>
        /// <param name="layer">Graphics layer.</param>
        /// <param name="linePen">The pen to draw the line.</param>
        /// <param name="symbolGap">The size of the symbol gap. Argument is the original index of the data. The return value is the absolute symbol gap at this index.
        /// This function is null if no symbol gap is required.</param>
        /// <param name="skipFrequency">Skip frequency. Normally 1, thus all gaps are taken into account. If 2, only every 2nd gap is taken into account, and so on.</param>
        /// <param name="connectCircular">If true, there is a line connecting the start and the end of the range.</param>
        /// <param name="linePlotStyle">The line plot style.</param>
        public override void PaintOneRange(
            Graphics g,
            PointF[] allLinePoints,
            IPlotRange range,
            IPlotArea layer,
            PenX linePen,
            Func <int, double> symbolGap,
            int skipFrequency,
            bool connectCircular,
            LinePlotStyle linePlotStyle)
        {
            // Bezier is only supported with point numbers n=4+3*k
            // so trim the range appropriately
            if (range.Length < 4)
            {
                return; // then too less points are in this range
            }
            PointF[] circularLinePoints;

            if (connectCircular)
            {
                var circularLinePointsLengthM1 = 2 + TrimToValidBezierLength(range.Length);
                circularLinePoints = new PointF[circularLinePointsLengthM1 + 1];
                Array.Copy(allLinePoints, range.LowerBound, circularLinePoints, 0, range.Length); // Extract
                circularLinePoints[circularLinePointsLengthM1] = circularLinePoints[0];

                // amend missing control points
                if (circularLinePointsLengthM1 - range.Length >= 1)
                {
                    circularLinePoints[circularLinePointsLengthM1 - 1] = GdiExtensionMethods.Interpolate(circularLinePoints[circularLinePointsLengthM1 - 3], circularLinePoints[circularLinePointsLengthM1], 0.5); // Last Control point should be halfway between
                }
                if (circularLinePointsLengthM1 - range.Length >= 2)
                {
                    circularLinePoints[circularLinePointsLengthM1 - 2] = GdiExtensionMethods.Interpolate(circularLinePoints[circularLinePointsLengthM1 - 3], circularLinePoints[circularLinePointsLengthM1], 0.5); // Middle Control point should be halfway between previous fixed point and last(=first) fixed point
                }
                range = range.WithUpperBoundExtendedBy(circularLinePointsLengthM1 - range.Length);
            }
            else // not circular
            {
                var trimmedLength = TrimToValidBezierLength(range.Length);
                if (range.Length != trimmedLength)
                {
                    range = range.WithUpperBoundShortenedBy(range.Length - trimmedLength);
                }

                if (range.LowerBound == 0 && trimmedLength == allLinePoints.Length)
                {
                    circularLinePoints = allLinePoints;
                }
                else
                {
                    circularLinePoints = new PointF[trimmedLength];
                    Array.Copy(allLinePoints, range.LowerBound, circularLinePoints, 0, trimmedLength); // Extract
                }
            }

            if (null != symbolGap)                                                                  // circular with symbol gap
            {
                var realSkipFrequency = skipFrequency % 3 == 0 ? skipFrequency : skipFrequency * 3; // least common multiple of skipFrequency and 3
                var skipLinePoints    = new PointF[0];
                foreach (var segmentRange in GetSegmentRanges(range, symbolGap, realSkipFrequency, connectCircular))
                {
                    if (segmentRange.IsFullRangeClosedCurve) // test if this is a closed polygon without any gaps -> draw a closed polygon and return
                    {
                        // use the whole circular arry to draw a closed polygon without any gaps
                        g.DrawBeziers(linePen, circularLinePoints);
                    }
                    else
                    {
                        var skipLinePointsLength = 1 + segmentRange.Length;
                        if (skipLinePoints.Length != skipLinePointsLength)
                        {
                            skipLinePoints = new PointF[skipLinePointsLength];
                        }
                        Array.Copy(circularLinePoints, segmentRange.IndexAtSubRangeStart, skipLinePoints, 0, skipLinePointsLength);

                        PointF[] shortenedLinePoints;
                        if (segmentRange.GapAtSubRangeStart != 0 || segmentRange.GapAtSubRangeEnd != 0)
                        {
                            shortenedLinePoints = GdiExtensionMethods.ShortenBezierCurve(skipLinePoints, segmentRange.GapAtSubRangeStart / 2, segmentRange.GapAtSubRangeEnd / 2);
                        }
                        else
                        {
                            shortenedLinePoints = skipLinePoints;
                        }

                        if (null != shortenedLinePoints)
                        {
                            g.DrawBeziers(linePen, shortenedLinePoints);
                        }
                    }
                }
            }
            else // no symbol gap
            {
                g.DrawBeziers(linePen, circularLinePoints);
            }
        }
Пример #53
0
		/// <summary>
		/// Template to make a line draw.
		/// </summary>
		/// <param name="g">Graphics context.</param>
		/// <param name="allLinePoints">The plot data. Don't use the Range property of the pdata, since it is overriden by the next argument.</param>
		/// <param name="range">The plot range to use.</param>
		/// <param name="layer">Graphics layer.</param>
		/// <param name="linePen">The pen to draw the line.</param>
		/// <param name="symbolGap">The size of the symbol gap. Argument is the original index of the data. The return value is the absolute symbol gap at this index.
		/// This function is null if no symbol gap is required.</param>
		/// <param name="skipFrequency">Skip frequency. Normally 1, thus all gaps are taken into account. If 2, only every 2nd gap is taken into account, and so on.</param>
		/// <param name="connectCircular">If true, there is a line connecting the start and the end of the range.</param>
		/// <param name="linePlotStyle">The line plot style.</param>
		public override void PaintOneRange(
			Graphics g,
			PointF[] allLinePoints,
			IPlotRange range,
			IPlotArea layer,
			PenX linePen,
			Func<int, double> symbolGap,
			int skipFrequency,
			bool connectCircular,
			LinePlotStyle linePlotStyle)
		{
			// Bezier is only supported with point numbers n=4+3*k
			// so trim the range appropriately
			if (range.Length < 4)
				return; // then too less points are in this range

			if (connectCircular)
			{
				var circularLinePointsLengthM1 = 2 + TrimToValidBezierLength(range.Length);
				var circularLinePoints = new PointF[circularLinePointsLengthM1 + 1];
				Array.Copy(allLinePoints, range.LowerBound, circularLinePoints, 0, range.Length); // Extract
				circularLinePoints[circularLinePointsLengthM1] = circularLinePoints[0];

				// amend missing control points
				if (circularLinePointsLengthM1 - range.Length >= 1)
					circularLinePoints[circularLinePointsLengthM1 - 1] = GdiExtensionMethods.Interpolate(circularLinePoints[circularLinePointsLengthM1 - 3], circularLinePoints[circularLinePointsLengthM1], 0.5); // Last Control point should be halfway between
				if (circularLinePointsLengthM1 - range.Length >= 2)
					circularLinePoints[circularLinePointsLengthM1 - 2] = GdiExtensionMethods.Interpolate(circularLinePoints[circularLinePointsLengthM1 - 3], circularLinePoints[circularLinePointsLengthM1], 0.5); // Middle Control point should be halfway between previous fixed point and last(=first) fixed point

				if (null != symbolGap) // circular with symbol gap
				{
					var realSkipFrequency = skipFrequency % 3 == 0 ? skipFrequency : skipFrequency * 3; // least common multiple of skipFrequency and 3
					for (int i = 0; i < range.Length; i += realSkipFrequency)
					{
						var skipLinePointsLength = Math.Min(realSkipFrequency + 1, TrimToValidBezierLength(circularLinePoints.Length - i));
						if (skipLinePointsLength >= 4)
						{
							var skipLinePoints = new PointF[skipLinePointsLength];
							Array.Copy(circularLinePoints, i, skipLinePoints, 0, skipLinePointsLength); // Extract

							var gapAtStart = symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i));
							double gapAtEnd;
							if (connectCircular && realSkipFrequency >= (range.Length - 1 - i))
								gapAtEnd = symbolGap(range.OriginalFirstPoint);
							else if (realSkipFrequency <= (range.Length - 1 - i))
								gapAtEnd = symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i + realSkipFrequency));
							else
								gapAtEnd = 0;

							if (gapAtStart != 0 || gapAtEnd != 0)
							{
								skipLinePoints = GdiExtensionMethods.ShortenBezierCurve(skipLinePoints, gapAtStart / 2, gapAtEnd / 2);
							}

							if (null != skipLinePoints)
							{
								g.DrawBeziers(linePen, skipLinePoints);
							}
						}
					}
				}
				else // circular without symbol gap
				{
					g.DrawBeziers(linePen, circularLinePoints);
				}
			}
			else // not circular
			{
				if (null != symbolGap) // not circular with symbol gap
				{
					var realSkipFrequency = skipFrequency % 3 == 0 ? skipFrequency : skipFrequency * 3; // least common multiple of skipFrequency and 3
					for (int i = 0; i < range.Length; i += realSkipFrequency)
					{
						var skipLinePointsLength = Math.Min(realSkipFrequency + 1, TrimToValidBezierLength(range.Length - i));
						if (skipLinePointsLength >= 4)
						{
							var skipLinePoints = new PointF[skipLinePointsLength];
							Array.Copy(allLinePoints, range.LowerBound + i, skipLinePoints, 0, skipLinePointsLength); // Extract

							var gapAtStart = symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i));
							var gapAtEnd = symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(range.LowerBound + i + skipLinePointsLength - 1));

							if (gapAtStart != 0 || gapAtEnd != 0)
							{
								skipLinePoints = GdiExtensionMethods.ShortenBezierCurve(skipLinePoints, gapAtStart / 2, gapAtEnd / 2);
							}

							if (null != skipLinePoints)
							{
								g.DrawBeziers(linePen, skipLinePoints);
							}
						}
					}
				}
				else // not circular without symbol gap
				{
					var trimmedLength = TrimToValidBezierLength(range.Length);
					var subLinePoints = new PointF[trimmedLength];
					Array.Copy(allLinePoints, range.LowerBound, subLinePoints, 0, trimmedLength); // Extract
					g.DrawBeziers(linePen, subLinePoints);
				}
			}
		}
Пример #54
0
		/// <summary>
		/// Template to make a line draw.
		/// </summary>
		/// <param name="g">Graphics context.</param>
		/// <param name="allLinePoints">The plot data. Don't use the Range property of the pdata, since it is overriden by the next argument.</param>
		/// <param name="range">The plot range to use.</param>
		/// <param name="layer">Graphics layer.</param>
		/// <param name="linePen">The pen to draw the line.</param>
		/// <param name="symbolGap">The size of the symbol gap. Argument is the original index of the data. The return value is the absolute symbol gap at this index.
		/// This function is null if no symbol gap is required.</param>
		/// <param name="skipFrequency">Skip frequency. Normally 1, thus all gaps are taken into account. If 2, only every 2nd gap is taken into account, and so on.</param>
		/// <param name="connectCircular">If true, there is a line connecting the start and the end of the range.</param>
		/// <param name="linePlotStyle">The line plot style.</param>
		public override void PaintOneRange(
			Graphics g,
			PointF[] allLinePoints,
			IPlotRange range,
			IPlotArea layer,
			PenX linePen,
			Func<int, double> symbolGap,
			int skipFrequency,
			bool connectCircular,
			LinePlotStyle linePlotStyle)
		{
			PointF[] subLinePoints;
			if (range.LowerBound == 0 && range.UpperBound == allLinePoints.Length)
			{
				// under optimal conditions we can use allLinePoints directly
				subLinePoints = allLinePoints;
			}
			else
			{
				// otherwise, make a new array
				subLinePoints = new PointF[range.Length];
				Array.Copy(allLinePoints, range.LowerBound, subLinePoints, 0, range.Length); // Extract
			}

			int lastIdx = range.Length - 1;
			var layerSize = layer.Size;

			if (connectCircular)
			{
				if (symbolGap != null)
				{
					// convert points to bezier segments
					var bezierSegments = GdiExtensionMethods.ClosedCardinalSplineToBezierSegments(subLinePoints, subLinePoints.Length);
					var subBezierSegments = new PointF[0];
					int subPointLengthM1, subBezierLength;
					for (int i = 0; i < (range.Length); i += skipFrequency)
					{
						subPointLengthM1 = Math.Min(skipFrequency, range.Length - i);
						int originalIndexAtStart = range.GetOriginalRowIndexFromPlotPointIndex(i + range.LowerBound);
						double gapAtStart = symbolGap(originalIndexAtStart);
						int originalIndexAtEnd = ((i + skipFrequency) < range.Length) ? range.GetOriginalRowIndexFromPlotPointIndex(i + range.LowerBound + skipFrequency) : range.OriginalFirstPoint;
						double gapAtEnd = symbolGap(originalIndexAtEnd);
						subBezierLength = 3 * subPointLengthM1 + 1;
						if (subBezierSegments.Length != subBezierLength)
							subBezierSegments = new PointF[subBezierLength];

						Array.Copy(bezierSegments, i * 3, subBezierSegments, 0, subBezierLength);
						var shortenedBezierSegments = GdiExtensionMethods.ShortenBezierCurve(subBezierSegments, gapAtStart / 2, gapAtEnd / 2);

						if (null != shortenedBezierSegments)
						{
							g.DrawBeziers(linePen, shortenedBezierSegments);
						}
					}
				}
				else
				{
					g.DrawClosedCurve(linePen, subLinePoints);
				}
			}
			else
			{
				if (symbolGap != null)
				{
					// convert points to bezier segments
					var bezierSegments = GdiExtensionMethods.OpenCardinalSplineToBezierSegments(subLinePoints, subLinePoints.Length);
					var subBezierSegments = new PointF[0];
					int subPointLengthM1, subBezierLength;
					for (int i = 0; i < (range.Length - 1); i += skipFrequency)
					{
						subPointLengthM1 = Math.Min(skipFrequency, range.Length - 1 - i);
						int originalIndex = range.GetOriginalRowIndexFromPlotPointIndex(i + range.LowerBound);
						double gapAtStart = symbolGap(originalIndex);
						double gapAtEnd = subPointLengthM1 == skipFrequency ? symbolGap(range.GetOriginalRowIndexFromPlotPointIndex(i + range.LowerBound + skipFrequency)) : 0;
						subBezierLength = 3 * subPointLengthM1 + 1;
						if (subBezierSegments.Length != subBezierLength)
							subBezierSegments = new PointF[subBezierLength];

						Array.Copy(bezierSegments, i * 3, subBezierSegments, 0, subBezierLength);
						var shortenedBezierSegments = GdiExtensionMethods.ShortenBezierCurve(subBezierSegments, gapAtStart / 2, gapAtEnd / 2);

						if (null != shortenedBezierSegments)
						{
							g.DrawBeziers(linePen, shortenedBezierSegments);
						}
					}
				}
				else
				{
					g.DrawCurve(linePen, subLinePoints);
				}
			}
		}