Example #1
0
        CreateAndSaveSubgraphImages
        (
            IGraph oSubgraph,
            String sVertexName,
            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs,
            TemporaryImages oThumbnailImages
        )
        {
            Debug.Assert(oSubgraph != null);
            Debug.Assert(!String.IsNullOrEmpty(sVertexName));
            Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
            Debug.Assert(oThumbnailImages != null);
            AssertValid();

            if (oCreateSubgraphImagesAsyncArgs.SaveToFolder)
            {
                CreateAndSaveSubgraphImageInFolder(oSubgraph, sVertexName,
                                                   oCreateSubgraphImagesAsyncArgs);
            }

            if (oCreateSubgraphImagesAsyncArgs.CreateThumbnails)
            {
                CreateAndSaveThumbnailImage(oSubgraph, sVertexName,
                                            oCreateSubgraphImagesAsyncArgs, oThumbnailImages);
            }
        }
Example #2
0
        CreateAndSaveSubgraphImageInFolder
        (
            IGraph oSubgraph,
            String sVertexName,
            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs
        )
        {
            Debug.Assert(oSubgraph != null);
            Debug.Assert(!String.IsNullOrEmpty(sVertexName));
            Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
            Debug.Assert(oCreateSubgraphImagesAsyncArgs.SaveToFolder);
            AssertValid();

            // Save the graph to a bitmap.

            Bitmap oBitmap = CreateSubgraphImage(oSubgraph,
                                                 oCreateSubgraphImagesAsyncArgs,
                                                 oCreateSubgraphImagesAsyncArgs.ImageSizePx);

            try
            {
                // Save the bitmap in the specified folder.

                SaveSubgraphImage(oBitmap,
                                  oCreateSubgraphImagesAsyncArgs.Folder,
                                  sVertexName, oCreateSubgraphImagesAsyncArgs
                                  );
            }
            finally
            {
                GraphicsUtil.DisposeBitmap(ref oBitmap);
            }
        }
Example #3
0
        BackgroundWorker_DoWork
        (
            object sender,
            DoWorkEventArgs e
        )
        {
            Debug.Assert(sender is BackgroundWorker);
            AssertValid();

            BackgroundWorker oBackgroundWorker = (BackgroundWorker)sender;

            Debug.Assert(e.Argument is CreateSubgraphImagesAsyncArgs);

            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs =
                (CreateSubgraphImagesAsyncArgs)e.Argument;

            // The NodeXLVisual object couldn't be created by
            // CreateSubgraphImagesAsync(), because the object must be created by
            // the thread that uses it.  Create it now.

            oCreateSubgraphImagesAsyncArgs.NodeXLVisual = CreateNodeXLVisual(
                oCreateSubgraphImagesAsyncArgs.GeneralUserSettings);

            CreateSubgraphImagesInternal(oCreateSubgraphImagesAsyncArgs,
                                         m_oBackgroundWorker, e);
        }
Example #4
0
        SaveSubgraphImage
        (
            Bitmap oBitmap,
            String sFolder,
            String sFileNameNoExtension,
            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs
        )
        {
            Debug.Assert(oBitmap != null);
            Debug.Assert(!String.IsNullOrEmpty(sFolder));
            Debug.Assert(!String.IsNullOrEmpty(sFileNameNoExtension));
            Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
            AssertValid();

            ImageFormat eImageFormat = oCreateSubgraphImagesAsyncArgs.ImageFormat;

            String sFileNameWithoutPath =
                FileUtil.EncodeIllegalFileNameChars(sFileNameNoExtension)
                + "." + SaveableImageFormats.GetFileExtension(eImageFormat);

            String sFileNameWithPath = Path.Combine(sFolder, sFileNameWithoutPath);

            SaveBitmap(oBitmap, sFileNameWithPath, eImageFormat);

            return(sFileNameWithoutPath);
        }
Example #5
0
        CreateAndSaveThumbnailImage
        (
            IGraph oSubgraph,
            String sVertexName,
            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs,
            TemporaryImages oThumbnailImages
        )
        {
            Debug.Assert(oSubgraph != null);
            Debug.Assert(!String.IsNullOrEmpty(sVertexName));
            Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
            Debug.Assert(oCreateSubgraphImagesAsyncArgs.CreateThumbnails);
            Debug.Assert(oThumbnailImages != null);
            AssertValid();

            if (oThumbnailImages.Folder == null)
            {
                // Create a temporary folder where the thumbnail images will be
                // stored.

                String sTemporaryFolder = Path.Combine(
                    Path.GetTempPath(),
                    Path.GetRandomFileName()
                    );

                Directory.CreateDirectory(sTemporaryFolder);

                oThumbnailImages.Folder = sTemporaryFolder;
            }

            // Save the graph to a bitmap.

            Bitmap oBitmap = CreateSubgraphImage(oSubgraph,
                                                 oCreateSubgraphImagesAsyncArgs,
                                                 oCreateSubgraphImagesAsyncArgs.ThumbnailSizePx);

            try
            {
                // Save the bitmap in the temporary folder.

                String sTemporaryFileName = SaveSubgraphImage(oBitmap,
                                                              oThumbnailImages.Folder, sVertexName,
                                                              oCreateSubgraphImagesAsyncArgs
                                                              );

                // Add the file name to the dictionary.  They key is the vertex
                // name and the value is the file name, without a path.

                oThumbnailImages.FileNames[sVertexName] = sTemporaryFileName;
            }
            finally
            {
                GraphicsUtil.DisposeBitmap(ref oBitmap);
            }
        }
