示例#1
0
        /// <summary>Adds the y-values of a plot item to an array of y-values..</summary>
        /// <param name="yArray">The y array to be added to. If null, a new array will be allocated (and filled with the y-values of the plot item).</param>
        /// <param name="pdata">The pdata.</param>
        /// <returns>If the parameter <paramref name="yArray"/> was not null, then that <paramref name="yArray"/> is returned. Otherwise the newly allocated array is returned.</returns>
        public static AltaxoVariant[] AddUp(AltaxoVariant[] yArray, Processed2DPlotData pdata)
        {
            if (null == pdata)
            {
                throw new ArgumentNullException(nameof(pdata));
            }

            if (yArray == null)
            {
                yArray = new AltaxoVariant[pdata.RangeList.PlotPointCount];

                int j = -1;
                foreach (int originalIndex in pdata.RangeList.OriginalRowIndices())
                {
                    j++;
                    yArray[j] = pdata.GetYPhysical(originalIndex);
                }
            }
            else // this is not the first item
            {
                int j = -1;
                foreach (int originalIndex in pdata.RangeList.OriginalRowIndices())
                {
                    j++;
                    yArray[j] += pdata.GetYPhysical(originalIndex);
                }
            }
            return(yArray);
        }
示例#2
0
        public void MergeYBoundsInto(IPlotArea layer, IPhysicalBoundaries pb, PlotItemCollection coll)
        {
            var pbclone = (IPhysicalBoundaries)pb.Clone(); // before we can use CanUseStyle, we have to give physical y boundaries template

            CoordinateTransformingStyleBase.MergeYBoundsInto(pbclone, coll);
            if (!CanUseStyle(layer, coll, out var plotDataList))
            {
                pb.Add(pbclone);
                return;
            }

            // we put zero into the y-Boundaries, since the addition starts with that value
            pb.Add(new AltaxoVariant(0.0));

            AltaxoVariant[] ySumArray = null;

            int idx = -1;

            foreach (IGPlotItem pi in coll)
            {
                if (pi is G2DPlotItem)
                {
                    idx++;

                    var gpi = (G2DPlotItem)pi;
                    Processed2DPlotData pdata = plotDataList[gpi];

                    if (null != pdata)
                    {
                        // Note: we can not use AddUp function here, since
                        // when we have positive/negative items, the intermediate bounds
                        // might be wider than the bounds of the end result

                        if (ySumArray == null)
                        {
                            ySumArray = new AltaxoVariant[pdata.RangeList.PlotPointCount];

                            int j = -1;
                            foreach (int originalIndex in pdata.RangeList.OriginalRowIndices())
                            {
                                j++;
                                ySumArray[j] = pdata.GetYPhysical(originalIndex);
                                pb.Add(ySumArray[j]);
                            }
                        }
                        else // this is not the first item
                        {
                            int j = -1;
                            foreach (int originalIndex in pdata.RangeList.OriginalRowIndices())
                            {
                                j++;
                                ySumArray[j] += pdata.GetYPhysical(originalIndex);
                                pb.Add(ySumArray[j]);
                            }
                        }
                    }
                }
            }
        }
示例#3
0
        public void Paint(System.Drawing.Graphics g, IPlotArea layer, PlotItemCollection coll)
        {
            System.Drawing.Region[] clippingColl = new System.Drawing.Region[coll.Count];
            Processed2DPlotData[]   plotDataColl = new Processed2DPlotData[coll.Count];
            double[] xincColl = new double[coll.Count];
            double[] yincColl = new double[coll.Count];

            int idx = -1;
            Processed2DPlotData previousPlotData = null;

            for (int i = 0; i < coll.Count; i++)
            {
                if (coll[i] is G2DPlotItem)
                {
                    idx++;
                    double currxinc = xincColl[i] = idx * _xinc * _scaleXInc;
                    double curryinc = yincColl[i] = idx * _yinc * _scaleYInc;

                    G2DPlotItem         gpi      = coll[i] as G2DPlotItem;
                    Processed2DPlotData plotdata = plotDataColl[i] = gpi.GetRangesAndPoints(layer);
                    plotdata.PreviousItemData = previousPlotData;
                    previousPlotData          = plotdata;

                    int j = -1;
                    foreach (int rowIndex in plotdata.RangeList.OriginalRowIndices())
                    {
                        j++;

                        AltaxoVariant xx = plotdata.GetXPhysical(rowIndex) + currxinc;
                        AltaxoVariant yy = plotdata.GetYPhysical(rowIndex) + curryinc;

                        Logical3D rel = new Logical3D(layer.XAxis.PhysicalVariantToNormal(xx), layer.YAxis.PhysicalVariantToNormal(yy));
                        double    xabs, yabs;
                        layer.CoordinateSystem.LogicalToLayerCoordinates(rel, out xabs, out yabs);
                        plotdata.PlotPointsInAbsoluteLayerCoordinates[j] = new System.Drawing.PointF((float)xabs, (float)yabs);
                    }

                    if (_useClipping)
                    {
                        GraphicsPath path = new System.Drawing.Drawing2D.GraphicsPath();
                    }
                }
            }
            for (int i = coll.Count - 1; i >= 0; i--)
            {
                if (null == plotDataColl[i])
                {
                    coll[i].Paint(g, layer);
                }
                else
                {
                    TransformedLayerWrapper layerwrapper = new TransformedLayerWrapper(layer, xincColl[i], yincColl[i]);
                    ((G2DPlotItem)coll[i]).Paint(g, layerwrapper, plotDataColl[i]);
                }
            }
        }
