/// <summary>
        /// Перенести область графиков
        /// </summary>
        /// <param name="chartPart">Область графиков для перемещения</param>
        /// <param name="cellAddress">Позиция области графиков (ячейка, левый верхний край области)</param>
        /// <param name="columnOffset">Отклонение от левого края ячейки</param>
        /// <param name="rowOffset">Отклонение от верхнего края ячейки</param>
        /// <returns>true - если операция выполнилась успешно, false - в обратном случае.</returns>
        public static bool RelocateTo(this ChartPart chartPart, string cellAddress, long columnOffset = 0, long rowOffset = 0)
        {
            var columnNum = Utils.ToColumNum(cellAddress);
            var rowNum    = Utils.ToRowNum(cellAddress);

            return(chartPart.RelocateTo((int)columnNum, (int)rowNum, columnOffset, rowOffset));
        }
        /// <summary>
        /// Переместить область графиков
        /// </summary>
        /// <param name="chartPart">Часть документа с графиками</param>
        /// <param name="topLeft">Верхняя левая позиция области</param>
        /// <returns>true - если операция выполнилась успешно, false - в обратном случае.</returns>
        public static bool RelocateTo(this ChartPart chartPart, Drawing.Spreadsheet.FromMarker topLeft)
        {
            int  newTop;
            long newTopOffset;
            int  newLeft;
            long newLeftOffset;

            try
            {
                newTop        = int.Parse(topLeft.RowId.InnerText);
                newTopOffset  = long.Parse(topLeft.RowOffset.InnerText);
                newLeft       = int.Parse(topLeft.ColumnId.InnerText);
                newLeftOffset = long.Parse(topLeft.ColumnOffset.InnerText);
            }
            catch
            {
                return(false);
            }

            int columnNum = newLeft + 1;
            int rowNum    = newTop + 1;

            return(chartPart.RelocateTo(columnNum, rowNum, newLeftOffset, newTopOffset));
        }
        /// <summary>
        /// Перенести область графиков
        /// </summary>
        /// <param name="chartPart">Область графиков для перемещения</param>
        /// <param name="columnNum">Номер колонки (соответствует левому краю области)</param>
        /// <param name="rowNum">Номер строки (соответствует верхнему краю области)</param>
        /// <param name="columnOffset">Отклонение от левого края ячейки</param>
        /// <param name="rowOffset">Отклонение от верхнего края ячейки</param>
        /// <returns>true - если операция выполнилась успешно, false - в обратном случае.</returns>
        public static bool RelocateTo(this ChartPart chartPart, int columnNum, int rowNum, long columnOffset = 0, long rowOffset = 0)
        {
            var theAnchor = chartPart.Anchor();

            if (theAnchor == null)
            {
                return(false);
            }
            if (theAnchor.FromMarker == null || theAnchor.ToMarker == null)
            {
                return(false);
            }

            int  top, bottom;
            long topOffset, bottomOffset;
            int  left, right;
            long leftOffset, rightOffset;

            try
            {
                top        = int.Parse(theAnchor.FromMarker.RowId.InnerText);
                topOffset  = long.Parse(theAnchor.FromMarker.RowOffset.InnerText);
                left       = int.Parse(theAnchor.FromMarker.ColumnId.InnerText);
                leftOffset = long.Parse(theAnchor.FromMarker.ColumnOffset.InnerText);

                bottom       = int.Parse(theAnchor.ToMarker.RowId.InnerText);
                bottomOffset = long.Parse(theAnchor.ToMarker.RowOffset.InnerText);
                right        = int.Parse(theAnchor.ToMarker.ColumnId.InnerText);
                rightOffset  = long.Parse(theAnchor.ToMarker.ColumnOffset.InnerText);
            }
            catch
            {
                return(false);
            }

            var distanceX       = right - left;
            var distanceXOffset = rightOffset - leftOffset;
            var distanceY       = bottom - top;
            var distanceYOffset = bottomOffset - topOffset;

            int  newTop        = rowNum - 1;
            long newTopOffset  = rowOffset;
            int  newLeft       = columnNum - 1;
            long newLeftOffset = columnOffset;

            int  newBottom       = newTop + distanceY;
            long newBottomOffset = newTopOffset + distanceYOffset;
            int  newRight        = newLeft + distanceX;
            long newRightOffset  = newLeftOffset + distanceXOffset;

            var topLeft = new Drawing.Spreadsheet.FromMarker()
            {
                ColumnId     = new ColumnId(newLeft.ToString()),
                ColumnOffset = new ColumnOffset(newLeftOffset.ToString()),
                RowId        = new RowId(newTop.ToString()),
                RowOffset    = new RowOffset(newTopOffset.ToString())
            };

            var bottomRight = new Drawing.Spreadsheet.ToMarker()
            {
                ColumnId     = new ColumnId(newRight.ToString()),
                ColumnOffset = new ColumnOffset(newRightOffset.ToString()),
                RowId        = new RowId(newBottom.ToString()),
                RowOffset    = new RowOffset(newBottomOffset.ToString())
            };

            chartPart.RelocateTo(topLeft, bottomRight);
            return(true);
        }