Example #6
0
        CreateSubgraph
        (
            IVertex oOriginalVertex,
            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs
        )
        {
            Debug.Assert(oOriginalVertex != null);
            Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
            AssertValid();

            // Create a new empty graph that will contain the vertex's subgraph.

            IGraph oSubgraph = new Graph();

            // Clone the original vertex, its adjacent vertices, and the connecting
            // edges into the subgraph.

            Decimal decLevels = oCreateSubgraphImagesAsyncArgs.Levels;

            IVertex oSubgraphVertex = CloneVertexIntoSubgraph(oOriginalVertex,
                                                              oSubgraph, decLevels);

            if (oCreateSubgraphImagesAsyncArgs.SelectVertex)
            {
                // Select the vertex.

                oSubgraphVertex.SetValue(ReservedMetadataKeys.IsSelected, true);
            }

            if (oCreateSubgraphImagesAsyncArgs.SelectIncidentEdges)
            {
                // Select the vertex's incident edges.

                foreach (IEdge oIncidentEdge in oSubgraphVertex.IncidentEdges)
                {
                    oIncidentEdge.SetValue(ReservedMetadataKeys.IsSelected, true);
                }
            }

            return(oSubgraph);
        }
        SaveSubgraphImage
        (
            Bitmap oBitmap,
            String sFolder,
            String sVertexName,
            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs
        )
        {
            Debug.Assert(oBitmap != null);
            Debug.Assert(!String.IsNullOrEmpty(sFolder));
            Debug.Assert(!String.IsNullOrEmpty(sVertexName));
            Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
            AssertValid();

            ImageFormat eImageFormat = oCreateSubgraphImagesAsyncArgs.ImageFormat;

            // The "Img-" prefix is to prevent a vertex name like "con" or "lpt"
            // from causing the following exception when
            // System.Drawing.Image.Save() is called:
            //
            //   [ExternalException]: A generic error occurred in GDI+.
            //
            // The exception occurs because "con" (console), "lpt" (line printer)
            // and some other names are reserved file names in Windows.

            String sFileNameNoPath = String.Format(

                "Img-{0}.{1}"
                ,
                FileUtil.EncodeIllegalFileNameChars(sVertexName),
                SaveableImageFormats.GetFileExtension(eImageFormat)
                );

            String sFileNameWithPath = Path.Combine(sFolder, sFileNameNoPath);

            SaveBitmap(oBitmap, sFileNameWithPath, eImageFormat);

            return(sFileNameNoPath);
        }