示例#4
0
        public void Paint(System.Drawing.Graphics g, IPlotArea layer, Processed2DPlotData pdata, Processed2DPlotData prevItemData, Processed2DPlotData nextItemData)
        {
            if (null == pdata)
            {
                throw new ArgumentNullException(nameof(pdata));
            }

            PlotRangeList rangeList = pdata.RangeList;

            System.Drawing.PointF[] ptArray = pdata.PlotPointsInAbsoluteLayerCoordinates;
            layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(0, 0), out var xleft, out var ybottom);
            layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(1, 1), out var xright, out var ytop);
            float xe = (float)xright;
            float ye = (float)ybottom;

            var path = new GraphicsPath();

            double globalBaseValue;

            if (_usePhysicalBaseValue)
            {
                globalBaseValue = layer.YAxis.PhysicalVariantToNormal(_baseValue);
                if (double.IsNaN(globalBaseValue))
                {
                    globalBaseValue = 0;
                }
            }
            else
            {
                globalBaseValue = _baseValue.ToDouble();
            }

            bool useVariableFillColor  = null != _fillBrush && null != _cachedColorForIndexFunction && !_independentFillColor;
            bool useVariableFrameColor = null != _framePen && null != _cachedColorForIndexFunction && !_independentFrameColor;

            var fillBrush = _fillBrush == null ? null : useVariableFillColor?_fillBrush.Clone() : _fillBrush;

            var framePen = _framePen == null ? null : useVariableFrameColor?_framePen.Clone() : _framePen;

            int j = -1;

            foreach (int originalRowIndex in pdata.RangeList.OriginalRowIndices())
            {
                j++;

                double xcn = _xOffsetLogical + layer.XAxis.PhysicalVariantToNormal(pdata.GetXPhysical(originalRowIndex));
                double xln = xcn - 0.5 * _xSizeLogical;
                double xrn = xcn + 0.5 * _xSizeLogical;

                double ycn    = layer.YAxis.PhysicalVariantToNormal(pdata.GetYPhysical(originalRowIndex));
                double ynbase = globalBaseValue;

                if (_startAtPreviousItem && pdata.PreviousItemData != null)
                {
                    double prevstart = layer.YAxis.PhysicalVariantToNormal(pdata.PreviousItemData.GetYPhysical(originalRowIndex));
                    if (!double.IsNaN(prevstart))
                    {
                        ynbase  = prevstart;
                        ynbase += Math.Sign(ynbase - globalBaseValue) * _previousItemYGap;
                    }
                }

                path.Reset();
                layer.CoordinateSystem.GetIsoline(path, new Logical3D(xln, ynbase), new Logical3D(xln, ycn));
                layer.CoordinateSystem.GetIsoline(path, new Logical3D(xln, ycn), new Logical3D(xrn, ycn));
                layer.CoordinateSystem.GetIsoline(path, new Logical3D(xrn, ycn), new Logical3D(xrn, ynbase));
                layer.CoordinateSystem.GetIsoline(path, new Logical3D(xrn, ynbase), new Logical3D(xln, ynbase));
                path.CloseFigure();

                if (null != fillBrush)
                {
                    if (useVariableFillColor)
                    {
                        fillBrush.Color = GdiColorHelper.ToNamedColor(_cachedColorForIndexFunction(originalRowIndex), "VariableColor");
                    }

                    fillBrush.SetEnvironment(path.GetBounds(), BrushX.GetEffectiveMaximumResolution(g, 1));
                    g.FillPath(fillBrush, path);
                }

                if (null != framePen)
                {
                    if (useVariableFrameColor)
                    {
                        framePen.Color = GdiColorHelper.ToNamedColor(_cachedColorForIndexFunction(originalRowIndex), "VariableColor");
                    }

                    framePen.SetEnvironment(path.GetBounds(), BrushX.GetEffectiveMaximumResolution(g, 1));
                    g.DrawPath(framePen, path);
                }
            }
        }
