//*************************************************************************
        //  Method: SaveToXps()
        //
        /// <summary>
        /// Saves the graph to the specified XPS file.
        /// </summary>
        ///
        /// <param name="imageSize">
        /// Size of the XPS image, in WPS units.
        /// </param>
        ///
        /// <param name="fileName">
        /// File name to save to.
        /// </param>
        ///
        /// <remarks>
        /// This could conceivably be put in the base-class NodeXLControl class,
        /// but that would force all users of the control to add references to the
        /// XPS assemblies.
        /// </remarks>
        //*************************************************************************
        public void SaveToXps(
            Size imageSize,
            String fileName
            )
        {
            Debug.Assert( !String.IsNullOrEmpty(fileName) );
            AssertValid();

            CheckIfLayingOutGraph("SaveToXps");

            // This control will be rehosted by a FixedPage.  It can't be a child
            // of logical trees, so disconnect it from its parent after saving the
            // current vertex locations.

            LayoutSaver oLayoutSaver = new LayoutSaver(this.Graph);

            Debug.Assert(this.Parent is Panel);
            Panel oParentPanel = (Panel)this.Parent;
            UIElementCollection oParentChildren = oParentPanel.Children;
            Int32 iChildIndex = oParentChildren.IndexOf(this);
            oParentChildren.Remove(this);

            GraphImageCenterer oGraphImageCenterer = new GraphImageCenterer(this);

            FixedDocument oFixedDocument = new FixedDocument();
            oFixedDocument.DocumentPaginator.PageSize = imageSize;
            PageContent oPageContent = new PageContent();

            FixedPage oFixedPage = new FixedPage();
            oFixedPage.Width = imageSize.Width;
            oFixedPage.Height = imageSize.Height;

            this.Width = imageSize.Width;
            this.Height = imageSize.Height;

            // Adjust the control's translate transforms so that the image will be
            // centered on the same point on the graph that the control is centered
            // on.

            oGraphImageCenterer.CenterGraphImage(imageSize);

            oFixedPage.Children.Add(this);
            oFixedPage.Measure(imageSize);

            oFixedPage.Arrange(new System.Windows.Rect(
            new System.Windows.Point(), imageSize) );

            oFixedPage.UpdateLayout();

            ( (System.Windows.Markup.IAddChild)oPageContent ).AddChild(
            oFixedPage);

            oFixedDocument.Pages.Add(oPageContent);

            try
            {
            XpsDocument oXpsDocument = new XpsDocument(fileName,
                FileAccess.Write);

            XpsDocumentWriter oXpsDocumentWriter =
                XpsDocument.CreateXpsDocumentWriter(oXpsDocument);

            oXpsDocumentWriter.Write(oFixedDocument);
            oXpsDocument.Close();
            }
            finally
            {
            // Reconnect the NodeXLControl to its original parent.  Reset the
            // size to Auto in the process.

            oFixedPage.Children.Remove(this);
            this.Width = Double.NaN;
            this.Height = Double.NaN;
            oGraphImageCenterer.RestoreCenter();
            oParentChildren.Insert(iChildIndex, this);

            // The graph may have shrunk when it was connected to the
            // FixedPage, and even though it will be expanded to its original
            // dimensions when UpdateLayout() is called below, the layout may
            // have lost "resolution" and the results may be poor.
            //
            // Fix this by restoring the original layout and redrawing the
            // graph.

            this.UpdateLayout();
            oLayoutSaver.RestoreLayout();
            this.DrawGraph(false);
            }
        }
Example #2
0
        //*************************************************************************
        //  Method: CopyGraphToBitmap()
        //
        /// <summary>
        /// Creates a bitmap image of the graph.
        /// </summary>
        ///
        /// <param name="bitmapWidthPx">
        /// Width of the bitmap image, in pixels.  Must be greater than 0.
        /// </param>
        ///
        /// <param name="bitmapHeightPx">
        /// Height of the bitmap image, in pixels.  Must be greater than 0.
        /// </param>
        ///
        /// <returns>
        /// A bitmap image of the graph displayed within the control, with the
        /// specified dimensions.
        /// </returns>
        ///
        /// <remarks>
        /// An exception is thrown if the graph is being laid out when this method
        /// is called.  Check the <see cref="IsLayingOutGraph" /> property before
        /// calling this.
        /// </remarks>
        //*************************************************************************
        public System.Drawing.Bitmap CopyGraphToBitmap(
            Int32 bitmapWidthPx,
            Int32 bitmapHeightPx
            )
        {
            AssertValid();

            const String MethodName = "CopyGraphToBitmap";

            this.ArgumentChecker.CheckArgumentPositive(MethodName, "bitmapWidthPx",
            bitmapWidthPx);

            this.ArgumentChecker.CheckArgumentPositive(MethodName, "bitmapHeightPx",
            bitmapHeightPx);

            CheckIfLayingOutGraph(MethodName);

            // Save the current vertex locations.

            LayoutSaver oLayoutSaver = new LayoutSaver(this.Graph);

            // Adjust the control's transforms so that the image will be centered
            // on the same point on the graph that the control is centered on.

            GraphImageCenterer oGraphImageCenterer = new GraphImageCenterer(this);

            oGraphImageCenterer.CenterGraphImage(
            new Size(bitmapWidthPx, bitmapHeightPx) );

            // Transform the graph's layout to the specified size.

            Double dOriginalActualWidth = this.ActualWidth;
            Double dOriginalActualHeight = this.ActualHeight;

            Rect oBitmapRectangle = new Rect(0, 0,
            (Double)bitmapWidthPx, (Double)bitmapHeightPx);

            TransformLayout(oBitmapRectangle);

            Debug.Assert(m_eLayoutState == LayoutState.Stable);

            DrawGraph(oBitmapRectangle);

            System.Drawing.Bitmap oBitmap = WpfGraphicsUtil.VisualToBitmap(this,
            bitmapWidthPx, bitmapHeightPx);

            // Restore the original layout.
            //
            // NOTE:
            //
            // Don't try calling TransformLayout() again using the original
            // rectangle.  The first call to TransformLayout() lost "resolution" if
            // the layout was transformed to a smaller rectangle, and attempting to
            // reverse the transform will yield poor results.

            oLayoutSaver.RestoreLayout();

            oBitmapRectangle =
            new Rect(0, 0, dOriginalActualWidth, dOriginalActualHeight);

            Debug.Assert(m_eLayoutState == LayoutState.Stable);

            DrawGraph(oBitmapRectangle);

            oGraphImageCenterer.RestoreCenter();

            return (oBitmap);
        }