Example #8
0
        CreateSubgraphImage
        (
            IGraph oSubgraph,
            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs,
            Size oImageSizePx
        )
        {
            Debug.Assert(oSubgraph != null);
            Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
            AssertValid();

            Rectangle oSubgraphRectangle = new Rectangle(new Point(0, 0),
                                                         oImageSizePx);

            // Lay out the graph, then draw it using the NodeXLVisual object.

            IAsyncLayout oLayout = oCreateSubgraphImagesAsyncArgs.Layout;

            oLayout.LayOutGraph(oSubgraph,
                                new LayoutContext(oSubgraphRectangle));

            NodeXLVisual oNodeXLVisual =
                oCreateSubgraphImagesAsyncArgs.NodeXLVisual;

            GraphDrawingContext oGraphDrawingContext =
                CreateGraphDrawingContext(oSubgraphRectangle,
                                          oLayout.Margin,
                                          oCreateSubgraphImagesAsyncArgs.GeneralUserSettings);

            oNodeXLVisual.GraphDrawer.DrawGraph(oSubgraph, oGraphDrawingContext);

            // Save the graph to a bitmap.

            Bitmap oBitmap = WpfGraphicsUtil.VisualToBitmap(oNodeXLVisual,
                                                            oSubgraphRectangle.Width, oSubgraphRectangle.Height);

            return(oBitmap);
        }
    SaveSubgraphImage
    (
        Bitmap oBitmap,
        String sFolder,
        String sVertexName,
        CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs
    )
    {
        Debug.Assert(oBitmap != null);
        Debug.Assert( !String.IsNullOrEmpty(sFolder) );
        Debug.Assert( !String.IsNullOrEmpty(sVertexName) );
        Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
        AssertValid();

        ImageFormat eImageFormat = oCreateSubgraphImagesAsyncArgs.ImageFormat;

        // The "Img-" prefix is to prevent a vertex name like "con" or "lpt"
        // from causing the following exception when
        // System.Drawing.Image.Save() is called:
        //
        //   [ExternalException]: A generic error occurred in GDI+.
        //
        // The exception occurs because "con" (console), "lpt" (line printer)
        // and some other names are reserved file names in Windows.

        String sFileNameNoPath = String.Format(

            "Img-{0}.{1}"
            ,
            FileUtil.EncodeIllegalFileNameChars(sVertexName),
            SaveableImageFormats.GetFileExtension(eImageFormat)
            );

        String sFileNameWithPath = Path.Combine(sFolder, sFileNameNoPath);

        SaveBitmap(oBitmap, sFileNameWithPath, eImageFormat);

        return (sFileNameNoPath);
    }
        //*************************************************************************
        //  Method: SaveSubgraphImage()
        //
        /// <summary>
        /// Saves an image of a subgraph to disk.
        /// </summary>
        ///
        /// <param name="oBitmap">
        /// Subgraph image.
        /// </param>
        ///
        /// <param name="sFolder">
        /// Full path to the folder to save the image to.
        /// </param>
        ///
        /// <param name="sFileNameNoExtension">
        /// Name of the file to save the image to, without a path or extension.
        /// </param>
        ///
        /// <param name="oCreateSubgraphImagesAsyncArgs">
        /// Contains the arguments needed to asynchronously create subgraph images.
        /// </param>
        ///
        /// <returns>
        /// The name of the file the image was saved to, without a path.
        /// </returns>
        //*************************************************************************
        protected String SaveSubgraphImage(
            Bitmap oBitmap,
            String sFolder,
            String sFileNameNoExtension,
            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs
            )
        {
            Debug.Assert(oBitmap != null);
            Debug.Assert( !String.IsNullOrEmpty(sFolder) );
            Debug.Assert( !String.IsNullOrEmpty(sFileNameNoExtension) );
            Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
            AssertValid();

            ImageFormat eImageFormat = oCreateSubgraphImagesAsyncArgs.ImageFormat;

            String sFileNameWithoutPath =
            FileUtil.EncodeIllegalFileNameChars(sFileNameNoExtension)
            + "." + SaveableImageFormats.GetFileExtension(eImageFormat);

            String sFileNameWithPath = Path.Combine(sFolder, sFileNameWithoutPath);

            SaveBitmap(oBitmap, sFileNameWithPath, eImageFormat);

            return (sFileNameWithoutPath);
        }
        //*************************************************************************
        //  Method: CreateAndSaveSubgraphImageInFolder()
        //
        /// <summary>
        /// Creates an image of a subgraph for one of a graph's vertices and saves
        /// the image to a specified folder.
        /// </summary>
        ///
        /// <param name="oSubgraph">
        /// The subgraph to create an image for.
        /// </param>
        ///
        /// <param name="sVertexName">
        /// Name of the vertex the subgraph is for.
        /// </param>
        ///
        /// <param name="oCreateSubgraphImagesAsyncArgs">
        /// Contains the arguments needed to asynchronously create subgraph images.
        /// </param>
        //*************************************************************************
        protected void CreateAndSaveSubgraphImageInFolder(
            IGraph oSubgraph,
            String sVertexName,
            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs
            )
        {
            Debug.Assert(oSubgraph != null);
            Debug.Assert( !String.IsNullOrEmpty(sVertexName) );
            Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
            Debug.Assert(oCreateSubgraphImagesAsyncArgs.SaveToFolder);
            AssertValid();

            // Save the graph to a bitmap.

            Bitmap oBitmap = CreateSubgraphImage(oSubgraph,
            oCreateSubgraphImagesAsyncArgs,
            oCreateSubgraphImagesAsyncArgs.ImageSizePx);

            try
            {
            // Save the bitmap in the specified folder.

            SaveSubgraphImage(oBitmap,
                oCreateSubgraphImagesAsyncArgs.Folder,
                sVertexName, oCreateSubgraphImagesAsyncArgs
                );
            }
            finally
            {
            GraphicsUtil.DisposeBitmap(ref oBitmap);
            }
        }
        //*************************************************************************
        //  Method: CreateSubgraphImagesAsync()
        //
        /// <summary>
        /// Asynchronously creates images of a subgraph for each of a graph's
        /// vertices and saves the images to disk.
        /// </summary>
        ///
        /// <param name="graph">
        /// The graph to use.
        /// </param>
        ///
        /// <param name="selectedVertices">
        /// Collection of the vertices in <paramref name="graph" /> that were
        /// selected by the user in the workbook from which the graph was created.
        /// Can be empty but not null.
        /// </param>
        ///
        /// <param name="levels">
        /// The number of levels of adjacent vertices to include in each subgraph.
        /// Must be a multiple of 0.5.  If 0, a subgraph includes just the vertex;
        /// if 1, it includes the vertex and its adjacent vertices; if 2, it
        /// includes the vertex, its adjacent vertices, and their adjacent
        /// vertices; and so on.  The difference between N.5 and N.0 is that N.5
        /// includes any edges connecting the outermost vertices to each other,
        /// whereas N.0 does not.  1.5, for example, includes any edges that
        /// connect the vertex's adjacent vertices to each other, whereas 1.0
        /// includes only those edges that connect the adjacent vertices to the
        /// vertex.
        /// </param>
        ///
        /// <param name="saveToFolder">
        /// true to save subgraph images to a folder.
        /// </param>
        ///
        /// <param name="folder">
        /// The folder to save subgraph images to.  Used only if <paramref
        /// name="saveToFolder" /> is true.
        /// </param>
        ///
        /// <param name="imageSizePx">
        /// The size of each subgraph image saved to a folder, in pixels.  Used
        /// only if <paramref name="saveToFolder" /> is true.
        /// </param>
        ///
        /// <param name="imageFormat">
        /// The format of each subgraph image saved to a folder.  Used only if
        /// <paramref name="saveToFolder" /> is true.
        /// </param>
        ///
        /// <param name="createThumbnails">
        /// true to save thumbnail images to a temporary folder.
        /// </param>
        ///
        /// <param name="thumbnailSizePx">
        /// The size of each thumbnail image, in pixels.  Used only if <paramref
        /// name="createThumbnails" /> is true.
        /// </param>
        ///
        /// <param name="selectedVerticesOnly">
        /// true to create subgraph images for the vertices in <paramref
        /// name="selectedVertices" /> only, false to create them for all images.
        /// </param>
        ///
        /// <param name="selectVertex">
        /// true to select the vertex around which each subgraph is created.
        /// </param>
        ///
        /// <param name="selectIncidentEdges">
        /// true to select the incident edges of the vertex around which each
        /// subgraph is created.
        /// </param>
        ///
        /// <param name="generalUserSettings">
        /// The user's general user settings.
        /// </param>
        ///
        /// <param name="layoutUserSettings">
        /// The user's layout user settings.
        /// </param>
        ///
        /// <remarks>
        /// When image creation completes, the <see
        /// cref="ImageCreationCompleted" /> event fires.
        ///
        /// <para>
        /// If thumbnail images are created, they are saved to a temporary folder.
        /// Information about the thumbnail images can be found in the <see
        /// cref="TemporaryImages" /> object stored in the <see
        /// cref="RunWorkerCompletedEventArgs.Result" /> propery of the <see
        /// cref="RunWorkerCompletedEventArgs" /> returned by the <see
        /// cref="ImageCreationCompleted" /> event.
        /// </para>
        ///
        /// <para>
        /// To cancel the analysis, call <see cref="CancelAsync" />.
        /// </para>
        ///
        /// </remarks>
        //*************************************************************************
        public void CreateSubgraphImagesAsync(
            IGraph graph,
            ICollection<IVertex> selectedVertices,
            Decimal levels,
            Boolean saveToFolder,
            String folder,
            Size imageSizePx,
            ImageFormat imageFormat,
            Boolean createThumbnails,
            Size thumbnailSizePx,
            Boolean selectedVerticesOnly,
            Boolean selectVertex,
            Boolean selectIncidentEdges,
            GeneralUserSettings generalUserSettings,
            LayoutUserSettings layoutUserSettings
            )
        {
            Debug.Assert(graph != null);
            Debug.Assert(selectedVertices != null);
            Debug.Assert(levels >= 0);
            Debug.Assert(Decimal.Remainder(levels, 0.5M) == 0M);
            Debug.Assert( !saveToFolder || !String.IsNullOrEmpty(folder) );
            Debug.Assert( !saveToFolder || imageSizePx.Width > 0);
            Debug.Assert( !saveToFolder || imageSizePx.Height > 0);
            Debug.Assert( !createThumbnails || thumbnailSizePx.Width > 0);
            Debug.Assert( !createThumbnails || thumbnailSizePx.Height > 0);
            Debug.Assert(generalUserSettings != null);
            AssertValid();

            const String MethodName = "CreateSubgraphImagesAsync";

            if (this.IsBusy)
            {
            throw new InvalidOperationException( String.Format(

                "{0}:{1}: An asynchronous operation is already in progress."
                ,
                this.ClassName,
                MethodName
                ) );
            }

            // Wrap the arguments in an object that can be passed to
            // BackgroundWorker.RunWorkerAsync().

            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs =
            new CreateSubgraphImagesAsyncArgs();

            oCreateSubgraphImagesAsyncArgs.Graph = graph;
            oCreateSubgraphImagesAsyncArgs.SelectedVertices = selectedVertices;
            oCreateSubgraphImagesAsyncArgs.Levels = levels;
            oCreateSubgraphImagesAsyncArgs.SaveToFolder = saveToFolder;
            oCreateSubgraphImagesAsyncArgs.Folder = folder;
            oCreateSubgraphImagesAsyncArgs.ImageSizePx = imageSizePx;
            oCreateSubgraphImagesAsyncArgs.ImageFormat = imageFormat;
            oCreateSubgraphImagesAsyncArgs.CreateThumbnails = createThumbnails;
            oCreateSubgraphImagesAsyncArgs.ThumbnailSizePx = thumbnailSizePx;

            oCreateSubgraphImagesAsyncArgs.SelectedVerticesOnly =
            selectedVerticesOnly;

            oCreateSubgraphImagesAsyncArgs.SelectVertex = selectVertex;

            oCreateSubgraphImagesAsyncArgs.SelectIncidentEdges =
            selectIncidentEdges;

            oCreateSubgraphImagesAsyncArgs.GeneralUserSettings =
            generalUserSettings;

            oCreateSubgraphImagesAsyncArgs.Layout =
            CreateLayout(layoutUserSettings);

            // Note: the NodeXLVisual object can't be created yet, because it must
            // be created on the same thread that uses it.  It will get created by
            // BackgroundWorker_DoWork().

            oCreateSubgraphImagesAsyncArgs.NodeXLVisual = null;

            // Create a BackgroundWorker and handle its events.

            m_oBackgroundWorker = new BackgroundWorker();

            m_oBackgroundWorker.WorkerReportsProgress = true;
            m_oBackgroundWorker.WorkerSupportsCancellation = true;

            m_oBackgroundWorker.DoWork += new DoWorkEventHandler(
            BackgroundWorker_DoWork);

            m_oBackgroundWorker.ProgressChanged +=
            new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged);

            m_oBackgroundWorker.RunWorkerCompleted +=
            new RunWorkerCompletedEventHandler(
                BackgroundWorker_RunWorkerCompleted);

            m_oBackgroundWorker.RunWorkerAsync(oCreateSubgraphImagesAsyncArgs);
        }