示例#5
0
        protected void PaintOneRange(Graphics g, IPlotArea layer, IPlotRange range, Processed2DPlotData pdata)
        {
            const double logicalClampMinimum = -10;
            const double logicalClampMaximum = 11;

            // Plot error bars for the dependent variable (y)
            var columnX = ColumnX;
            var columnY = ColumnY;

            if (columnX == null || columnY == null)
            {
                return; // nothing to do if both error columns are null
            }
            if (!typeof(double).IsAssignableFrom(columnX.ItemType) || !typeof(double).IsAssignableFrom(columnY.ItemType))
            {
                return; // TODO make this an runtime paint error to be reported
            }
            var strokePen = _strokePen.Clone();

            using (var isoLine = new GraphicsPath())
            {
                int lower = range.LowerBound;
                int upper = range.UpperBound;

                for (int j = lower; j < upper; j += _skipFrequency)
                {
                    int    originalRowIndex = range.GetOriginalRowIndexFromPlotPointIndex(j);
                    double symbolSize       = null == _cachedSymbolSizeForIndexFunction ? _symbolSize : _cachedSymbolSizeForIndexFunction(originalRowIndex);

                    strokePen.Width = (_lineWidth1Offset + _lineWidth1Factor * symbolSize);

                    if (null != _cachedColorForIndexFunction)
                    {
                        strokePen.Color = GdiColorHelper.ToNamedColor(_cachedColorForIndexFunction(originalRowIndex), "VariableColor");
                    }

                    if (!(strokePen.EndCap is LineCaps.FlatCap))
                    {
                        strokePen.EndCap = strokePen.EndCap.WithMinimumAbsoluteAndRelativeSize(symbolSize * _endCapSizeFactor + _endCapSizeOffset, 1 + 1E-6);
                    }

                    // Calculate target
                    AltaxoVariant targetX, targetY;
                    switch (_meaningOfValues)
                    {
                    case ValueInterpretation.AbsoluteDifference:
                    {
                        targetX = pdata.GetXPhysical(originalRowIndex) + columnX[originalRowIndex];
                        targetY = pdata.GetYPhysical(originalRowIndex) + columnY[originalRowIndex];
                    }
                    break;

                    case ValueInterpretation.AbsoluteValue:
                    {
                        targetX = columnX[originalRowIndex];
                        targetY = columnY[originalRowIndex];
                    }
                    break;

                    default:
                        throw new NotImplementedException(nameof(_meaningOfValues));
                    }

                    var logicalTarget = layer.GetLogical3D(targetX, targetY);
                    var logicalOrigin = layer.GetLogical3D(pdata, originalRowIndex);

                    if (!_independentOnShiftingGroupStyles && (0 != _cachedLogicalShiftX || 0 != _cachedLogicalShiftY))
                    {
                        logicalOrigin.RX += _cachedLogicalShiftX;
                        logicalOrigin.RY += _cachedLogicalShiftY;
                        logicalTarget.RX += _cachedLogicalShiftX;
                        logicalTarget.RY += _cachedLogicalShiftY;
                    }

                    if (!Calc.RMath.IsInIntervalCC(logicalOrigin.RX, logicalClampMinimum, logicalClampMaximum))
                    {
                        continue;
                    }
                    if (!Calc.RMath.IsInIntervalCC(logicalOrigin.RY, logicalClampMinimum, logicalClampMaximum))
                    {
                        continue;
                    }
                    if (!Calc.RMath.IsInIntervalCC(logicalOrigin.RZ, logicalClampMinimum, logicalClampMaximum))
                    {
                        continue;
                    }

                    if (!Calc.RMath.IsInIntervalCC(logicalTarget.RX, logicalClampMinimum, logicalClampMaximum))
                    {
                        continue;
                    }
                    if (!Calc.RMath.IsInIntervalCC(logicalTarget.RY, logicalClampMinimum, logicalClampMaximum))
                    {
                        continue;
                    }
                    if (!Calc.RMath.IsInIntervalCC(logicalTarget.RZ, logicalClampMinimum, logicalClampMaximum))
                    {
                        continue;
                    }

                    isoLine.Reset();

                    layer.CoordinateSystem.GetIsoline(isoLine, logicalOrigin, logicalTarget);
                    if (null == isoLine)
                    {
                        continue;
                    }

                    PointF[] isoLinePathPoints = null;

                    if (_useManualVectorLength)
                    {
                        isoLine.Flatten();
                        isoLinePathPoints = isoLine.PathPoints;

                        double length        = _vectorLengthOffset + _vectorLengthFactor * symbolSize;
                        double isoLineLength = isoLinePathPoints.TotalLineLength();
                        isoLinePathPoints = isoLinePathPoints.ShortenedBy(RADouble.NewAbs(0), RADouble.NewAbs(isoLineLength - length));
                        if (null == isoLine)
                        {
                            continue;
                        }
                    }

                    if (_useSymbolGap)
                    {
                        if (null == isoLinePathPoints)
                        {
                            isoLine.Flatten();
                            isoLinePathPoints = isoLine.PathPoints;
                        }

                        double gap = _symbolGapOffset + _symbolGapFactor * symbolSize;
                        if (gap != 0)
                        {
                            isoLinePathPoints = isoLinePathPoints.ShortenedBy(RADouble.NewAbs(gap / 2), RADouble.NewAbs(0));
                            if (null == isoLine)
                            {
                                continue;
                            }
                        }
                    }

                    if (null != isoLinePathPoints)
                    {
                        g.DrawLines(_strokePen, isoLinePathPoints);
                    }
                    else
                    {
                        g.DrawPath(strokePen, isoLine);
                    }
                }
            }
        }
