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