Example #13
0
        CreateSubgraphImagesInternal
        (
            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs,
            BackgroundWorker oBackgroundWorker,
            DoWorkEventArgs oDoWorkEventArgs
        )
        {
            Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
            Debug.Assert(oBackgroundWorker != null);
            Debug.Assert(oDoWorkEventArgs != null);
            AssertValid();

            // Create an object to keep track of the thumbnail images this method
            // creates and stores in a temporary folder.

            TemporaryImages oThumbnailImages = new TemporaryImages();

            oThumbnailImages.ImageSizePx =
                oCreateSubgraphImagesAsyncArgs.ThumbnailSizePx;

            oDoWorkEventArgs.Result = oThumbnailImages;

            ICollection <IVertex> oVertices;

            if (oCreateSubgraphImagesAsyncArgs.SelectedVerticesOnly)
            {
                oVertices = oCreateSubgraphImagesAsyncArgs.SelectedVertices;
            }
            else
            {
                oVertices = oCreateSubgraphImagesAsyncArgs.Graph.Vertices;
            }

            Int32 iSubgraphsCreated = 0;

            Boolean bSaveToFolder = oCreateSubgraphImagesAsyncArgs.SaveToFolder;

            Boolean bCreateThumbnails =
                oCreateSubgraphImagesAsyncArgs.CreateThumbnails;

            if (bSaveToFolder || bCreateThumbnails)
            {
                foreach (IVertex oVertex in oVertices)
                {
                    if (oBackgroundWorker.CancellationPending)
                    {
                        if (oThumbnailImages.Folder != null)
                        {
                            // Delete the entire temporary folder.

                            Directory.Delete(oThumbnailImages.Folder, true);

                            oThumbnailImages.Folder = null;
                        }

                        oDoWorkEventArgs.Cancel = true;
                        break;
                    }

                    String sVertexName = oVertex.Name;

                    oBackgroundWorker.ReportProgress(0,
                                                     String.Format(
                                                         "Creating subgraph image for \"{0}\"."
                                                         ,
                                                         sVertexName
                                                         ));

                    // Create a subgraph for the vertex.

                    IGraph oSubgraph = CreateSubgraph(oVertex,
                                                      oCreateSubgraphImagesAsyncArgs);

                    // Create and save images for the subgraph.

                    CreateAndSaveSubgraphImages(oSubgraph, sVertexName,
                                                oCreateSubgraphImagesAsyncArgs, oThumbnailImages);

                    iSubgraphsCreated++;
                }
            }

            oBackgroundWorker.ReportProgress(0,
                                             String.Format(
                                                 "Done.  Created {0} subgraph {1}."
                                                 ,
                                                 iSubgraphsCreated.ToString(ExcelTemplateForm.Int32Format),
                                                 StringUtil.MakePlural("image", iSubgraphsCreated)
                                                 ));
        }
        //*************************************************************************
        //  Method: CreateAndSaveSubgraphImages()
        //
        /// <summary>
        /// Creates images of a subgraph for one of a graph's vertices and saves
        /// the images to disk.
        /// </summary>
        ///
        /// <param name="oSubgraph">
        /// The subgraph to create images for.
        /// </param>
        ///
        /// <param name="sVertexName">
        /// Name of the vertex the subgraph is for.
        /// </param>
        ///
        /// <param name="oCreateSubgraphImagesAsyncArgs">
        /// Contains the arguments needed to asynchronously create subgraph images.
        /// </param>
        ///
        /// <param name="oThumbnailImages">
        /// Keeps track of the thumbnail images this method creates and stores in a
        /// temporary folder.
        /// </param>
        ///
        /// <remarks>
        /// This method creates zero, one, or two images of a subgraph and saves
        /// them to disk.
        /// </remarks>
        //*************************************************************************
        protected void CreateAndSaveSubgraphImages(
            IGraph oSubgraph,
            String sVertexName,
            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs,
            TemporaryImages oThumbnailImages
            )
        {
            Debug.Assert(oSubgraph != null);
            Debug.Assert( !String.IsNullOrEmpty(sVertexName) );
            Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
            Debug.Assert(oThumbnailImages != null);
            AssertValid();

            if (oCreateSubgraphImagesAsyncArgs.SaveToFolder)
            {
            CreateAndSaveSubgraphImageInFolder(oSubgraph, sVertexName,
                oCreateSubgraphImagesAsyncArgs);
            }

            if (oCreateSubgraphImagesAsyncArgs.CreateThumbnails)
            {
            CreateAndSaveThumbnailImage(oSubgraph, sVertexName,
                oCreateSubgraphImagesAsyncArgs, oThumbnailImages);
            }
        }