示例#6
0
        public void PaintPreprocessing(System.Drawing.Graphics g, IPaintContext paintContext, IPlotArea layer, PlotItemCollection coll)
        {
            var paintData = new CachedPaintData
            {
                _clippingColl = new System.Drawing.Region[coll.Count],
                _plotDataColl = new Processed2DPlotData[coll.Count],
                _xincColl     = new double[coll.Count],
                _yincColl     = new double[coll.Count]
            };

            paintContext.AddValue(this, paintData);

            // First prepare
            int idx = -1;
            Processed2DPlotData previousPlotData = null;

            for (int i = 0; i < coll.Count; i++)
            {
                if (coll[i] is G2DPlotItem)
                {
                    idx++;
                    double currxinc = paintData._xincColl[i] = idx * _xinc * _scaleXInc;
                    double curryinc = paintData._yincColl[i] = idx * _yinc * _scaleYInc;

                    var gpi = coll[i] as G2DPlotItem;
                    Processed2DPlotData plotdata = paintData._plotDataColl[i] = gpi.GetRangesAndPoints(layer);
                    plotdata.PreviousItemData = previousPlotData;
                    previousPlotData          = plotdata;

                    int j = -1;
                    foreach (int rowIndex in plotdata.RangeList.OriginalRowIndices())
                    {
                        j++;

                        AltaxoVariant xx = plotdata.GetXPhysical(rowIndex) + currxinc;
                        AltaxoVariant yy = plotdata.GetYPhysical(rowIndex) + curryinc;

                        var rel = new Logical3D(layer.XAxis.PhysicalVariantToNormal(xx), layer.YAxis.PhysicalVariantToNormal(yy));
                        layer.CoordinateSystem.LogicalToLayerCoordinates(rel, out var xabs, out var yabs);
                        plotdata.PlotPointsInAbsoluteLayerCoordinates[j] = new System.Drawing.PointF((float)xabs, (float)yabs);
                    }

                    // if clipping is used, we must get a clipping region for every plot item
                    // and combine the regions from
                    if (_useClipping)
                    {
                        if (i == 0)
                        {
                            paintData._clippingColl[i] = g.Clip;
                        }

                        Plot.Styles.LinePlotStyle linestyle = null;
                        foreach (Plot.Styles.IG2DPlotStyle st in gpi.Style)
                        {
                            if (st is Plot.Styles.LinePlotStyle)
                            {
                                linestyle = st as Plot.Styles.LinePlotStyle;
                                break;
                            }
                        }

                        if (null != linestyle)
                        {
                            var path = new System.Drawing.Drawing2D.GraphicsPath();
                            linestyle.GetFillPath(path, layer, plotdata, CSPlaneID.Bottom);
                            if ((i + 1) < paintData._clippingColl.Length)
                            {
                                paintData._clippingColl[i + 1] = paintData._clippingColl[i].Clone();
                                paintData._clippingColl[i + 1].Exclude(path);
                            }
                        }
                        else
                        {
                            if ((i + 1) < paintData._clippingColl.Length)
                            {
                                paintData._clippingColl[i + 1] = paintData._clippingColl[i];
                            }
                        }
                    }
                }
            }
        }
    public static AltaxoVariant[] AddUp(AltaxoVariant[] yArray, Processed2DPlotData pdata)
    {
      if (yArray == null)
      {
        yArray = new AltaxoVariant[pdata.RangeList.PlotPointCount];

        int j = -1;
        foreach (int originalIndex in pdata.RangeList.OriginalRowIndices())
        {
          j++;
          yArray[j] = pdata.GetYPhysical(originalIndex);
        }
      }
      else // this is not the first item
      {
        int j = -1;
        foreach (int originalIndex in pdata.RangeList.OriginalRowIndices())
        {
          j++;
          yArray[j] += pdata.GetYPhysical(originalIndex);
        }
      }
      return yArray;
    }
