} // end of function

        void ShowCross(XYScatterPointInformation scatterPoint)
        {
            this._PlotIndex = scatterPoint.PlotIndex;
            this._RowIndex  = scatterPoint.RowIndex;
            // convert this layer coordinates first to PrintableAreaCoordinates
            PointF printableCoord = _grac.Layers[this._LayerNumber].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));
            //Cursor.Position = ((Control)_grac.View).PointToScreen(newPixelCoord);



            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
        }
        /// <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);
            }
        }
        /// <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>
        /// Moves the cross along the plot.
        /// </summary>
        /// <param name="increment"></param>
        void MoveLeftRight(int increment)
        {
            if (!TestMovementPresumtions())
            {
                return;
            }

            XYScatterPointInformation scatterPoint = m_PlotItem.GetNextPlotPoint(_grac.Doc.Layers[this._LayerNumber], this._PlotIndex, increment);

            if (null != scatterPoint)
            {
                ShowCross(scatterPoint);
            }
        }
        /// <summary>
        /// Moves the cross along the plot.
        /// </summary>
        /// <param name="increment"></param>
        private void MoveLeftRight(int increment)
        {
            if (!TestMovementPresumtions())
            {
                return;
            }

            XYScatterPointInformation scatterPoint = _PlotItem.GetNextPlotPoint(_layer, _PlotIndex, increment);

            if (null != scatterPoint)
            {
                ShowCross(scatterPoint);
            }
        }
        /// <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
        } // end of function

        private void ShowCross(XYScatterPointInformation scatterPoint)
        {
            _PlotIndex = scatterPoint.PlotIndex;
            _RowIndex  = scatterPoint.RowIndex;
            // convert this layer coordinates first to PrintableAreaCoordinates
            var rootLayerCoord = _layer.TransformCoordinatesFromHereToRoot(scatterPoint.LayerCoordinates);

            _positionOfCrossInRootLayerCoordinates = rootLayerCoord;
            // m_Cross.X -= _grac.GraphViewOffset.X;
            // m_Cross.Y -= _grac.GraphViewOffset.Y;

            var newPixelCoord = _grac.ConvertGraphToMouseCoordinates(rootLayerCoord);

            //Cursor.Position = new Point((int)(Cursor.Position.X + newPixelCoord.X - mouseXY.X),(int)(Cursor.Position.Y + newPixelCoord.Y - mouseXY.Y));
            //Cursor.Position = ((Control)_grac.View).PointToScreen(newPixelCoord);

            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
        }
        /// <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);
            }
        }