Example #15
0
        CreateSubgraphImagesAsync
        (
            IGraph graph,
            ICollection <IVertex> selectedVertices,
            Decimal levels,
            Boolean saveToFolder,
            String folder,
            Size imageSizePx,
            ImageFormat imageFormat,
            Boolean createThumbnails,
            Size thumbnailSizePx,
            Boolean selectedVerticesOnly,
            Boolean selectVertex,
            Boolean selectIncidentEdges,
            GeneralUserSettings generalUserSettings,
            LayoutUserSettings layoutUserSettings
        )
        {
            Debug.Assert(graph != null);
            Debug.Assert(selectedVertices != null);
            Debug.Assert(levels >= 0);
            Debug.Assert(Decimal.Remainder(levels, 0.5M) == 0M);
            Debug.Assert(!saveToFolder || !String.IsNullOrEmpty(folder));
            Debug.Assert(!saveToFolder || imageSizePx.Width > 0);
            Debug.Assert(!saveToFolder || imageSizePx.Height > 0);
            Debug.Assert(!createThumbnails || thumbnailSizePx.Width > 0);
            Debug.Assert(!createThumbnails || thumbnailSizePx.Height > 0);
            Debug.Assert(generalUserSettings != null);
            AssertValid();

            const String MethodName = "CreateSubgraphImagesAsync";

            if (this.IsBusy)
            {
                throw new InvalidOperationException(String.Format(

                                                        "{0}:{1}: An asynchronous operation is already in progress."
                                                        ,
                                                        this.ClassName,
                                                        MethodName
                                                        ));
            }

            // Wrap the arguments in an object that can be passed to
            // BackgroundWorker.RunWorkerAsync().

            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs =
                new CreateSubgraphImagesAsyncArgs();

            oCreateSubgraphImagesAsyncArgs.Graph            = graph;
            oCreateSubgraphImagesAsyncArgs.SelectedVertices = selectedVertices;
            oCreateSubgraphImagesAsyncArgs.Levels           = levels;
            oCreateSubgraphImagesAsyncArgs.SaveToFolder     = saveToFolder;
            oCreateSubgraphImagesAsyncArgs.Folder           = folder;
            oCreateSubgraphImagesAsyncArgs.ImageSizePx      = imageSizePx;
            oCreateSubgraphImagesAsyncArgs.ImageFormat      = imageFormat;
            oCreateSubgraphImagesAsyncArgs.CreateThumbnails = createThumbnails;
            oCreateSubgraphImagesAsyncArgs.ThumbnailSizePx  = thumbnailSizePx;

            oCreateSubgraphImagesAsyncArgs.SelectedVerticesOnly =
                selectedVerticesOnly;

            oCreateSubgraphImagesAsyncArgs.SelectVertex = selectVertex;

            oCreateSubgraphImagesAsyncArgs.SelectIncidentEdges =
                selectIncidentEdges;

            oCreateSubgraphImagesAsyncArgs.GeneralUserSettings =
                generalUserSettings;

            oCreateSubgraphImagesAsyncArgs.Layout =
                CreateLayout(layoutUserSettings);

            // Note: the NodeXLVisual object can't be created yet, because it must
            // be created on the same thread that uses it.  It will get created by
            // BackgroundWorker_DoWork().

            oCreateSubgraphImagesAsyncArgs.NodeXLVisual = null;

            // Create a BackgroundWorker and handle its events.

            m_oBackgroundWorker = new BackgroundWorker();

            m_oBackgroundWorker.WorkerReportsProgress      = true;
            m_oBackgroundWorker.WorkerSupportsCancellation = true;

            m_oBackgroundWorker.DoWork += new DoWorkEventHandler(
                BackgroundWorker_DoWork);

            m_oBackgroundWorker.ProgressChanged +=
                new ProgressChangedEventHandler(BackgroundWorker_ProgressChanged);

            m_oBackgroundWorker.RunWorkerCompleted +=
                new RunWorkerCompletedEventHandler(
                    BackgroundWorker_RunWorkerCompleted);

            m_oBackgroundWorker.RunWorkerAsync(oCreateSubgraphImagesAsyncArgs);
        }
        //*************************************************************************
        //  Method: CreateAndSaveThumbnailImage()
        //
        /// <summary>
        /// Creates a thumbnail image of a subgraph for one of a graph's vertices.
        /// </summary>
        ///
        /// <param name="oSubgraph">
        /// The subgraph to create an image for.
        /// </param>
        ///
        /// <param name="sVertexName">
        /// Name of the vertex the subgraph is for.
        /// </param>
        ///
        /// <param name="oCreateSubgraphImagesAsyncArgs">
        /// Contains the arguments needed to asynchronously create subgraph images.
        /// </param>
        ///
        /// <param name="oThumbnailImages">
        /// Keeps track of the thumbnail images this method creates and stores in a
        /// temporary folder.
        /// </param>
        //*************************************************************************
        protected void CreateAndSaveThumbnailImage(
            IGraph oSubgraph,
            String sVertexName,
            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs,
            TemporaryImages oThumbnailImages
            )
        {
            Debug.Assert(oSubgraph != null);
            Debug.Assert( !String.IsNullOrEmpty(sVertexName) );
            Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
            Debug.Assert(oCreateSubgraphImagesAsyncArgs.CreateThumbnails);
            Debug.Assert(oThumbnailImages != null);
            AssertValid();

            if (oThumbnailImages.Folder == null)
            {
            // Create a temporary folder where the thumbnail images will be
            // stored.

            String sTemporaryFolder = Path.Combine(
                Path.GetTempPath(),
                Path.GetRandomFileName()
                );

            Directory.CreateDirectory(sTemporaryFolder);

            oThumbnailImages.Folder = sTemporaryFolder;
            }

            // Save the graph to a bitmap.

            Bitmap oBitmap = CreateSubgraphImage(oSubgraph,
            oCreateSubgraphImagesAsyncArgs,
            oCreateSubgraphImagesAsyncArgs.ThumbnailSizePx);

            try
            {
            // Save the bitmap in the temporary folder.

            String sTemporaryFileName = SaveSubgraphImage(oBitmap,
                oThumbnailImages.Folder, sVertexName,
                oCreateSubgraphImagesAsyncArgs
                );

            // Add the file name to the dictionary.  They key is the vertex
            // name and the value is the file name, without a path.

            oThumbnailImages.FileNames[sVertexName] = sTemporaryFileName;
            }
            finally
            {
            GraphicsUtil.DisposeBitmap(ref oBitmap);
            }
        }
        //*************************************************************************
        //  Method: CreateSubgraphImagesInternal()
        //
        /// <summary>
        /// Creates an image of a subgraph for each of a graph's vertices and saves
        /// the images to disk.
        /// </summary>
        ///
        /// <param name="oCreateSubgraphImagesAsyncArgs">
        /// Contains the arguments needed to asynchronously create subgraph images.
        /// </param>
        ///
        /// <param name="oBackgroundWorker">
        /// A BackgroundWorker object.
        /// </param>
        ///
        /// <param name="oDoWorkEventArgs">
        /// A DoWorkEventArgs object.
        /// </param>
        //*************************************************************************
        protected void CreateSubgraphImagesInternal(
            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs,
            BackgroundWorker oBackgroundWorker,
            DoWorkEventArgs oDoWorkEventArgs
            )
        {
            Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
            Debug.Assert(oBackgroundWorker != null);
            Debug.Assert(oDoWorkEventArgs != null);
            AssertValid();

            // Create an object to keep track of the thumbnail images this method
            // creates and stores in a temporary folder.

            TemporaryImages oThumbnailImages = new TemporaryImages();

            oThumbnailImages.ImageSizePx =
            oCreateSubgraphImagesAsyncArgs.ThumbnailSizePx;

            oDoWorkEventArgs.Result = oThumbnailImages;

            ICollection<IVertex> oVertices;

            if (oCreateSubgraphImagesAsyncArgs.SelectedVerticesOnly)
            {
            oVertices = oCreateSubgraphImagesAsyncArgs.SelectedVertices;
            }
            else
            {
            oVertices = oCreateSubgraphImagesAsyncArgs.Graph.Vertices;
            }

            Int32 iSubgraphsCreated = 0;

            Boolean bSaveToFolder = oCreateSubgraphImagesAsyncArgs.SaveToFolder;

            Boolean bCreateThumbnails =
            oCreateSubgraphImagesAsyncArgs.CreateThumbnails;

            if (bSaveToFolder || bCreateThumbnails)
            {
            foreach (IVertex oVertex in oVertices)
            {
                if (oBackgroundWorker.CancellationPending)
                {
                    if (oThumbnailImages.Folder != null)
                    {
                        // Delete the entire temporary folder.

                        Directory.Delete(oThumbnailImages.Folder, true);

                        oThumbnailImages.Folder = null;
                    }

                    oDoWorkEventArgs.Cancel = true;
                    break;
                }

                String sVertexName = oVertex.Name;

                oBackgroundWorker.ReportProgress(0,
                    String.Format(
                        "Creating subgraph image for \"{0}\"."
                        ,
                        sVertexName
                    ) );

                // Create a subgraph for the vertex.

                IGraph oSubgraph = CreateSubgraph(oVertex,
                    oCreateSubgraphImagesAsyncArgs);

                // Create and save images for the subgraph.

                CreateAndSaveSubgraphImages(oSubgraph, sVertexName,
                    oCreateSubgraphImagesAsyncArgs, oThumbnailImages);

                iSubgraphsCreated++;
            }
            }

            oBackgroundWorker.ReportProgress(0,
            String.Format(
                "Done.  Created {0} subgraph {1}."
                ,
                iSubgraphsCreated.ToString(ExcelTemplateForm.Int32Format),
                StringUtil.MakePlural("image", iSubgraphsCreated)
                ) );
        }
        //*************************************************************************
        //  Method: CreateSubgraphImage()
        //
        /// <summary>
        /// Creates an image of a subgraph for one of a graph's vertices.
        /// </summary>
        ///
        /// <param name="oSubgraph">
        /// The subgraph to create an image for.
        /// </param>
        ///
        /// <param name="oCreateSubgraphImagesAsyncArgs">
        /// Contains the arguments needed to asynchronously create subgraph images.
        /// </param>
        ///
        /// <param name="oImageSizePx">
        /// Size of the image, in pixels.
        /// </param>
        ///
        /// <returns>
        /// The subgraph image, as a Bitmap.
        /// </returns>
        //*************************************************************************
        protected Bitmap CreateSubgraphImage(
            IGraph oSubgraph,
            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs,
            Size oImageSizePx
            )
        {
            Debug.Assert(oSubgraph != null);
            Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
            AssertValid();

            Rectangle oSubgraphRectangle = new Rectangle(new Point(0, 0),
            oImageSizePx);

            // Lay out the graph, then draw it using the NodeXLVisual object.

            IAsyncLayout oLayout = oCreateSubgraphImagesAsyncArgs.Layout;

            oLayout.LayOutGraph( oSubgraph,
            new LayoutContext(oSubgraphRectangle) );

            NodeXLVisual oNodeXLVisual =
            oCreateSubgraphImagesAsyncArgs.NodeXLVisual;

            GraphDrawingContext oGraphDrawingContext =
            CreateGraphDrawingContext(oSubgraphRectangle,
                oLayout.Margin,
                oCreateSubgraphImagesAsyncArgs.GeneralUserSettings);

            oNodeXLVisual.GraphDrawer.DrawGraph(oSubgraph, oGraphDrawingContext);

            // Save the graph to a bitmap.

            Bitmap oBitmap = WpfGraphicsUtil.VisualToBitmap(oNodeXLVisual,
            oSubgraphRectangle.Width, oSubgraphRectangle.Height);

            return (oBitmap);
        }
        //*************************************************************************
        //  Method: CreateSubgraph()
        //
        /// <summary>
        /// Creates a subgraph for one of a graph's vertices.
        /// </summary>
        ///
        /// <param name="oOriginalVertex">
        /// The vertex to create a subgraph for.
        /// </param>
        ///
        /// <param name="oCreateSubgraphImagesAsyncArgs">
        /// Contains the arguments needed to asynchronously create subgraph images.
        /// </param>
        ///
        /// <returns>
        /// A new subgraph.
        /// </returns>
        //*************************************************************************
        protected IGraph CreateSubgraph(
            IVertex oOriginalVertex,
            CreateSubgraphImagesAsyncArgs oCreateSubgraphImagesAsyncArgs
            )
        {
            Debug.Assert(oOriginalVertex != null);
            Debug.Assert(oCreateSubgraphImagesAsyncArgs != null);
            AssertValid();

            // Create a new empty graph that will contain the vertex's subgraph.

            IGraph oSubgraph = new Graph();

            // Clone the original vertex, its adjacent vertices, and the connecting
            // edges into the subgraph.

            Decimal decLevels = oCreateSubgraphImagesAsyncArgs.Levels;

            IVertex oSubgraphVertex = CloneVertexIntoSubgraph(oOriginalVertex,
            oSubgraph, decLevels);

            if (oCreateSubgraphImagesAsyncArgs.SelectVertex)
            {
            // Select the vertex.

            oSubgraphVertex.SetValue(ReservedMetadataKeys.IsSelected, true);
            }

            if (oCreateSubgraphImagesAsyncArgs.SelectIncidentEdges)
            {
            // Select the vertex's incident edges.

            foreach (IEdge oIncidentEdge in oSubgraphVertex.IncidentEdges)
            {
                oIncidentEdge.SetValue(ReservedMetadataKeys.IsSelected, true);
            }
            }

            return (oSubgraph);
        }