示例#8
0
		protected void PaintOneRange(Graphics g, IPlotArea layer, IPlotRange range, Processed2DPlotData pdata)
		{
			const double logicalClampMinimum = -10;
			const double logicalClampMaximum = 11;

			// Plot error bars for the dependent variable (y)
			var columnX = ColumnX;
			var columnY = ColumnY;

			if (columnX == null || columnY == null)
				return; // nothing to do if both error columns are null

			if (!typeof(double).IsAssignableFrom(columnX.ItemType) || !typeof(double).IsAssignableFrom(columnY.ItemType))
				return; // TODO make this an runtime paint error to be reported

			var strokePen = _strokePen.Clone();

			using (GraphicsPath isoLine = new GraphicsPath())
			{

				int lower = range.LowerBound;
				int upper = range.UpperBound;


				for (int j = lower; j < upper; j += _skipFrequency)
				{
					int originalRowIndex = range.GetOriginalRowIndexFromPlotPointIndex(j);
					double symbolSize = null == _cachedSymbolSizeForIndexFunction ? _symbolSize : _cachedSymbolSizeForIndexFunction(originalRowIndex);

					strokePen.Width = (_lineWidth1Offset + _lineWidth1Factor * symbolSize);

					if (null != _cachedColorForIndexFunction)
						strokePen.Color = GdiColorHelper.ToNamedColor(_cachedColorForIndexFunction(originalRowIndex), "VariableColor");

					if (!(strokePen.EndCap is LineCaps.FlatCap))
						strokePen.EndCap = strokePen.EndCap.WithMinimumAbsoluteAndRelativeSize(symbolSize * _endCapSizeFactor + _endCapSizeOffset, 1 + 1E-6);

					// Calculate target
					AltaxoVariant targetX, targetY;
					switch (_meaningOfValues)
					{
						case ValueInterpretation.AbsoluteDifference:
							{
								targetX = pdata.GetXPhysical(originalRowIndex) + columnX[originalRowIndex];
								targetY = pdata.GetYPhysical(originalRowIndex) + columnY[originalRowIndex];
							}
							break;

						case ValueInterpretation.AbsoluteValue:
							{
								targetX = columnX[originalRowIndex];
								targetY = columnY[originalRowIndex];
							}
							break;

						default:
							throw new NotImplementedException(nameof(_meaningOfValues));
					}

					var logicalTarget = layer.GetLogical3D(targetX, targetY);
					var logicalOrigin = layer.GetLogical3D(pdata, originalRowIndex);

					if (!_independentOnShiftingGroupStyles && (0 != _cachedLogicalShiftX || 0 != _cachedLogicalShiftY))
					{
						logicalOrigin.RX += _cachedLogicalShiftX;
						logicalOrigin.RY += _cachedLogicalShiftY;
						logicalTarget.RX += _cachedLogicalShiftX;
						logicalTarget.RY += _cachedLogicalShiftY;
					}

					if (!Calc.RMath.IsInIntervalCC(logicalOrigin.RX, logicalClampMinimum, logicalClampMaximum))
						continue;
					if (!Calc.RMath.IsInIntervalCC(logicalOrigin.RY, logicalClampMinimum, logicalClampMaximum))
						continue;
					if (!Calc.RMath.IsInIntervalCC(logicalOrigin.RZ, logicalClampMinimum, logicalClampMaximum))
						continue;

					if (!Calc.RMath.IsInIntervalCC(logicalTarget.RX, logicalClampMinimum, logicalClampMaximum))
						continue;
					if (!Calc.RMath.IsInIntervalCC(logicalTarget.RY, logicalClampMinimum, logicalClampMaximum))
						continue;
					if (!Calc.RMath.IsInIntervalCC(logicalTarget.RZ, logicalClampMinimum, logicalClampMaximum))
						continue;

					isoLine.Reset();

					layer.CoordinateSystem.GetIsoline(isoLine, logicalOrigin, logicalTarget);
					if (null == isoLine)
						continue;

					PointF[] isoLinePathPoints = null;

					if (_useManualVectorLength)
					{
						isoLine.Flatten();
						isoLinePathPoints = isoLine.PathPoints;

						double length = _vectorLengthOffset + _vectorLengthFactor * symbolSize;
						double isoLineLength = isoLinePathPoints.TotalLineLength();
						isoLinePathPoints = isoLinePathPoints.ShortenedBy(RADouble.NewAbs(0), RADouble.NewAbs(isoLineLength - length));
						if (null == isoLine)
							continue;
					}

					if (_useSymbolGap)
					{
						if (null == isoLinePathPoints)
						{
							isoLine.Flatten();
							isoLinePathPoints = isoLine.PathPoints;
						}

						double gap = _symbolGapOffset + _symbolGapFactor * symbolSize;
						if (gap != 0)
						{
							isoLinePathPoints = isoLinePathPoints.ShortenedBy(RADouble.NewAbs(gap / 2), RADouble.NewAbs(0));
							if (null == isoLine)
								continue;
						}
					}

					if (null != isoLinePathPoints)
						g.DrawLines(_strokePen, isoLinePathPoints);
					else
						g.DrawPath(strokePen, isoLine);
				}

			}
		}
