Exemplo n.º 1
0
        /// <summary>
        /// Get the names of the x and y column of the active plot.
        /// </summary>
        /// <param name="ctrl">The current active graph controller.</param>
        /// <returns>An array of two strings. The first string is the name of the x-column, the second
        /// the name of the y-column.</returns>
        public static string[] GetActivePlotName(Altaxo.Graph.GUI.GraphController ctrl)
        {
            string[] result = new string[2] {
                String.Empty, String.Empty
            };

            IGPlotItem plotItem = ctrl.ActiveLayer.PlotItems.Flattened[ctrl.CurrentPlotNumber];

            XYColumnPlotItem xyPlotItem = plotItem as XYColumnPlotItem;

            if (xyPlotItem == null)
            {
                return(result);
            }

            XYColumnPlotData data = xyPlotItem.XYColumnPlotData;

            if (data == null)
            {
                return(result);
            }

            result[0] = data.XColumn.FullName;
            result[1] = data.YColumn.FullName;

            return(result);
        }
        private IGPlotItem CreatePlotItem(string tablename, string columnname)
        {
            // create a new plotassociation from the column
            // first, get the y column from table and name
            Data.DataTable tab = Current.Project.DataTableCollection[tablename];
            if (null != tab)
            {
                Data.DataColumn ycol = tab[columnname];
                if (null != ycol)
                {
                    Data.DataColumn xcol = tab.DataColumns.FindXColumnOf(ycol);

                    XYColumnPlotItem result;
                    if (null == xcol)
                    {
                        result = new XYColumnPlotItem(new XYColumnPlotData(new Altaxo.Data.IndexerColumn(), ycol), new G2DPlotStyleCollection(LineScatterPlotStyleKind.Scatter));
                    }
                    else
                    {
                        result = new XYColumnPlotItem(new XYColumnPlotData(xcol, ycol), new G2DPlotStyleCollection(LineScatterPlotStyleKind.LineAndScatter));
                    }


                    return(result);
                }
            }
            return(null);
        }
        /// <summary>
        /// Moves the cross to the next plot item. If no plot item is found in this layer, it moves the cross to the next layer.
        /// </summary>
        /// <param name="increment"></param>
        void MoveUpDown(int increment)
        {
            if (!TestMovementPresumtions())
            {
                return;
            }

            int numlayers          = _grac.Layers.Count;
            int nextlayer          = _LayerNumber;
            int nextplotitemnumber = this._PlotItemNumber;

            XYScatterPointInformation scatterPoint = null;
            XYColumnPlotItem          plotitem     = null;

            do
            {
                nextplotitemnumber = this._PlotItemNumber + Math.Sign(increment);
                if (nextplotitemnumber < 0)
                {
                    nextlayer         -= 1;
                    nextplotitemnumber = nextlayer < 0 ? int.MaxValue : _grac.Layers[nextlayer].PlotItems.Flattened.Length - 1;
                }
                else if (nextplotitemnumber >= _grac.Layers[nextlayer].PlotItems.Flattened.Length)
                {
                    nextlayer         += 1;
                    nextplotitemnumber = 0;
                }
                // check if this results in a valid information
                if (nextlayer < 0 || nextlayer >= numlayers)
                {
                    break;
                }

                if (nextplotitemnumber < 0 || nextplotitemnumber >= _grac.Layers[nextlayer].PlotItems.Flattened.Length)
                {
                    continue;
                }

                plotitem = _grac.Layers[nextlayer].PlotItems.Flattened[nextplotitemnumber] as XYColumnPlotItem;
                if (null == plotitem)
                {
                    continue;
                }

                scatterPoint = plotitem.GetNextPlotPoint(_grac.Layers[nextlayer], this._PlotIndex, 0);
            } while(scatterPoint == null);

            if (null != scatterPoint)
            {
                this.m_PlotItem      = plotitem;
                this._LayerNumber    = nextlayer;
                this._PlotItemNumber = nextplotitemnumber;
                this._PlotIndex      = scatterPoint.PlotIndex;
                this._RowIndex       = scatterPoint.RowIndex;

                ShowCross(scatterPoint);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Plots selected data columns of a table.
        /// </summary>
        /// <param name="table">The source table.</param>
        /// <param name="selectedColumns">The data columns of the table that should be plotted.</param>
        /// <param name="graph">The graph document to plot into.</param>
        /// <param name="templatePlotStyle">The plot style which is the template for all plot items.</param>
        /// <param name="groupStyles">The group styles for the newly built plot item collection.</param>
        public static IGraphController Plot(DataTable table,
                                            IAscendingIntegerCollection selectedColumns,
                                            Graph.Gdi.GraphDocument graph,
                                            G2DPlotStyleCollection templatePlotStyle,
                                            PlotGroupStyleCollection groupStyles)
        {
            List <IGPlotItem> pilist = CreatePlotItems(table, selectedColumns, templatePlotStyle);

            // now create a new Graph with this plot associations
            Altaxo.Graph.GUI.IGraphController gc = Current.ProjectService.CreateNewGraph(graph);
            // Set x and y axes according to the first plot item in the list
            if (pilist.Count > 0 && (pilist[0] is XYColumnPlotItem))
            {
                XYColumnPlotItem firstitem = (XYColumnPlotItem)pilist[0];
                if (firstitem.Data.XColumn is TextColumn)
                {
                    gc.Doc.Layers[0].LinkedScales.SetScale(0, new Graph.Scales.TextScale());
                }
                else if (firstitem.Data.XColumn is DateTimeColumn)
                {
                    gc.Doc.Layers[0].LinkedScales.SetScale(0, new Graph.Scales.DateTimeScale());
                }

                if (firstitem.Data.YColumn is TextColumn)
                {
                    gc.Doc.Layers[0].LinkedScales.SetScale(1, new Graph.Scales.TextScale());
                }
                else if (firstitem.Data.YColumn is DateTimeColumn)
                {
                    gc.Doc.Layers[0].LinkedScales.SetScale(1, new Graph.Scales.DateTimeScale());
                }
            }


            PlotItemCollection newPlotGroup = new PlotItemCollection(gc.Doc.Layers[0].PlotItems);

            foreach (IGPlotItem pi in pilist)
            {
                newPlotGroup.Add(pi);
            }
            if (groupStyles != null)
            {
                newPlotGroup.GroupStyles = groupStyles;
            }
            else
            {
                newPlotGroup.CollectStyles(newPlotGroup.GroupStyles);
            }

            gc.Doc.Layers[0].PlotItems.Add(newPlotGroup);

            return(gc);
        }
        /// <summary>
        /// Handles the MouseDown event when the plot point tool is selected
        /// </summary>
        /// <param name="e">The mouse event args</param>

        public override void OnMouseDown(System.Windows.Forms.MouseEventArgs e)
        {
            base.OnMouseDown(e);

            PointF mouseXY = new PointF(e.X, e.Y);
            PointF graphXY = _grac.PixelToPrintableAreaCoordinates(mouseXY);

            // search for a object first
            IHitTestObject clickedObject;
            int            clickedLayerNumber = 0;

            _grac.FindGraphObjectAtPixelPosition(mouseXY, true, out clickedObject, out clickedLayerNumber);
            if (null != clickedObject && clickedObject.HittedObject is XYColumnPlotItem)
            {
                m_PlotItem = (XYColumnPlotItem)clickedObject.HittedObject;
                PointF[] transXY = new PointF[] { graphXY };
                Matrix   inv     = clickedObject.Transformation.Clone();
                inv.Invert();
                inv.TransformPoints(transXY);
                XYScatterPointInformation scatterPoint = m_PlotItem.GetNearestPlotPoint(clickedObject.ParentLayer, transXY[0]);

                this._PlotItemNumber = GetPlotItemNumber(clickedLayerNumber, m_PlotItem);
                this._LayerNumber    = clickedLayerNumber;


                if (null != scatterPoint)
                {
                    this._PlotIndex = scatterPoint.PlotIndex;
                    this._RowIndex  = scatterPoint.RowIndex;
                    // convert this layer coordinates first to PrintableAreaCoordinates
                    PointF printableCoord = clickedObject.ParentLayer.LayerToGraphCoordinates(scatterPoint.LayerCoordinates);
                    m_Cross    = printableCoord;
                    m_Cross.X += _grac.Doc.PrintableBounds.X;
                    m_Cross.Y += _grac.Doc.PrintableBounds.Y;

                    PointF newPixelCoord = _grac.PrintableAreaToPixelCoordinates(printableCoord);
                    Cursor.Position = new Point((int)(Cursor.Position.X + newPixelCoord.X - mouseXY.X), (int)(Cursor.Position.Y + newPixelCoord.Y - mouseXY.Y));


                    this.DisplayData(m_PlotItem, scatterPoint.RowIndex,
                                     m_PlotItem.XYColumnPlotData.XColumn[scatterPoint.RowIndex],
                                     m_PlotItem.XYColumnPlotData.YColumn[scatterPoint.RowIndex]);



                    // here we shoud switch the bitmap cache mode on and link us with the AfterPaint event
                    // of the grac
                    _grac.RepaintGraphArea(); // no refresh necessary, only invalidate to show the cross
                }
            }
        } // end of function
 /// <summary>
 /// Find the plot item number of a given plot item.
 /// </summary>
 /// <param name="layernumber"></param>
 /// <param name="plotitem"></param>
 /// <returns></returns>
 int GetPlotItemNumber(int layernumber, XYColumnPlotItem plotitem)
 {
     if (layernumber < _grac.Doc.Layers.Count)
     {
         for (int i = 0; i < _grac.Doc.Layers[layernumber].PlotItems.Flattened.Length; i++)
         {
             if (object.ReferenceEquals(_grac.Doc.Layers[layernumber].PlotItems.Flattened[i], plotitem))
             {
                 return(i);
             }
         }
     }
     return(-1);
 }
Exemplo n.º 7
0
 /// <summary>
 /// Find the plot item number of a given plot item.
 /// </summary>
 /// <param name="layer">The layer in which this plot item resides.</param>
 /// <param name="plotitem">The plot item for which the number should be retrieved.</param>
 /// <returns></returns>
 private int GetPlotItemNumber(XYPlotLayer layer, XYColumnPlotItem plotitem)
 {
     if (null != layer)
     {
         for (int i = 0; i < layer.PlotItems.Flattened.Length; i++)
         {
             if (object.ReferenceEquals(layer.PlotItems.Flattened[i], plotitem))
             {
                 return(i);
             }
         }
     }
     return(-1);
 }
Exemplo n.º 8
0
        /// <summary>
        /// Handles the MouseDown event when the plot point tool is selected
        /// </summary>
        /// <param name="position">Mouse position.</param>
        /// <param name="e">The mouse event args</param>
        public override void OnMouseDown(PointD2D position, MouseButtonEventArgs e)
        {
            base.OnMouseDown(position, e);

            var graphXY = _grac.ConvertMouseToRootLayerCoordinates(position);

            _grac.FindGraphObjectAtPixelPosition(position, true, out var clickedObject, out var clickedLayerNumber);
            if (null != clickedObject && clickedObject.HittedObject is XYColumnPlotItem)
            {
                _PlotItem = (XYColumnPlotItem)clickedObject.HittedObject;
                var transXY = clickedObject.Transformation.InverseTransformPoint(graphXY);

                _layer = (XYPlotLayer)(clickedObject.ParentLayer);
                XYScatterPointInformation scatterPoint = _PlotItem.GetNearestPlotPoint(_layer, transXY);
                _PlotItemNumber = GetPlotItemNumber(_layer, _PlotItem);

                if (null != scatterPoint)
                {
                    _PlotIndex = scatterPoint.PlotIndex;
                    _RowIndex  = scatterPoint.RowIndex;
                    // convert this layer coordinates first to PrintableAreaCoordinates
                    var rootLayerCoord = clickedObject.ParentLayer.TransformCoordinatesFromHereToRoot(scatterPoint.LayerCoordinates);
                    _positionOfCrossInRootLayerCoordinates = rootLayerCoord;
                    // m_Cross.X -= _grac.GraphViewOffset.X;
                    // m_Cross.Y -= _grac.GraphViewOffset.Y;

                    var newPixelCoord = _grac.ConvertGraphToMouseCoordinates(rootLayerCoord);

                    // TODO (Wpf)
                    //var newCursorPosition = new Point((int)(Cursor.Position.X + newPixelCoord.X - mouseXY.X),(int)(Cursor.Position.Y + newPixelCoord.Y - mouseXY.Y));
                    //SetCursorPos(newCursorPosition.X, newCursorPosition.Y);

                    DisplayData(_PlotItem, scatterPoint.RowIndex,
                                _PlotItem.XYColumnPlotData.XColumn[scatterPoint.RowIndex],
                                _PlotItem.XYColumnPlotData.YColumn[scatterPoint.RowIndex]);

                    // here we shoud switch the bitmap cache mode on and link us with the AfterPaint event
                    // of the grac
                    _grac.RenderOverlay(); // no refresh necessary, only invalidate to show the cross
                }
            }
        } // end of function
Exemplo n.º 9
0
        /// <summary>
        /// Retrieves the data points of the current active plot.
        /// </summary>
        /// <param name="ctrl">The graph controller which controls the graph from which the points are to retrieve.</param>
        /// <param name="xarr">The array of the data point's x values.</param>
        /// <param name="yarr">The array of the data point's y values.</param>
        /// <param name="nPlotPoints">The number of plot points (may be smaller than the length of x and y arrays.</param>
        /// <returns>Null if all is ok, or error message if not.</returns>
        public static string GetActivePlotPoints(Altaxo.Graph.GUI.GraphController ctrl, ref double[] xarr, ref double[] yarr, out int nPlotPoints)
        {
            nPlotPoints = 0;

            ctrl.EnsureValidityOfCurrentLayerNumber();
            ctrl.EnsureValidityOfCurrentPlotNumber();

            IGPlotItem plotItem = ctrl.ActiveLayer.PlotItems.Flattened[ctrl.CurrentPlotNumber];

            XYColumnPlotItem xyPlotItem = plotItem as XYColumnPlotItem;

            if (xyPlotItem == null)
            {
                return("No active plot!");
            }

            XYColumnPlotData data = xyPlotItem.XYColumnPlotData;

            if (data == null)
            {
                return("Active plot item has no data");
            }

            if (!(data.XColumn is Altaxo.Data.INumericColumn) || !(data.YColumn is Altaxo.Data.INumericColumn))
            {
                return("X-Y values of plot data are not both numeric");
            }

            Altaxo.Data.INumericColumn xcol = (Altaxo.Data.INumericColumn)data.XColumn;
            Altaxo.Data.INumericColumn ycol = (Altaxo.Data.INumericColumn)data.YColumn;

            int n = data.PlottablePoints;

            if (null == xarr || xarr.Length < n)
            {
                xarr = new double[n];
            }
            if (null == yarr || yarr.Length < n)
            {
                yarr = new double[n];
            }

            int end = data.PlotRangeEnd;

            int j = 0;

            for (int i = data.PlotRangeStart; i < end && j < n; i++)
            {
                double x = xcol[i];
                double y = ycol[i];

                if (double.IsNaN(x) || double.IsNaN(y))
                {
                    continue;
                }

                xarr[j] = x;
                yarr[j] = y;
                ++j;
            }
            nPlotPoints = j;
            return(null);
        }
Exemplo n.º 10
0
        public static string Fit(Altaxo.Graph.GUI.GraphController ctrl)
        {
            if (ctrl.CurrentPlotNumber < 0)
            {
                return("No active plot!");
            }

            IGPlotItem plotItem = ctrl.ActiveLayer.PlotItems.Flattened[ctrl.CurrentPlotNumber];

            XYColumnPlotItem xyPlotItem = plotItem as XYColumnPlotItem;

            if (xyPlotItem == null)
            {
                return("Active plot is not a X-Y Plot!");
            }

            INumericColumn xColumn = xyPlotItem.XYColumnPlotData.XColumn as INumericColumn;
            INumericColumn yColumn = xyPlotItem.XYColumnPlotData.YColumn as INumericColumn;

            if (xColumn == null)
            {
                return("The x-column is not numeric");
            }

            if (yColumn == null)
            {
                return("The y-column is not numeric");
            }


            Calc.Regression.Nonlinear.NonlinearFitDocument localdoc = ctrl.Doc.GetGraphProperty(FitDocumentPropertyName) as Calc.Regression.Nonlinear.NonlinearFitDocument;


            if (localdoc == null)
            {
                if (_lastFitDocument == null)
                {
                    localdoc = new Altaxo.Calc.Regression.Nonlinear.NonlinearFitDocument();
                }
                else
                {
                    localdoc = (Altaxo.Calc.Regression.Nonlinear.NonlinearFitDocument)_lastFitDocument.Clone();
                }
            }


            if (localdoc.FitEnsemble.Count == 0)
            {
                Calc.Regression.Nonlinear.FitElement fitele = new Altaxo.Calc.Regression.Nonlinear.FitElement(
                    xColumn,
                    yColumn,
                    xyPlotItem.XYColumnPlotData.PlotRangeStart,
                    xyPlotItem.XYColumnPlotData.PlotRangeLength);

                localdoc.FitEnsemble.Add(fitele);
            }
            else // localdoc.FitEnsemble.Count>0
            {
                localdoc.FitEnsemble[0].SetIndependentVariable(0, xColumn);
                localdoc.FitEnsemble[0].SetDependentVariable(0, yColumn);
                localdoc.FitEnsemble[0].SetRowRange(xyPlotItem.XYColumnPlotData.PlotRangeStart, xyPlotItem.XYColumnPlotData.PlotRangeLength);
            }

            localdoc.FitContext = ctrl;


            object fitdocasobject = localdoc;

            if (true == Current.Gui.ShowDialog(ref fitdocasobject, "Non-linear fitting"))
            {
                // store the fit document in the graphs property
                ctrl.Doc.SetGraphProperty(FitDocumentPropertyName, localdoc);

                _lastFitDocument = (Altaxo.Calc.Regression.Nonlinear.NonlinearFitDocument)localdoc.Clone();
            }


            return(null);
        }
Exemplo n.º 11
0
        /// <summary>
        /// Gets a new or recycled fit document for a given plot item <see cref="XYColumnPlotItem"/>.
        /// </summary>
        /// <param name="xyPlotItem">The xy plot item.</param>
        /// <param name="ctrl">The control.</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException">xyPlotItem</exception>
        private static Tuple <string, NonlinearFitDocument, string, XYPlotLayer> GetNewFitDocumentFor(XYColumnPlotItem xyPlotItem, Altaxo.Gui.Graph.Gdi.Viewing.IGraphController ctrl)
        {
            if (null == xyPlotItem)
            {
                throw new ArgumentNullException(nameof(xyPlotItem));
            }

            var activeLayer = Altaxo.Main.AbsoluteDocumentPath.GetRootNodeImplementing <XYPlotLayer>(xyPlotItem);
            var xColumn     = xyPlotItem.XYColumnPlotData.XColumn;
            var yColumn     = xyPlotItem.XYColumnPlotData.YColumn;

            if (xColumn == null || xColumn.ItemType != typeof(double))
            {
                return(new Tuple <string, NonlinearFitDocument, string, XYPlotLayer>("The x-column is not numeric", null, null, activeLayer));
            }

            if (yColumn == null || yColumn.ItemType != typeof(double))
            {
                return(new Tuple <string, NonlinearFitDocument, string, XYPlotLayer>("The y-column is not numeric", null, null, activeLayer));
            }

            var localdoc = (ctrl.Doc.GetGraphProperty(FitDocumentPropertyName) as Calc.Regression.Nonlinear.NonlinearFitDocument) ??
                           (Altaxo.Calc.Regression.Nonlinear.NonlinearFitDocument)_lastFitDocument?.Clone() ??
                           new Altaxo.Calc.Regression.Nonlinear.NonlinearFitDocument();

            if (localdoc.FitEnsemble.Count == 0) // if there was no fit before
            {
                var fitele = new Altaxo.Calc.Regression.Nonlinear.FitElement(
                    xyPlotItem.Data.DataTable,
                    xyPlotItem.Data.GroupNumber,
                    xyPlotItem.Data.DataRowSelection,
                    xColumn,
                    yColumn);

                localdoc.FitEnsemble.Add(fitele);
            }
            else // there was a fit before, thus localdoc.FitEnsemble.Count>0
            {
                bool hasColumnsChanged = false;

                hasColumnsChanged |= !(object.ReferenceEquals(localdoc.FitEnsemble[0].DataTable, xyPlotItem.Data.DataTable));
                hasColumnsChanged |= !(object.ReferenceEquals(localdoc.FitEnsemble[0].GroupNumber, xyPlotItem.Data.GroupNumber));
                hasColumnsChanged |= !(object.ReferenceEquals(localdoc.FitEnsemble[0].IndependentVariables(0), xColumn));
                hasColumnsChanged |= !(object.ReferenceEquals(localdoc.FitEnsemble[0].DependentVariables(0), yColumn));

                localdoc.FitEnsemble[0].SetIndependentVariable(0, xColumn);
                localdoc.FitEnsemble[0].SetDependentVariable(0, yColumn);

                if (hasColumnsChanged) // if some of the columns has changed, take the data row selection of the plot item
                {
                    localdoc.FitEnsemble[0].DataRowSelection = xyPlotItem.Data.DataRowSelection;
                }
            }

            return(new Tuple <string, NonlinearFitDocument, string, XYPlotLayer>(string.Empty, localdoc, null, activeLayer));
        }
Exemplo n.º 12
0
        private static Tuple <string, NonlinearFitDocument, string, XYPlotLayer> SelectFitDocument(Gui.Graph.Gdi.Viewing.IGraphController ctrl, XYColumnPlotItem columnPlotItem)
        {
            if (null == columnPlotItem)
            {
                throw new ArgumentNullException(nameof(columnPlotItem));
            }

            var        activeLayer             = Altaxo.Main.AbsoluteDocumentPath.GetRootNodeImplementing <XYPlotLayer>(columnPlotItem);
            DataColumn columPlotItemDataColumn = columnPlotItem.Data.YColumn.GetUnderlyingDataColumnOrDefault();

            if (null != columPlotItemDataColumn)
            {
                // try to find a nonlinear function plot item whose dependent variable equals to the y of the column plot item
                foreach (var funcItem in TreeNodeExtensions.TakeFromHereToFirstLeaves((IGPlotItem)activeLayer.PlotItems).OfType <XYNonlinearFitFunctionPlotItem>())
                {
                    if (object.ReferenceEquals(columPlotItemDataColumn, funcItem.DependentVariableColumn.GetUnderlyingDataColumnOrDefault()))
                    {
                        return(new Tuple <string, NonlinearFitDocument, string, XYPlotLayer>(string.Empty, funcItem.FitDocumentCopy, funcItem.FitDocumentIdentifier, activeLayer));
                    }
                }
            }
            // Get a new fit document from the selected xy plot item
            return(GetNewFitDocumentFor(columnPlotItem, ctrl));
        }
Exemplo n.º 13
0
        /// <summary>
        /// Moves the cross to the next plot item. If no plot item is found in this layer, it moves the cross to the next layer.
        /// </summary>
        /// <param name="increment"></param>
        private void MoveUpDown(int increment)
        {
            if (!TestMovementPresumtions())
            {
                return;
            }

            var layerList          = _layer.SiblingLayers;
            int numlayers          = layerList.Count;
            var nextlayer          = _layer as XYPlotLayer;
            int indexOfNextLayer   = layerList.IndexOf(_layer);
            int nextplotitemnumber = _PlotItemNumber;

            XYScatterPointInformation scatterPoint = null;
            XYColumnPlotItem          plotitem     = null;

            do
            {
                nextplotitemnumber = nextplotitemnumber + Math.Sign(increment);
                if (nextplotitemnumber < 0) // then try to use the previous layer
                {
                    --indexOfNextLayer;
                    nextlayer          = indexOfNextLayer >= 0 ? layerList[indexOfNextLayer] as XYPlotLayer : null;
                    nextplotitemnumber = nextlayer == null ? int.MaxValue : nextlayer.PlotItems.Flattened.Length - 1;
                }
                else if (nextplotitemnumber >= nextlayer.PlotItems.Flattened.Length)
                {
                    ++indexOfNextLayer;
                    nextlayer          = indexOfNextLayer < layerList.Count ? layerList[indexOfNextLayer] as XYPlotLayer : null;
                    nextplotitemnumber = 0;
                }
                // check if this results in a valid information
                if (indexOfNextLayer < 0 || indexOfNextLayer >= numlayers)
                {
                    break; // no more layers available
                }
                if (nextlayer == null)
                {
                    continue; // this is not an XYPlotLayer
                }
                if (nextplotitemnumber < 0 || nextplotitemnumber >= nextlayer.PlotItems.Flattened.Length)
                {
                    continue;
                }

                plotitem = nextlayer.PlotItems.Flattened[nextplotitemnumber] as XYColumnPlotItem;
                if (null == plotitem)
                {
                    continue;
                }

                scatterPoint = plotitem.GetNextPlotPoint(nextlayer, _PlotIndex, 0);
            } while (scatterPoint == null);

            if (null != scatterPoint)
            {
                _PlotItem       = plotitem;
                _layer          = nextlayer;
                _PlotItemNumber = nextplotitemnumber;
                _PlotIndex      = scatterPoint.PlotIndex;
                _RowIndex       = scatterPoint.RowIndex;

                ShowCross(scatterPoint);
            }
        }