示例#9
0
        public void Paint(System.Drawing.Graphics g, IPlotArea layer, Processed2DPlotData pdata)
        {
            PlotRangeList rangeList = pdata.RangeList;

            System.Drawing.PointF[] ptArray = pdata.PlotPointsInAbsoluteLayerCoordinates;

            // paint the drop style


            double xleft, xright, ytop, ybottom;

            layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(0, 0), out xleft, out ybottom);
            layer.CoordinateSystem.LogicalToLayerCoordinates(new Logical3D(1, 1), out xright, out ytop);
            float xe = (float)xright;
            float ye = (float)ybottom;

            GraphicsPath path = new GraphicsPath();

            double globalBaseValue;

            if (_usePhysicalBaseValue)
            {
                globalBaseValue = layer.YAxis.PhysicalVariantToNormal(_baseValue);
                if (double.IsNaN(globalBaseValue))
                {
                    globalBaseValue = 0;
                }
            }
            else
            {
                globalBaseValue = _baseValue.ToDouble();
            }


            int j = -1;

            foreach (int originalRowIndex in pdata.RangeList.OriginalRowIndices())
            {
                j++;

                double xcn = layer.XAxis.PhysicalVariantToNormal(pdata.GetXPhysical(originalRowIndex));
                double xln = xcn + _position;
                double xrn = xln + _width;

                double ycn    = layer.YAxis.PhysicalVariantToNormal(pdata.GetYPhysical(originalRowIndex));
                double ynbase = globalBaseValue;

                if (_startAtPreviousItem && pdata.PreviousItemData != null)
                {
                    double prevstart = layer.YAxis.PhysicalVariantToNormal(pdata.PreviousItemData.GetYPhysical(originalRowIndex));
                    if (!double.IsNaN(prevstart))
                    {
                        ynbase  = prevstart;
                        ynbase += Math.Sign(ynbase - globalBaseValue) * _previousItemYGap;
                    }
                }


                path.Reset();
                layer.CoordinateSystem.GetIsoline(path, new Logical3D(xln, ynbase), new Logical3D(xln, ycn));
                layer.CoordinateSystem.GetIsoline(path, new Logical3D(xln, ycn), new Logical3D(xrn, ycn));
                layer.CoordinateSystem.GetIsoline(path, new Logical3D(xrn, ycn), new Logical3D(xrn, ynbase));
                layer.CoordinateSystem.GetIsoline(path, new Logical3D(xrn, ynbase), new Logical3D(xln, ynbase));
                path.CloseFigure();

                _fillBrush.Rectangle = path.GetBounds();
                g.FillPath(_fillBrush, path);

                if (_framePen != null)
                {
                    _framePen.BrushRectangle = path.GetBounds();
                    g.DrawPath(_framePen, path);
                }
            }
        }