示例#1
0
        TryCalculateGraphMetricsForOneGroup
        (
            GroupInformation oGroupInformation,
            CalculateGraphMetricsContext oCalculateGraphMetricsContext,
            out OverallMetrics oOverallMetrics
        )
        {
            Debug.Assert(oGroupInformation != null);
            Debug.Assert(oGroupInformation.Vertices != null);
            Debug.Assert(oGroupInformation.Vertices.Count > 0);
            Debug.Assert(oCalculateGraphMetricsContext != null);
            AssertValid();

            oOverallMetrics = null;

            ICollection <IVertex> oVertices = oGroupInformation.Vertices;

            // Create a new graph from the vertices in the group and the edges that
            // connect them.

            IGraph oNewGraph = SubgraphCalculator.GetSubgraphAsNewGraph(oVertices);

            // Calculate the overall metrics for the new graph using the
            // OverallMetricCalculator class in the Algorithms namespace, which
            // knows nothing about Excel.

            return((new Algorithms.OverallMetricCalculator()).
                   TryCalculateGraphMetrics(oNewGraph,
                                            oCalculateGraphMetricsContext.BackgroundWorker,
                                            out oOverallMetrics));
        }
示例#2
0
        TryCalculateGraphMetrics
        (
            IGraph graph,
            CalculateGraphMetricsContext calculateGraphMetricsContext,
            out GraphMetricColumn [] graphMetricColumns
        )
        {
            Debug.Assert(graph != null);
            Debug.Assert(calculateGraphMetricsContext != null);
            AssertValid();

            graphMetricColumns = null;

            // Partition the graph into clusters using the ClusterCalculator class
            // in the Algorithms namespace, which knows nothing about Excel.

            ICollection <Community> oCommunities;

            Algorithms.ClusterCalculator oClusterCalculator =
                new Algorithms.ClusterCalculator();

            oClusterCalculator.Algorithm = m_eAlgorithm;

            if (!oClusterCalculator.TryCalculateGraphMetrics(graph,
                                                             calculateGraphMetricsContext.BackgroundWorker,
                                                             out oCommunities))
            {
                // The user cancelled.

                return(false);
            }

            // Convert the collection of communities to an array of
            // GraphMetricColumn objects.

            graphMetricColumns =
                GroupsToGraphMetricColumnsConverter.Convert <Community>(
                    oCommunities,
                    (oCommunity) => oCommunity.Vertices
                    );

            return(true);
        }
示例#3
0
        TryCalculateGraphMetrics
        (
            IGraph graph,
            CalculateGraphMetricsContext calculateGraphMetricsContext,
            out GraphMetricColumn [] graphMetricColumns
        )
        {
            Debug.Assert(graph != null);
            Debug.Assert(calculateGraphMetricsContext != null);
            AssertValid();

            return(TryCalculateGraphMetrics(graph, calculateGraphMetricsContext,
                                            new Algorithms.PageRankCalculator(),

                                            calculateGraphMetricsContext.GraphMetricUserSettings.
                                            ShouldCalculateGraphMetrics(GraphMetrics.PageRank),

                                            VertexTableColumnNames.PageRank,
                                            VertexTableColumnWidths.PageRank,
                                            CellStyleNames.GraphMetricGood, out graphMetricColumns));
        }
        TryCalculateGraphMetrics
        (
            IGraph graph,
            CalculateGraphMetricsContext calculateGraphMetricsContext,
            out GraphMetricColumn [] graphMetricColumns
        )
        {
            Debug.Assert(graph != null);
            Debug.Assert(calculateGraphMetricsContext != null);
            AssertValid();

            graphMetricColumns = null;

            // Partition the graph into strongly connected components using the
            // ConnectedComponentCalculator class in the Algorithms namespace,
            // which knows nothing about Excel.
            //
            // Note that ConnectedComponentCalculator does its work synchronously.

            Algorithms.ConnectedComponentCalculator oConnectedComponentCalculator =
                new Algorithms.ConnectedComponentCalculator();

            IList <LinkedList <IVertex> > oComponents =
                oConnectedComponentCalculator.CalculateStronglyConnectedComponents(
                    graph, false);

            // Convert the collection of components to an array of
            // GraphMetricColumn objects.

            graphMetricColumns =
                GroupsToGraphMetricColumnsConverter.Convert <LinkedList <IVertex> >(
                    oComponents,
                    (oComponent) => oComponent
                    );

            return(true);
        }
        //*************************************************************************
        //  Method: TryCalculateGraphMetrics()
        //
        /// <summary>
        /// Attempts to calculate a set of one or more related metrics.
        /// </summary>
        ///
        /// <param name="graph">
        /// The graph to calculate metrics for.  The graph may contain duplicate
        /// edges and self-loops.
        /// </param>
        ///
        /// <param name="calculateGraphMetricsContext">
        /// Provides access to objects needed for calculating graph metrics.
        /// </param>
        ///
        /// <param name="graphMetricColumns">
        /// Where an array of GraphMetricColumn objects gets stored if true is
        /// returned, one for each related metric calculated by this method.
        /// </param>
        ///
        /// <returns>
        /// true if the graph metrics were calculated, false if the user wants to
        /// cancel.
        /// </returns>
        ///
        /// <remarks>
        /// This method periodically checks BackgroundWorker.<see
        /// cref="BackgroundWorker.CancellationPending" />.  If true, the method
        /// immediately returns false.
        ///
        /// <para>
        /// It also periodically reports progress by calling the
        /// BackgroundWorker.<see
        /// cref="BackgroundWorker.ReportProgress(Int32, Object)" /> method.  The
        /// userState argument is a <see cref="GraphMetricProgress" /> object.
        /// </para>
        ///
        /// <para>
        /// Calculated metrics for hidden rows are ignored by the caller, because
        /// Excel misbehaves when values are written to hidden cells.
        /// </para>
        ///
        /// </remarks>
        //*************************************************************************
        public override Boolean TryCalculateGraphMetrics(
            IGraph graph,
            CalculateGraphMetricsContext calculateGraphMetricsContext,
            out GraphMetricColumn [] graphMetricColumns
            )
        {
            Debug.Assert(graph != null);
            Debug.Assert(calculateGraphMetricsContext != null);
            AssertValid();

            graphMetricColumns = new GraphMetricColumn[0];

            if ( !calculateGraphMetricsContext.GraphMetricUserSettings.
            CalculateGraphMetrics(GraphMetrics.OverallMetrics) )
            {
            return (true);
            }

            // Calculate the overall metrics using the OverallMetricCalculator
            // class in the Algorithms namespace, which knows nothing about Excel.

            OverallMetrics oOverallMetrics;

            if ( !( new Algorithms.OverallMetricCalculator() ).
            TryCalculateGraphMetrics(graph,
                calculateGraphMetricsContext.BackgroundWorker,
                out oOverallMetrics) )
            {
            // The user cancelled.

            return (false);
            }

            OverallMetricRows oOverallMetricRows = new OverallMetricRows();

            //*********************************
            // Graph type
            //*********************************

            AddRow("Graph Type", oOverallMetrics.Directedness.ToString(),
            oOverallMetricRows);

            //*********************************
            // Vertex count
            //*********************************

            AddRow(oOverallMetricRows);
            AddRow("Vertices", oOverallMetrics.Vertices, oOverallMetricRows);

            //*********************************
            // Edge counts
            //*********************************

            String sDuplicateEdgeStyle = CellStyleNames.GraphMetricGood;
            String sDuplicateEdgeComments = String.Empty;
            String sGraphDensityComments = String.Empty;

            if (oOverallMetrics.EdgesWithDuplicates > 0)
            {
            // The graph density is rendered invalid when the graph has
            // duplicate edges.

            sDuplicateEdgeStyle = CellStyleNames.GraphMetricBad;

            sDuplicateEdgeComments =
                "You can merge duplicate edges using NodeXL, Data, Prepare"
                + " Data, Merge Duplicate Edges."
                ;

            sGraphDensityComments =
                "The workbook contains duplicate edges that have caused the"
                + " graph density to be inaccurate.  "
                + sDuplicateEdgeComments
                ;
            }

            AddRow(oOverallMetricRows);
            AddRow("Unique Edges", oOverallMetrics.UniqueEdges, oOverallMetricRows);

            AddRow("Edges With Duplicates",
            FormatInt32(oOverallMetrics.EdgesWithDuplicates),
            sDuplicateEdgeComments, sDuplicateEdgeStyle,
            oOverallMetricRows);

            AddRow("Total Edges", oOverallMetrics.TotalEdges, oOverallMetricRows);

            //*********************************
            // Self-loops
            //*********************************

            AddRow(oOverallMetricRows);
            AddRow("Self-Loops", oOverallMetrics.SelfLoops, oOverallMetricRows);

            //*********************************
            // Connected component counts
            //*********************************

            AddRow(oOverallMetricRows);

            AddRow("Connected Components", oOverallMetrics.ConnectedComponents,
            oOverallMetricRows);

            AddRow("Single-Vertex Connected Components",
            oOverallMetrics.SingleVertexConnectedComponents,
            oOverallMetricRows);

            AddRow("Maximum Vertices in a Connected Component",
            oOverallMetrics.MaximumConnectedComponentVertices,
            oOverallMetricRows);

            AddRow("Maximum Edges in a Connected Component",
            oOverallMetrics.MaximumConnectedComponentEdges,
            oOverallMetricRows);

            //*********************************
            // Geodesic distances
            //*********************************

            String sMaximumGeodesicDistance, sAverageGeodesicDistance;

            GetGeodesicDistanceStrings(oOverallMetrics,
            out sMaximumGeodesicDistance, out sAverageGeodesicDistance);

            AddRow(oOverallMetricRows);

            AddRow("Maximum Geodesic Distance (Diameter)",
            sMaximumGeodesicDistance, oOverallMetricRows);

            AddRow("Average Geodesic Distance", sAverageGeodesicDistance,
            oOverallMetricRows);

            //*********************************
            // Graph density
            //*********************************

            Nullable<Double> dGraphDensity = oOverallMetrics.GraphDensity;

            AddRow(oOverallMetricRows);

            AddRow("Graph Density", dGraphDensity.HasValue ?
            FormatDouble(dGraphDensity.Value) : NotApplicableMessage,
            sGraphDensityComments, sDuplicateEdgeStyle, oOverallMetricRows);

            //*********************************
            // NodeXL version
            //*********************************

            AddRow(oOverallMetricRows);

            AddRow("NodeXL Version", AssemblyUtil2.GetFileVersion(),
            oOverallMetricRows);

            graphMetricColumns = new GraphMetricColumn[] {

            CreateGraphMetricColumnOrdered(
                OverallMetricsTableColumnNames.Name,
                oOverallMetricRows.MetricNames),

            CreateGraphMetricColumnOrdered(
                OverallMetricsTableColumnNames.Value,
                oOverallMetricRows.MetricValues),

            CreateGraphMetricColumnOrdered(
                OverallMetricsTableColumnNames.Comments,
                oOverallMetricRows.MetricComments),
            };

            return (true);
        }
        //*************************************************************************
        //  Method: TryCalculateGraphMetrics()
        //
        /// <summary>
        /// Attempts to calculate a set of one or more related metrics.
        /// </summary>
        ///
        /// <param name="graph">
        /// The graph to calculate metrics for.  The graph may contain duplicate
        /// edges and self-loops.
        /// </param>
        ///
        /// <param name="calculateGraphMetricsContext">
        /// Provides access to objects needed for calculating graph metrics.
        /// </param>
        ///
        /// <param name="graphMetricColumns">
        /// Where an array of GraphMetricColumn objects gets stored if true is
        /// returned, one for each related metric calculated by this method.
        /// </param>
        ///
        /// <returns>
        /// true if the graph metrics were calculated or don't need to be
        /// calculated, false if the user wants to cancel.
        /// </returns>
        ///
        /// <remarks>
        /// This method periodically checks BackgroundWorker.<see
        /// cref="BackgroundWorker.CancellationPending" />.  If true, the method
        /// immediately returns false.
        ///
        /// <para>
        /// It also periodically reports progress by calling the
        /// BackgroundWorker.<see
        /// cref="BackgroundWorker.ReportProgress(Int32, Object)" /> method.  The
        /// userState argument is a <see cref="GraphMetricProgress" /> object.
        /// </para>
        ///
        /// <para>
        /// Calculated metrics for hidden rows are ignored by the caller, because
        /// Excel misbehaves when values are written to hidden cells.
        /// </para>
        ///
        /// </remarks>
        //*************************************************************************
        public override Boolean TryCalculateGraphMetrics(
            IGraph graph,
            CalculateGraphMetricsContext calculateGraphMetricsContext,
            out GraphMetricColumn [] graphMetricColumns
            )
        {
            Debug.Assert(graph != null);
            Debug.Assert(calculateGraphMetricsContext != null);
            AssertValid();

            return ( TryCalculateGraphMetrics(graph, calculateGraphMetricsContext,
            new Algorithms.EigenvectorCentralityCalculator(),

            calculateGraphMetricsContext.GraphMetricUserSettings.
                ShouldCalculateGraphMetrics(GraphMetrics.EigenvectorCentrality),

            VertexTableColumnNames.EigenvectorCentrality,
            VertexTableColumnWidths.EigenvectorCentrality,
            CellStyleNames.GraphMetricGood, out graphMetricColumns) );
        }
        //*************************************************************************
        //  Method: CalculateGraphMetricsAsyncInternal()
        //
        /// <summary>
        /// Calculates one or more sets of graph metrics and stores the results in
        /// one or more worksheet columns.
        /// </summary>
        ///
        /// <param name="oCalculateGraphMetricsAsyncArgs">
        /// Contains the arguments needed to asynchronously calculate graph
        /// metrics.
        /// </param>
        ///
        /// <param name="oBackgroundWorker">
        /// A BackgroundWorker object.
        /// </param>
        ///
        /// <param name="oDoWorkEventArgs">
        /// A DoWorkEventArgs object.
        /// </param>
        //*************************************************************************
        protected void CalculateGraphMetricsAsyncInternal(
            CalculateGraphMetricsAsyncArgs oCalculateGraphMetricsAsyncArgs,
            BackgroundWorker oBackgroundWorker,
            DoWorkEventArgs oDoWorkEventArgs
            )
        {
            Debug.Assert(oCalculateGraphMetricsAsyncArgs != null);
            Debug.Assert(oBackgroundWorker != null);
            Debug.Assert(oDoWorkEventArgs != null);
            AssertValid();

            IGraph oGraph = oCalculateGraphMetricsAsyncArgs.Graph;

            List<GraphMetricColumn> oAggregatedGraphMetricColumns =
            new List<GraphMetricColumn>();

            CalculateGraphMetricsContext oCalculateGraphMetricsContext =
            new CalculateGraphMetricsContext(
                oCalculateGraphMetricsAsyncArgs.GraphMetricUserSettings,
                oBackgroundWorker);

            Boolean bDuplicateEdgesRemoved = false;

            foreach (IGraphMetricCalculator2 oGraphMetricCalculator in
            oCalculateGraphMetricsAsyncArgs.SortedGraphMetricCalculators)
            {
            if (!oGraphMetricCalculator.HandlesDuplicateEdges &&
                !bDuplicateEdgesRemoved)
            {
                // This and the remainder of the graph metric calculators
                // cannot handle duplicate edges.  Remove them from the graph.

                oGraph.Edges.RemoveDuplicates();
                bDuplicateEdgesRemoved = true;
            }

            // Calculate the implementation's graph metrics.

            GraphMetricColumn [] aoGraphMetricColumns;

            if ( !oGraphMetricCalculator.TryCalculateGraphMetrics(oGraph,
                oCalculateGraphMetricsContext, out aoGraphMetricColumns) )
            {
                // The user cancelled.

                oDoWorkEventArgs.Cancel = true;

                oBackgroundWorker.ReportProgress(0,
                    new GraphMetricProgress("Cancelled.", false)
                    );

                return;
            }

            // Aggregate the results.

            Debug.Assert(aoGraphMetricColumns != null);

            oAggregatedGraphMetricColumns.AddRange(aoGraphMetricColumns);
            }

            oDoWorkEventArgs.Result = oAggregatedGraphMetricColumns.ToArray();

            oBackgroundWorker.ReportProgress(100,
            new GraphMetricProgress(
                "Inserting metrics into the workbook.",
                true)
            );

            // Let the dialog the display the final progress report and update its
            // controls.

            System.Threading.Thread.Sleep(1);
        }
        TryCalculateGraphMetrics
        (
            IGraph graph,
            CalculateGraphMetricsContext calculateGraphMetricsContext,
            out GraphMetricColumn [] graphMetricColumns
        )
        {
            Debug.Assert(graph != null);
            Debug.Assert(calculateGraphMetricsContext != null);
            AssertValid();

            graphMetricColumns = new GraphMetricColumn[0];

            if (!calculateGraphMetricsContext.GraphMetricUserSettings.
                CalculateGraphMetrics(GraphMetrics.OverallMetrics))
            {
                return(true);
            }

            // Calculate the overall metrics using the OverallMetricCalculator
            // class in the Algorithms namespace, which knows nothing about Excel.

            OverallMetrics oOverallMetrics;

            if (!(new Algorithms.OverallMetricCalculator()).
                TryCalculateGraphMetrics(graph,
                                         calculateGraphMetricsContext.BackgroundWorker,
                                         out oOverallMetrics))
            {
                // The user cancelled.

                return(false);
            }

            OverallMetricRows oOverallMetricRows = new OverallMetricRows();


            //*********************************
            // Graph type
            //*********************************

            AddRow("Graph Type", oOverallMetrics.Directedness.ToString(),
                   oOverallMetricRows);


            //*********************************
            // Vertex count
            //*********************************

            AddRow(oOverallMetricRows);
            AddRow("Vertices", oOverallMetrics.Vertices, oOverallMetricRows);


            //*********************************
            // Edge counts
            //*********************************

            String sDuplicateEdgeStyle    = CellStyleNames.GraphMetricGood;
            String sDuplicateEdgeComments = String.Empty;
            String sGraphDensityComments  = String.Empty;

            if (oOverallMetrics.EdgesWithDuplicates > 0)
            {
                // The graph density is rendered invalid when the graph has
                // duplicate edges.

                sDuplicateEdgeStyle = CellStyleNames.GraphMetricBad;

                sDuplicateEdgeComments =
                    "You can merge duplicate edges using NodeXL, Data, Prepare"
                    + " Data, Merge Duplicate Edges."
                ;

                sGraphDensityComments =
                    "The workbook contains duplicate edges that have caused the"
                    + " graph density to be inaccurate.  "
                    + sDuplicateEdgeComments
                ;
            }

            AddRow(oOverallMetricRows);
            AddRow("Unique Edges", oOverallMetrics.UniqueEdges, oOverallMetricRows);

            AddRow("Edges With Duplicates",
                   FormatInt32(oOverallMetrics.EdgesWithDuplicates),
                   sDuplicateEdgeComments, sDuplicateEdgeStyle,
                   oOverallMetricRows);

            AddRow("Total Edges", oOverallMetrics.TotalEdges, oOverallMetricRows);


            //*********************************
            // Self-loops
            //*********************************

            AddRow(oOverallMetricRows);
            AddRow("Self-Loops", oOverallMetrics.SelfLoops, oOverallMetricRows);


            //*********************************
            // Connected component counts
            //*********************************

            AddRow(oOverallMetricRows);

            AddRow("Connected Components", oOverallMetrics.ConnectedComponents,
                   oOverallMetricRows);

            AddRow("Single-Vertex Connected Components",
                   oOverallMetrics.SingleVertexConnectedComponents,
                   oOverallMetricRows);

            AddRow("Maximum Vertices in a Connected Component",
                   oOverallMetrics.MaximumConnectedComponentVertices,
                   oOverallMetricRows);

            AddRow("Maximum Edges in a Connected Component",
                   oOverallMetrics.MaximumConnectedComponentEdges,
                   oOverallMetricRows);


            //*********************************
            // Geodesic distances
            //*********************************

            String sMaximumGeodesicDistance, sAverageGeodesicDistance;

            GetGeodesicDistanceStrings(oOverallMetrics,
                                       out sMaximumGeodesicDistance, out sAverageGeodesicDistance);

            AddRow(oOverallMetricRows);

            AddRow("Maximum Geodesic Distance (Diameter)",
                   sMaximumGeodesicDistance, oOverallMetricRows);

            AddRow("Average Geodesic Distance", sAverageGeodesicDistance,
                   oOverallMetricRows);


            //*********************************
            // Graph density
            //*********************************

            Nullable <Double> dGraphDensity = oOverallMetrics.GraphDensity;

            AddRow(oOverallMetricRows);

            AddRow("Graph Density", dGraphDensity.HasValue ?
                   FormatDouble(dGraphDensity.Value) : NotApplicableMessage,
                   sGraphDensityComments, sDuplicateEdgeStyle, oOverallMetricRows);


            //*********************************
            // NodeXL version
            //*********************************

            AddRow(oOverallMetricRows);

            AddRow("NodeXL Version", AssemblyUtil2.GetFileVersion(),
                   oOverallMetricRows);


            graphMetricColumns = new GraphMetricColumn[] {
                CreateGraphMetricColumnOrdered(
                    OverallMetricsTableColumnNames.Name,
                    oOverallMetricRows.MetricNames),

                CreateGraphMetricColumnOrdered(
                    OverallMetricsTableColumnNames.Value,
                    oOverallMetricRows.MetricValues),

                CreateGraphMetricColumnOrdered(
                    OverallMetricsTableColumnNames.Comments,
                    oOverallMetricRows.MetricComments),
            };

            return(true);
        }
        //*************************************************************************
        //  Method: FilterGraphMetricColumns()
        //
        /// <summary>
        /// Determines which GraphMetricColumn objects to return to the caller.
        /// </summary>
        ///
        /// <param name="oGraph">
        /// The graph to calculate metrics for.
        /// </param>
        ///
        /// <param name="oCalculateGraphMetricsContext">
        /// Provides access to objects needed for calculating graph metrics.
        /// </param>
        ///
        /// <param name="oInDegreeGraphMetricValues">
        /// List of GraphMetricValue objects for the in-degree column on the vertex
        /// worksheet.
        /// </param>
        ///
        /// <param name="oOutDegreeGraphMetricValues">
        /// List of GraphMetricValue objects for the out-degree column on the
        /// vertex worksheet.
        /// </param>
        ///
        /// <param name="oDegreeGraphMetricValues">
        /// List of GraphMetricValue objects for the degree column on the vertex
        /// worksheet.
        /// </param>
        ///
        /// <returns>
        /// An array of GraphMetricColumn objects.
        /// </returns>
        //*************************************************************************
        protected GraphMetricColumn[] FilterGraphMetricColumns(
            IGraph oGraph,
            CalculateGraphMetricsContext oCalculateGraphMetricsContext,
            List<GraphMetricValueWithID> oInDegreeGraphMetricValues,
            List<GraphMetricValueWithID> oOutDegreeGraphMetricValues,
            List<GraphMetricValueWithID> oDegreeGraphMetricValues
            )
        {
            AssertValid();

            Debug.Assert(oGraph != null);
            Debug.Assert(oCalculateGraphMetricsContext != null);
            Debug.Assert(oInDegreeGraphMetricValues != null);
            Debug.Assert(oOutDegreeGraphMetricValues != null);
            Debug.Assert(oDegreeGraphMetricValues != null);

            GraphMetricUserSettings oGraphMetricUserSettings =
            oCalculateGraphMetricsContext.GraphMetricUserSettings;

            Boolean bGraphIsDirected =
            (oGraph.Directedness == GraphDirectedness.Directed);

            Boolean bCalculateInDegree = bGraphIsDirected &&
            oGraphMetricUserSettings.ShouldCalculateGraphMetrics(
                GraphMetrics.InDegree);

            Boolean bCalculateOutDegree = bGraphIsDirected &&
            oGraphMetricUserSettings.ShouldCalculateGraphMetrics(
                GraphMetrics.OutDegree);

            Boolean bCalculateDegree = !bGraphIsDirected &&
            oGraphMetricUserSettings.ShouldCalculateGraphMetrics(
                GraphMetrics.Degree);

            // Figure out which columns to add.

            List<GraphMetricColumn> oGraphMetricColumns =
            new List<GraphMetricColumn>();

            if (bCalculateInDegree)
            {
            oGraphMetricColumns.Add( new GraphMetricColumnWithID(
                WorksheetNames.Vertices, TableNames.Vertices,
                VertexTableColumnNames.InDegree,
                VertexTableColumnWidths.InDegree,
                NumericFormat, CellStyleNames.GraphMetricGood,
                oInDegreeGraphMetricValues.ToArray() ) );
            }

            if (bCalculateOutDegree)
            {
            oGraphMetricColumns.Add( new GraphMetricColumnWithID(
                WorksheetNames.Vertices, TableNames.Vertices,
                VertexTableColumnNames.OutDegree,
                ExcelUtil.AutoColumnWidth,
                NumericFormat, CellStyleNames.GraphMetricGood,
                oOutDegreeGraphMetricValues.ToArray() ) );
            }

            if (bCalculateDegree)
            {
            oGraphMetricColumns.Add( new GraphMetricColumnWithID(
                WorksheetNames.Vertices, TableNames.Vertices,
                VertexTableColumnNames.Degree,
                ExcelUtil.AutoColumnWidth,
                NumericFormat, CellStyleNames.GraphMetricGood,
                oDegreeGraphMetricValues.ToArray() ) );
            }

            return ( oGraphMetricColumns.ToArray() );
        }
 //*************************************************************************
 //  Method: TryCalculateGraphMetrics()
 //
 /// <summary>
 /// Attempts to calculate a set of one or more related metrics.
 /// </summary>
 ///
 /// <param name="graph">
 /// The graph to calculate metrics for.  The graph may contain duplicate
 /// edges and self-loops.
 /// </param>
 ///
 /// <param name="calculateGraphMetricsContext">
 /// Provides access to objects needed for calculating graph metrics.
 /// </param>
 ///
 /// <param name="graphMetricColumns">
 /// Where an array of GraphMetricColumn objects gets stored if true is
 /// returned, one for each related metric calculated by this method.
 /// </param>
 ///
 /// <returns>
 /// true if the graph metrics were calculated or don't need to be
 /// calculated, false if the user wants to cancel.
 /// </returns>
 ///
 /// <remarks>
 /// This method should periodically check BackgroundWorker.<see
 /// cref="BackgroundWorker.CancellationPending" />.  If true, the method
 /// should immediately return false.
 ///
 /// <para>
 /// It should also periodically report progress by calling the
 /// BackgroundWorker.<see
 /// cref="BackgroundWorker.ReportProgress(Int32, Object)" /> method.  The
 /// userState argument must be a <see cref="GraphMetricProgress" /> object.
 /// </para>
 ///
 /// <para>
 /// Calculated metrics for hidden rows are ignored by the caller, because
 /// Excel misbehaves when values are written to hidden cells.
 /// </para>
 ///
 /// </remarks>
 //*************************************************************************
 public abstract Boolean TryCalculateGraphMetrics(
     IGraph graph,
     CalculateGraphMetricsContext calculateGraphMetricsContext,
     out GraphMetricColumn [] graphMetricColumns
     );
        //*************************************************************************
        //  Method: TryCalculateGraphMetrics()
        //
        /// <summary>
        /// Attempts to calculate a set of one or more related metrics.
        /// </summary>
        ///
        /// <param name="graph">
        /// The graph to calculate metrics for.  The graph may contain duplicate
        /// edges and self-loops.
        /// </param>
        ///
        /// <param name="calculateGraphMetricsContext">
        /// Provides access to objects needed for calculating graph metrics.
        /// </param>
        ///
        /// <param name="oneDoubleGraphMetricCalculator">
        /// Graph metric calculator in the Algorithms namespace that calculates
        /// one graph metric of type Double.
        /// </param>
        ///
        /// <param name="calculateGraphMetric">
        /// true to calculate the graph metric, false to skip it.
        /// </param>
        ///
        /// <param name="columnName">
        /// Name of the column to write to in the vertex table.
        /// </param>
        ///
        /// <param name="columnWidthChars">
        /// Width of the column, in characters, or <see
        /// cref="Microsoft.Research.CommunityTechnologies.AppLib.ExcelUtil.
        /// AutoColumnWidth" /> to set the width automatically.
        /// </param>
        ///
        /// <param name="style">
        /// Style of the column, or null to apply Excel's normal style.  Sample:
        /// "Bad".
        /// </param>
        ///
        /// <param name="graphMetricColumns">
        /// Where an array of GraphMetricColumn objects gets stored if true is
        /// returned, one for each related metric calculated by this method.
        /// </param>
        ///
        /// <returns>
        /// true if the graph metrics were calculated or don't need to be
        /// calculated, false if the user wants to cancel.
        /// </returns>
        ///
        /// <remarks>
        /// This method periodically checks BackgroundWorker.<see
        /// cref="BackgroundWorker.CancellationPending" />.  If true, the method
        /// immediately returns false.
        ///
        /// <para>
        /// It also periodically reports progress by calling the
        /// BackgroundWorker.<see
        /// cref="BackgroundWorker.ReportProgress(Int32, Object)" /> method.  The
        /// userState argument is a <see cref="GraphMetricProgress" /> object.
        /// </para>
        ///
        /// <para>
        /// Calculated metrics for hidden rows are ignored by the caller, because
        /// Excel misbehaves when values are written to hidden cells.
        /// </para>
        ///
        /// </remarks>
        //*************************************************************************
        protected Boolean TryCalculateGraphMetrics(
            IGraph graph,
            CalculateGraphMetricsContext calculateGraphMetricsContext,
            
            Algorithms.OneDoubleGraphMetricCalculatorBase
            oneDoubleGraphMetricCalculator,
            
            Boolean calculateGraphMetric,
            String columnName,
            Double columnWidthChars,
            String style,
            out GraphMetricColumn [] graphMetricColumns
            )
        {
            Debug.Assert(graph != null);
            Debug.Assert(calculateGraphMetricsContext != null);
            Debug.Assert(oneDoubleGraphMetricCalculator != null);
            Debug.Assert( !String.IsNullOrEmpty(columnName) );

            Debug.Assert(columnWidthChars == ExcelUtil.AutoColumnWidth ||
            columnWidthChars > 0);

            AssertValid();

            graphMetricColumns = new GraphMetricColumn[0];

            if (!calculateGraphMetric)
            {
            return (true);
            }

            // Calculate the graph metrics for each vertex using the
            // OneDoubleGraphMetricCalculatorBase object, which knows nothing about
            // Excel.

            Dictionary<Int32, Double> oGraphMetrics;

            if ( !oneDoubleGraphMetricCalculator.TryCalculateGraphMetrics(graph,
            calculateGraphMetricsContext.BackgroundWorker, out oGraphMetrics) )
            {
            // The user cancelled.

            return (false);
            }

            // Transfer the graph metrics to an array of GraphMetricValue objects.

            List<GraphMetricValueWithID> oGraphMetricValues =
            new List<GraphMetricValueWithID>();

            foreach (IVertex oVertex in graph.Vertices)
            {
            // Try to get the row ID stored in the worksheet.

            Int32 iRowID;

            if ( TryGetRowID(oVertex, out iRowID) )
            {
                oGraphMetricValues.Add( new GraphMetricValueWithID(
                    iRowID, oGraphMetrics[oVertex.ID] ) );
            }
            }

            graphMetricColumns = new GraphMetricColumn [] {
            new GraphMetricColumnWithID( WorksheetNames.Vertices,
                TableNames.Vertices, columnName, columnWidthChars,
                NumericFormat, style, oGraphMetricValues.ToArray()
                ) };

            return (true);
        }
        TryCalculateGraphMetrics
        (
            IGraph graph,
            CalculateGraphMetricsContext calculateGraphMetricsContext,
            out GraphMetricColumn [] graphMetricColumns
        )
        {
            Debug.Assert(graph != null);
            Debug.Assert(calculateGraphMetricsContext != null);
            AssertValid();

            graphMetricColumns = new GraphMetricColumn[0];

            if (!calculateGraphMetricsContext.GraphMetricUserSettings.
                ShouldCalculateGraphMetrics(GraphMetrics.BrandesFastCentralities))
            {
                return(true);
            }

            // Calculate the centralities for each vertex using the
            // BrandesFastCalculator class in the Algorithms namespace, which knows
            // nothing about Excel.

            Dictionary <Int32, Algorithms.BrandesVertexCentralities>
            oVertexCentralitiesDictionary;

            if (!(new Algorithms.BrandesFastCentralityCalculator()).
                TryCalculateGraphMetrics(graph,
                                         calculateGraphMetricsContext.BackgroundWorker,
                                         out oVertexCentralitiesDictionary))
            {
                // The user cancelled.

                return(false);
            }

            // Transfer the centralities to arrays of GraphMetricValue objects.

            List <GraphMetricValueWithID> oBetweennessCentralityValues =
                new List <GraphMetricValueWithID>();

            List <GraphMetricValueWithID> oClosenessCentralityValues =
                new List <GraphMetricValueWithID>();

            foreach (IVertex oVertex in graph.Vertices)
            {
                // Try to get the row ID stored in the worksheet.

                Int32 iRowID;

                if (TryGetRowID(oVertex, out iRowID))
                {
                    Algorithms.BrandesVertexCentralities oVertexCentralities =
                        oVertexCentralitiesDictionary[oVertex.ID];

                    oBetweennessCentralityValues.Add(
                        new GraphMetricValueWithID(iRowID,
                                                   oVertexCentralities.BetweennessCentrality
                                                   ));

                    oClosenessCentralityValues.Add(
                        new GraphMetricValueWithID(iRowID,
                                                   oVertexCentralities.ClosenessCentrality
                                                   ));
                }
            }

            graphMetricColumns = new GraphMetricColumn [] {
                new GraphMetricColumnWithID(WorksheetNames.Vertices,
                                            TableNames.Vertices,
                                            VertexTableColumnNames.BetweennessCentrality,
                                            VertexTableColumnWidths.BetweennessCentrality,
                                            NumericFormat, CellStyleNames.GraphMetricGood,
                                            oBetweennessCentralityValues.ToArray()
                                            ),

                new GraphMetricColumnWithID(WorksheetNames.Vertices,
                                            TableNames.Vertices,
                                            VertexTableColumnNames.ClosenessCentrality,
                                            VertexTableColumnWidths.ClosenessCentrality,
                                            NumericFormat, CellStyleNames.GraphMetricGood,
                                            oClosenessCentralityValues.ToArray()
                                            )
            };

            return(true);
        }
        //*************************************************************************
        //  Method: TryCalculateGraphMetrics()
        //
        /// <summary>
        /// Attempts to calculate a set of one or more related metrics.
        /// </summary>
        ///
        /// <param name="graph">
        /// The graph to calculate metrics for.  The graph may contain duplicate
        /// edges and self-loops.
        /// </param>
        ///
        /// <param name="calculateGraphMetricsContext">
        /// Provides access to objects needed for calculating graph metrics.
        /// </param>
        ///
        /// <param name="graphMetricColumns">
        /// Where an array of GraphMetricColumn objects gets stored if true is
        /// returned, one for each related metric calculated by this method.
        /// </param>
        ///
        /// <returns>
        /// true if the graph metrics were calculated or don't need to be
        /// calculated, false if the user wants to cancel.
        /// </returns>
        ///
        /// <remarks>
        /// This method periodically checks BackgroundWorker.<see
        /// cref="BackgroundWorker.CancellationPending" />.  If true, the method
        /// immediately returns false.
        ///
        /// <para>
        /// It also periodically reports progress by calling the
        /// BackgroundWorker.<see
        /// cref="BackgroundWorker.ReportProgress(Int32, Object)" /> method.  The
        /// userState argument is a <see cref="GraphMetricProgress" /> object.
        /// </para>
        ///
        /// <para>
        /// Calculated metrics for hidden rows are ignored by the caller, because
        /// Excel misbehaves when values are written to hidden cells.
        /// </para>
        ///
        /// </remarks>
        //*************************************************************************
        public override Boolean TryCalculateGraphMetrics(
            IGraph graph,
            CalculateGraphMetricsContext calculateGraphMetricsContext,
            out GraphMetricColumn [] graphMetricColumns
            )
        {
            Debug.Assert(graph != null);
            Debug.Assert(calculateGraphMetricsContext != null);
            AssertValid();

            graphMetricColumns = new GraphMetricColumn[0];

            if ( !calculateGraphMetricsContext.GraphMetricUserSettings.
            ShouldCalculateGraphMetrics(GraphMetrics.BrandesFastCentralities) )
            {
            return (true);
            }

            // Calculate the centralities for each vertex using the
            // BrandesFastCalculator class in the Algorithms namespace, which knows
            // nothing about Excel.

            Dictionary<Int32, Algorithms.BrandesVertexCentralities>
            oVertexCentralitiesDictionary;

            if ( !( new Algorithms.BrandesFastCentralityCalculator() ).
            TryCalculateGraphMetrics(graph,
                calculateGraphMetricsContext.BackgroundWorker,
                out oVertexCentralitiesDictionary) )
            {
            // The user cancelled.

            return (false);
            }

            // Transfer the centralities to arrays of GraphMetricValue objects.

            List<GraphMetricValueWithID> oBetweennessCentralityValues =
            new List<GraphMetricValueWithID>();

            List<GraphMetricValueWithID> oClosenessCentralityValues =
            new List<GraphMetricValueWithID>();

            foreach (IVertex oVertex in graph.Vertices)
            {
            // Try to get the row ID stored in the worksheet.

            Int32 iRowID;

            if ( TryGetRowID(oVertex, out iRowID) )
            {
                Algorithms.BrandesVertexCentralities oVertexCentralities =
                    oVertexCentralitiesDictionary[oVertex.ID];

                oBetweennessCentralityValues.Add(
                    new GraphMetricValueWithID(iRowID,
                        oVertexCentralities.BetweennessCentrality
                    ) );

                oClosenessCentralityValues.Add(
                    new GraphMetricValueWithID(iRowID,
                        oVertexCentralities.ClosenessCentrality
                    ) );
            }
            }

            graphMetricColumns = new GraphMetricColumn [] {

            new GraphMetricColumnWithID( WorksheetNames.Vertices,
                TableNames.Vertices,
                VertexTableColumnNames.BetweennessCentrality,
                VertexTableColumnWidths.BetweennessCentrality,
                NumericFormat, CellStyleNames.GraphMetricGood,
                oBetweennessCentralityValues.ToArray()
                ),

            new GraphMetricColumnWithID( WorksheetNames.Vertices,
                TableNames.Vertices,
                VertexTableColumnNames.ClosenessCentrality,
                VertexTableColumnWidths.ClosenessCentrality,
                NumericFormat, CellStyleNames.GraphMetricGood,
                oClosenessCentralityValues.ToArray()
                )
                };

            return (true);
        }
示例#14
0
        TryCalculateGraphMetrics
        (
            IGraph graph,
            CalculateGraphMetricsContext calculateGraphMetricsContext,
            out GraphMetricColumn [] graphMetricColumns
        )
        {
            Debug.Assert(graph != null);
            Debug.Assert(calculateGraphMetricsContext != null);
            AssertValid();

            // Note regarding cell styles:
            //
            // Versions of NodeXL earlier than 1.0.1.130 didn't merge duplicate
            // edges before calculating graph metrics, and as a result some metrics
            // were invalid.  That was indicated by applying the CellStyleNames.Bad
            // Excel style to the invalid cells.  Starting in version 1.0.1.130
            // there are no longer invalid metrics, but the
            // CellStyleNames.GraphMetricGood style is always applied to those old
            // potentially bad metric cells (instead of null, which uses the
            // current cell style) in case graph metrics are calculated on an old
            // workbook that had bad metric cells.  If null were used, the old Bad
            // style would always remain on the previously bad cells, even if are
            // now filled with good metric values.

            graphMetricColumns = new GraphMetricColumn[0];

            if (!calculateGraphMetricsContext.GraphMetricUserSettings.
                ShouldCalculateGraphMetrics(GraphMetrics.OverallMetrics))
            {
                return(true);
            }

            // Calculate the overall metrics using the OverallMetricCalculator
            // class in the Algorithms namespace, which knows nothing about Excel.

            OverallMetrics oOverallMetrics;

            if (!(new Algorithms.OverallMetricCalculator()).
                TryCalculateGraphMetrics(graph,
                                         calculateGraphMetricsContext.BackgroundWorker,
                                         out oOverallMetrics))
            {
                // The user cancelled.

                return(false);
            }

            OverallMetricRows oOverallMetricRows = new OverallMetricRows();


            //*********************************
            // Graph type
            //*********************************

            AddRow("Graph Type", oOverallMetrics.Directedness.ToString(),
                   oOverallMetricRows);


            //*********************************
            // Vertex count
            //*********************************

            AddRow(oOverallMetricRows);
            AddRow("Vertices", oOverallMetrics.Vertices, oOverallMetricRows);


            //*********************************
            // Edge counts
            //*********************************

            AddRow(oOverallMetricRows);

            AddRow("Unique Edges", oOverallMetrics.UniqueEdges, oOverallMetricRows);

            AddRow("Edges With Duplicates", oOverallMetrics.EdgesWithDuplicates,
                   oOverallMetricRows);

            AddRow("Total Edges", oOverallMetrics.TotalEdges, oOverallMetricRows);


            //*********************************
            // Self-loops
            //*********************************

            AddRow(oOverallMetricRows);

            AddRow("Self-Loops", oOverallMetrics.SelfLoops, oOverallMetricRows);


            //*********************************
            // Connected component counts
            //*********************************

            AddRow(oOverallMetricRows);

            AddRow("Connected Components", oOverallMetrics.ConnectedComponents,
                   oOverallMetricRows);

            AddRow("Single-Vertex Connected Components",
                   oOverallMetrics.SingleVertexConnectedComponents,
                   oOverallMetricRows);

            AddRow("Maximum Vertices in a Connected Component",
                   oOverallMetrics.MaximumConnectedComponentVertices,
                   oOverallMetricRows);

            AddRow("Maximum Edges in a Connected Component",
                   oOverallMetrics.MaximumConnectedComponentEdges,
                   oOverallMetricRows);


            //*********************************
            // Geodesic distances
            //*********************************

            AddRow(oOverallMetricRows);

            AddRow("Maximum Geodesic Distance (Diameter)",

                   NullableToGraphMetricValue <Int32>(
                       oOverallMetrics.MaximumGeodesicDistance),

                   oOverallMetricRows);

            AddRow("Average Geodesic Distance",

                   NullableToGraphMetricValue <Double>(
                       oOverallMetrics.AverageGeodesicDistance),

                   oOverallMetricRows);


            //*********************************
            // Graph density
            //*********************************

            AddRow(oOverallMetricRows);

            AddRow("Graph Density",
                   NullableToGraphMetricValue <Double>(oOverallMetrics.GraphDensity),
                   oOverallMetricRows);


            //*********************************
            // NodeXL version
            //*********************************

            AddRow(oOverallMetricRows);

            AddRow("NodeXL Version", AssemblyUtil2.GetFileVersion(),
                   oOverallMetricRows);


            graphMetricColumns = new GraphMetricColumn[] {
                CreateGraphMetricColumnOrdered(
                    OverallMetricsTableColumnNames.Name,
                    oOverallMetricRows.MetricNames),

                CreateGraphMetricColumnOrdered(
                    OverallMetricsTableColumnNames.Value,
                    oOverallMetricRows.MetricValues),
            };

            return(true);
        }
示例#15
0
        FilterGraphMetricColumns
        (
            IGraph oGraph,
            CalculateGraphMetricsContext oCalculateGraphMetricsContext,
            List <GraphMetricValueWithID> oInDegreeGraphMetricValues,
            List <GraphMetricValueWithID> oOutDegreeGraphMetricValues,
            List <GraphMetricValueWithID> oDegreeGraphMetricValues
        )
        {
            AssertValid();

            Debug.Assert(oGraph != null);
            Debug.Assert(oCalculateGraphMetricsContext != null);
            Debug.Assert(oInDegreeGraphMetricValues != null);
            Debug.Assert(oOutDegreeGraphMetricValues != null);
            Debug.Assert(oDegreeGraphMetricValues != null);

            GraphMetricUserSettings oGraphMetricUserSettings =
                oCalculateGraphMetricsContext.GraphMetricUserSettings;

            Boolean bGraphIsDirected =
                (oGraph.Directedness == GraphDirectedness.Directed);

            Boolean bCalculateInDegree = bGraphIsDirected &&
                                         oGraphMetricUserSettings.ShouldCalculateGraphMetrics(
                GraphMetrics.InDegree);

            Boolean bCalculateOutDegree = bGraphIsDirected &&
                                          oGraphMetricUserSettings.ShouldCalculateGraphMetrics(
                GraphMetrics.OutDegree);

            Boolean bCalculateDegree = !bGraphIsDirected &&
                                       oGraphMetricUserSettings.ShouldCalculateGraphMetrics(
                GraphMetrics.Degree);

            // Figure out which columns to add.

            List <GraphMetricColumn> oGraphMetricColumns =
                new List <GraphMetricColumn>();

            if (bCalculateInDegree)
            {
                oGraphMetricColumns.Add(new GraphMetricColumnWithID(
                                            WorksheetNames.Vertices, TableNames.Vertices,
                                            VertexTableColumnNames.InDegree,
                                            VertexTableColumnWidths.InDegree,
                                            NumericFormat, CellStyleNames.GraphMetricGood,
                                            oInDegreeGraphMetricValues.ToArray()));
            }

            if (bCalculateOutDegree)
            {
                oGraphMetricColumns.Add(new GraphMetricColumnWithID(
                                            WorksheetNames.Vertices, TableNames.Vertices,
                                            VertexTableColumnNames.OutDegree,
                                            ExcelUtil.AutoColumnWidth,
                                            NumericFormat, CellStyleNames.GraphMetricGood,
                                            oOutDegreeGraphMetricValues.ToArray()));
            }

            if (bCalculateDegree)
            {
                oGraphMetricColumns.Add(new GraphMetricColumnWithID(
                                            WorksheetNames.Vertices, TableNames.Vertices,
                                            VertexTableColumnNames.Degree,
                                            ExcelUtil.AutoColumnWidth,
                                            NumericFormat, CellStyleNames.GraphMetricGood,
                                            oDegreeGraphMetricValues.ToArray()));
            }

            return(oGraphMetricColumns.ToArray());
        }
示例#16
0
        TryCalculateGraphMetrics
        (
            IGraph graph,
            CalculateGraphMetricsContext calculateGraphMetricsContext,
            out GraphMetricColumn [] graphMetricColumns
        )
        {
            Debug.Assert(graph != null);
            Debug.Assert(calculateGraphMetricsContext != null);
            AssertValid();

            graphMetricColumns = new GraphMetricColumn[0];

            GraphMetricUserSettings oGraphMetricUserSettings =
                calculateGraphMetricsContext.GraphMetricUserSettings;

            if (!oGraphMetricUserSettings.ShouldCalculateGraphMetrics(
                    GraphMetrics.Degree |
                    GraphMetrics.InDegree |
                    GraphMetrics.OutDegree
                    ))
            {
                return(true);
            }

            IVertexCollection oVertices = graph.Vertices;
            Int32             iVertices = oVertices.Count;

            // The following lists correspond to vertex worksheet columns.

            List <GraphMetricValueWithID> oInDegreeGraphMetricValues =
                new List <GraphMetricValueWithID>();

            List <GraphMetricValueWithID> oOutDegreeGraphMetricValues =
                new List <GraphMetricValueWithID>();

            List <GraphMetricValueWithID> oDegreeGraphMetricValues =
                new List <GraphMetricValueWithID>();

            // Create a dictionary to keep track of vertex degrees.  The key is the
            // IVertex.ID and the value is a zero-based index into the above lists.

            Dictionary <Int32, Int32> oVertexIDDictionary =
                new Dictionary <Int32, Int32>();

            // Calculate the degrees for each vertex using the
            // VertexDegreeCalculator class in the Algorithms namespace, which
            // knows nothing about Excel.
            //
            // For simplicity, all degree metrics (in-degree, out-degree, and
            // degree) are calculated regardless of whether the graph is directed
            // or undirected.  After all metrics are calculated,
            // FilterGraphMetricColumns() filters out the metrics that don't apply
            // to the graph, based on its directedness.

            Dictionary <Int32, VertexDegrees> oVertexDegreeDictionary;

            if (!(new Algorithms.VertexDegreeCalculator()).
                TryCalculateGraphMetrics(graph,
                                         calculateGraphMetricsContext.BackgroundWorker,
                                         out oVertexDegreeDictionary))
            {
                // The user cancelled.

                return(false);
            }

            Int32 iRowID;

            foreach (IVertex oVertex in oVertices)
            {
                if (!TryGetRowID(oVertex, out iRowID))
                {
                    continue;
                }

                VertexDegrees oVertexDegrees;

                if (!oVertexDegreeDictionary.TryGetValue(oVertex.ID,
                                                         out oVertexDegrees))
                {
                    Debug.Assert(false);
                }

                oInDegreeGraphMetricValues.Add(new GraphMetricValueWithID(
                                                   iRowID, oVertexDegrees.InDegree));

                oOutDegreeGraphMetricValues.Add(new GraphMetricValueWithID(
                                                    iRowID, oVertexDegrees.OutDegree));

                oDegreeGraphMetricValues.Add(new GraphMetricValueWithID(
                                                 iRowID, oVertexDegrees.Degree));

                Debug.Assert(oInDegreeGraphMetricValues.Count ==
                             oOutDegreeGraphMetricValues.Count);

                oVertexIDDictionary.Add(oVertex.ID,
                                        oInDegreeGraphMetricValues.Count - 1);
            }

            // Figure out which columns to add.

            graphMetricColumns = FilterGraphMetricColumns(graph,
                                                          calculateGraphMetricsContext, oInDegreeGraphMetricValues,
                                                          oOutDegreeGraphMetricValues, oDegreeGraphMetricValues);

            return(true);
        }
示例#17
0
        TryCalculateGraphMetrics
        (
            IGraph graph,
            CalculateGraphMetricsContext calculateGraphMetricsContext,
            IGraphMetricCalculator graphMetricCalculator,
            Boolean calculateGraphMetric,
            String columnName,
            Double columnWidthChars,
            String style,
            out GraphMetricColumn [] graphMetricColumns
        )
        {
            Debug.Assert(graph != null);
            Debug.Assert(calculateGraphMetricsContext != null);
            Debug.Assert(graphMetricCalculator != null);
            Debug.Assert(!String.IsNullOrEmpty(columnName));

            Debug.Assert(columnWidthChars == ExcelUtil.AutoColumnWidth ||
                         columnWidthChars > 0);

            AssertValid();

            graphMetricColumns = new GraphMetricColumn[0];

            if (!calculateGraphMetric)
            {
                return(true);
            }

            // Calculate the graph metrics for each vertex using the
            // IGraphMetricCalculator object, which knows nothing about Excel.

            Object oGraphMetricsAsObject;

            if (!graphMetricCalculator.TryCalculateGraphMetrics(graph,
                                                                calculateGraphMetricsContext.BackgroundWorker,
                                                                out oGraphMetricsAsObject))
            {
                // The user cancelled.

                return(false);
            }

            Debug.Assert(oGraphMetricsAsObject is Dictionary <Int32, Double>);

            Dictionary <Int32, Double> oGraphMetrics =
                (Dictionary <Int32, Double>)oGraphMetricsAsObject;

            // Transfer the graph metrics to an array of GraphMetricValue objects.

            List <GraphMetricValueWithID> oGraphMetricValues =
                new List <GraphMetricValueWithID>();

            foreach (IVertex oVertex in graph.Vertices)
            {
                // Try to get the row ID stored in the worksheet.

                Int32 iRowID;

                if (TryGetRowID(oVertex, out iRowID))
                {
                    oGraphMetricValues.Add(new GraphMetricValueWithID(
                                               iRowID, oGraphMetrics[oVertex.ID]));
                }
            }

            graphMetricColumns = new GraphMetricColumn [] {
                new GraphMetricColumnWithID(WorksheetNames.Vertices,
                                            TableNames.Vertices, columnName, columnWidthChars,
                                            NumericFormat, style, oGraphMetricValues.ToArray()
                                            )
            };

            return(true);
        }
示例#18
0
        TryCalculateGraphMetrics
        (
            IGraph graph,
            CalculateGraphMetricsContext calculateGraphMetricsContext,
            out GraphMetricColumn [] graphMetricColumns
        )
        {
            Debug.Assert(graph != null);
            Debug.Assert(calculateGraphMetricsContext != null);
            AssertValid();

            graphMetricColumns = new GraphMetricColumn[0];

            Object oGroupInformationAsObject;

            // Attempt to retrieve the group information the WorkbookReader object
            // may have stored as metadata on the graph.

            if (
                !calculateGraphMetricsContext.GraphMetricUserSettings.
                ShouldCalculateGraphMetrics(GraphMetrics.GroupMetrics)
                ||
                !graph.TryGetValue(ReservedMetadataKeys.GroupInformation,
                                   typeof(ICollection <GroupInformation>),
                                   out oGroupInformationAsObject)
                )
            {
                return(true);
            }

            // The following lists correspond to group worksheet columns.

            List <GraphMetricValueWithID> oVerticesGraphMetricValues =
                new List <GraphMetricValueWithID>();

            List <GraphMetricValueWithID> oUniqueEdgesGraphMetricValues =
                new List <GraphMetricValueWithID>();

            List <GraphMetricValueWithID> oEdgesWithDuplicatesGraphMetricValues =
                new List <GraphMetricValueWithID>();

            List <GraphMetricValueWithID> oTotalEdgesGraphMetricValues =
                new List <GraphMetricValueWithID>();

            List <GraphMetricValueWithID> oSelfLoopsGraphMetricValues =
                new List <GraphMetricValueWithID>();

            List <GraphMetricValueWithID> oConnectedComponentsGraphMetricValues =
                new List <GraphMetricValueWithID>();

            List <GraphMetricValueWithID>
            oSingleVertexConnectedComponentsGraphMetricValues =
                new List <GraphMetricValueWithID>();

            List <GraphMetricValueWithID>
            oMaximumConnectedComponentVerticesGraphMetricValues =
                new List <GraphMetricValueWithID>();

            List <GraphMetricValueWithID>
            oMaximumConnectedComponentEdgesGraphMetricValues =
                new List <GraphMetricValueWithID>();

            List <GraphMetricValueWithID> oMaximumGeodesicDistanceGraphMetricValues =
                new List <GraphMetricValueWithID>();

            List <GraphMetricValueWithID> oAverageGeodesicDistanceGraphMetricValues =
                new List <GraphMetricValueWithID>();

            List <GraphMetricValueWithID> oGraphDensityGraphMetricValues =
                new List <GraphMetricValueWithID>();

            foreach (GroupInformation oGroupInformation in
                     (ICollection <GroupInformation>)oGroupInformationAsObject)
            {
                ICollection <IVertex> oVertices = oGroupInformation.Vertices;

                if (oVertices == null || oVertices.Count == 0 ||
                    !oGroupInformation.RowID.HasValue)
                {
                    continue;
                }

                OverallMetrics oOverallMetrics;

                if (!TryCalculateGraphMetricsForOneGroup(oGroupInformation,
                                                         calculateGraphMetricsContext, out oOverallMetrics))
                {
                    // The user cancelled.

                    return(false);
                }

                Int32 iRowID = oGroupInformation.RowID.Value;

                oVerticesGraphMetricValues.Add(new GraphMetricValueWithID(
                                                   iRowID, oOverallMetrics.Vertices));

                oUniqueEdgesGraphMetricValues.Add(new GraphMetricValueWithID(
                                                      iRowID, oOverallMetrics.UniqueEdges));

                oEdgesWithDuplicatesGraphMetricValues.Add(
                    new GraphMetricValueWithID(iRowID,
                                               oOverallMetrics.EdgesWithDuplicates));

                oTotalEdgesGraphMetricValues.Add(new GraphMetricValueWithID(iRowID,
                                                                            oOverallMetrics.TotalEdges));

                oSelfLoopsGraphMetricValues.Add(new GraphMetricValueWithID(iRowID,
                                                                           oOverallMetrics.SelfLoops));

                oConnectedComponentsGraphMetricValues.Add(
                    new GraphMetricValueWithID(iRowID,
                                               oOverallMetrics.ConnectedComponents));

                oSingleVertexConnectedComponentsGraphMetricValues.Add(
                    new GraphMetricValueWithID(iRowID,
                                               oOverallMetrics.SingleVertexConnectedComponents));

                oMaximumConnectedComponentVerticesGraphMetricValues.Add(
                    new GraphMetricValueWithID(iRowID,
                                               oOverallMetrics.MaximumConnectedComponentVertices));

                oMaximumConnectedComponentEdgesGraphMetricValues.Add(
                    new GraphMetricValueWithID(iRowID,
                                               oOverallMetrics.MaximumConnectedComponentEdges));

                oMaximumGeodesicDistanceGraphMetricValues.Add(
                    new GraphMetricValueWithID(iRowID,
                                               OverallMetricCalculator2.NullableToGraphMetricValue <Int32>(
                                                   oOverallMetrics.MaximumGeodesicDistance)));

                oAverageGeodesicDistanceGraphMetricValues.Add(
                    new GraphMetricValueWithID(iRowID,
                                               OverallMetricCalculator2.NullableToGraphMetricValue <Double>(
                                                   oOverallMetrics.AverageGeodesicDistance)));

                oGraphDensityGraphMetricValues.Add(
                    new GraphMetricValueWithID(iRowID,
                                               OverallMetricCalculator2.NullableToGraphMetricValue <Double>(
                                                   oOverallMetrics.GraphDensity)));
            }

            graphMetricColumns = new GraphMetricColumn [] {
                new GraphMetricColumnWithID(WorksheetNames.Groups,
                                            TableNames.Groups, GroupTableColumnNames.Vertices,
                                            ExcelUtil.AutoColumnWidth, Int32NumericFormat,
                                            CellStyleNames.GraphMetricGood,
                                            oVerticesGraphMetricValues.ToArray()),

                new GraphMetricColumnWithID(WorksheetNames.Groups,
                                            TableNames.Groups, GroupTableColumnNames.UniqueEdges,
                                            ExcelUtil.AutoColumnWidth, Int32NumericFormat,
                                            CellStyleNames.GraphMetricGood,
                                            oUniqueEdgesGraphMetricValues.ToArray()),

                new GraphMetricColumnWithID(WorksheetNames.Groups,
                                            TableNames.Groups, GroupTableColumnNames.EdgesWithDuplicates,
                                            ExcelUtil.AutoColumnWidth, Int32NumericFormat,
                                            CellStyleNames.GraphMetricGood,
                                            oEdgesWithDuplicatesGraphMetricValues.ToArray()),

                new GraphMetricColumnWithID(WorksheetNames.Groups,
                                            TableNames.Groups, GroupTableColumnNames.TotalEdges,
                                            ExcelUtil.AutoColumnWidth, Int32NumericFormat,
                                            CellStyleNames.GraphMetricGood,
                                            oTotalEdgesGraphMetricValues.ToArray()),

                new GraphMetricColumnWithID(WorksheetNames.Groups,
                                            TableNames.Groups, GroupTableColumnNames.SelfLoops,
                                            ExcelUtil.AutoColumnWidth, Int32NumericFormat,
                                            CellStyleNames.GraphMetricGood,
                                            oSelfLoopsGraphMetricValues.ToArray()),

                new GraphMetricColumnWithID(WorksheetNames.Groups,
                                            TableNames.Groups, GroupTableColumnNames.ConnectedComponents,
                                            ExcelUtil.AutoColumnWidth, Int32NumericFormat,
                                            CellStyleNames.GraphMetricGood,
                                            oConnectedComponentsGraphMetricValues.ToArray()),

                new GraphMetricColumnWithID(WorksheetNames.Groups,
                                            TableNames.Groups,
                                            GroupTableColumnNames.SingleVertexConnectedComponents,
                                            ExcelUtil.AutoColumnWidth, Int32NumericFormat,
                                            CellStyleNames.GraphMetricGood,
                                            oSingleVertexConnectedComponentsGraphMetricValues.ToArray()),

                new GraphMetricColumnWithID(WorksheetNames.Groups,
                                            TableNames.Groups,
                                            GroupTableColumnNames.MaximumConnectedComponentVertices,
                                            ExcelUtil.AutoColumnWidth, Int32NumericFormat,
                                            CellStyleNames.GraphMetricGood,
                                            oMaximumConnectedComponentVerticesGraphMetricValues.ToArray()
                                            ),

                new GraphMetricColumnWithID(WorksheetNames.Groups,
                                            TableNames.Groups,
                                            GroupTableColumnNames.MaximumConnectedComponentEdges,
                                            ExcelUtil.AutoColumnWidth, Int32NumericFormat,
                                            CellStyleNames.GraphMetricGood,
                                            oMaximumConnectedComponentEdgesGraphMetricValues.ToArray()
                                            ),

                new GraphMetricColumnWithID(WorksheetNames.Groups,
                                            TableNames.Groups,
                                            GroupTableColumnNames.MaximumGeodesicDistance,
                                            ExcelUtil.AutoColumnWidth, Int32NumericFormat,
                                            CellStyleNames.GraphMetricGood,
                                            oMaximumGeodesicDistanceGraphMetricValues.ToArray()),

                new GraphMetricColumnWithID(WorksheetNames.Groups,
                                            TableNames.Groups,
                                            GroupTableColumnNames.AverageGeodesicDistance,
                                            ExcelUtil.AutoColumnWidth, DoubleNumericFormat,
                                            CellStyleNames.GraphMetricGood,
                                            oAverageGeodesicDistanceGraphMetricValues.ToArray()),

                new GraphMetricColumnWithID(WorksheetNames.Groups,
                                            TableNames.Groups, GroupTableColumnNames.GraphDensity,
                                            ExcelUtil.AutoColumnWidth, DoubleNumericFormat,
                                            CellStyleNames.GraphMetricGood,
                                            oGraphDensityGraphMetricValues.ToArray()),
            };

            return(true);
        }
        CalculateGraphMetricsAsyncInternal
        (
            CalculateGraphMetricsAsyncArgs oCalculateGraphMetricsAsyncArgs,
            BackgroundWorker oBackgroundWorker,
            DoWorkEventArgs oDoWorkEventArgs
        )
        {
            Debug.Assert(oCalculateGraphMetricsAsyncArgs != null);
            Debug.Assert(oBackgroundWorker != null);
            Debug.Assert(oDoWorkEventArgs != null);
            AssertValid();

            IGraph oGraph = oCalculateGraphMetricsAsyncArgs.Graph;

            List <GraphMetricColumn> oAggregatedGraphMetricColumns =
                new List <GraphMetricColumn>();

            CalculateGraphMetricsContext oCalculateGraphMetricsContext =
                new CalculateGraphMetricsContext(
                    oCalculateGraphMetricsAsyncArgs.GraphMetricUserSettings,
                    oBackgroundWorker);

            Boolean bDuplicateEdgesRemoved = false;

            foreach (IGraphMetricCalculator2 oGraphMetricCalculator in
                     oCalculateGraphMetricsAsyncArgs.SortedGraphMetricCalculators)
            {
                if (!oGraphMetricCalculator.HandlesDuplicateEdges &&
                    !bDuplicateEdgesRemoved)
                {
                    // This and the remainder of the graph metric calculators
                    // cannot handle duplicate edges.  Remove them from the graph.

                    oGraph.Edges.RemoveDuplicates();
                    bDuplicateEdgesRemoved = true;
                }

                // Calculate the implementation's graph metrics.

                GraphMetricColumn [] aoGraphMetricColumns;

                if (!oGraphMetricCalculator.TryCalculateGraphMetrics(oGraph,
                                                                     oCalculateGraphMetricsContext, out aoGraphMetricColumns))
                {
                    // The user cancelled.

                    oDoWorkEventArgs.Cancel = true;

                    oBackgroundWorker.ReportProgress(0,
                                                     new GraphMetricProgress("Cancelled.", false)
                                                     );

                    return;
                }

                // Aggregate the results.

                Debug.Assert(aoGraphMetricColumns != null);

                oAggregatedGraphMetricColumns.AddRange(aoGraphMetricColumns);
            }

            oDoWorkEventArgs.Result = oAggregatedGraphMetricColumns.ToArray();

            oBackgroundWorker.ReportProgress(100,
                                             new GraphMetricProgress(
                                                 "Inserting metrics into the workbook.",
                                                 true)
                                             );

            // Let the dialog the display the final progress report and update its
            // controls.

            System.Threading.Thread.Sleep(1);
        }
示例#20
0
 TryCalculateGraphMetrics
 (
     IGraph graph,
     CalculateGraphMetricsContext calculateGraphMetricsContext,
     out GraphMetricColumn [] graphMetricColumns
 );
        //*************************************************************************
        //  Method: TryCalculateGraphMetrics()
        //
        /// <summary>
        /// Attempts to calculate a set of one or more related metrics.
        /// </summary>
        ///
        /// <param name="graph">
        /// The graph to calculate metrics for.  The graph may contain duplicate
        /// edges and self-loops.
        /// </param>
        ///
        /// <param name="calculateGraphMetricsContext">
        /// Provides access to objects needed for calculating graph metrics.
        /// </param>
        ///
        /// <param name="graphMetricColumns">
        /// Where an array of GraphMetricColumn objects gets stored if true is
        /// returned, one for each related metric calculated by this method.
        /// </param>
        ///
        /// <returns>
        /// true if the graph metrics were calculated or don't need to be
        /// calculated, false if the user wants to cancel.
        /// </returns>
        ///
        /// <remarks>
        /// This method periodically checks BackgroundWorker.<see
        /// cref="BackgroundWorker.CancellationPending" />.  If true, the method
        /// immediately returns false.
        ///
        /// <para>
        /// It also periodically reports progress by calling the
        /// BackgroundWorker.<see
        /// cref="BackgroundWorker.ReportProgress(Int32, Object)" /> method.  The
        /// userState argument is a <see cref="GraphMetricProgress" /> object.
        /// </para>
        ///
        /// <para>
        /// Calculated metrics for hidden rows are ignored by the caller, because
        /// Excel misbehaves when values are written to hidden cells.
        /// </para>
        ///
        /// </remarks>
        //*************************************************************************
        public override Boolean TryCalculateGraphMetrics(
            IGraph graph,
            CalculateGraphMetricsContext calculateGraphMetricsContext,
            out GraphMetricColumn [] graphMetricColumns
            )
        {
            Debug.Assert(graph != null);
            Debug.Assert(calculateGraphMetricsContext != null);
            AssertValid();

            graphMetricColumns = new GraphMetricColumn[0];

            GraphMetricUserSettings oGraphMetricUserSettings =
            calculateGraphMetricsContext.GraphMetricUserSettings;

            if ( !oGraphMetricUserSettings.ShouldCalculateGraphMetrics(
                GraphMetrics.Degree |
                GraphMetrics.InDegree |
                GraphMetrics.OutDegree
            ) )
            {
            return (true);
            }

            IVertexCollection oVertices = graph.Vertices;
            Int32 iVertices = oVertices.Count;

            // The following lists correspond to vertex worksheet columns.

            List<GraphMetricValueWithID> oInDegreeGraphMetricValues =
            new List<GraphMetricValueWithID>();

            List<GraphMetricValueWithID> oOutDegreeGraphMetricValues =
            new List<GraphMetricValueWithID>();

            List<GraphMetricValueWithID> oDegreeGraphMetricValues =
            new List<GraphMetricValueWithID>();

            // Create a dictionary to keep track of vertex degrees.  The key is the
            // IVertex.ID and the value is a zero-based index into the above lists.

            Dictionary<Int32, Int32> oVertexIDDictionary =
            new Dictionary<Int32, Int32>();

            // Calculate the degrees for each vertex using the
            // VertexDegreeCalculator class in the Algorithms namespace, which
            // knows nothing about Excel.
            //
            // For simplicity, all degree metrics (in-degree, out-degree, and
            // degree) are calculated regardless of whether the graph is directed
            // or undirected.  After all metrics are calculated,
            // FilterGraphMetricColumns() filters out the metrics that don't apply
            // to the graph, based on its directedness.

            Dictionary<Int32, VertexDegrees> oVertexDegreeDictionary;

            if ( !( new Algorithms.VertexDegreeCalculator() ).
            TryCalculateGraphMetrics(graph,
                calculateGraphMetricsContext.BackgroundWorker,
                out oVertexDegreeDictionary) )
            {
            // The user cancelled.

            return (false);
            }

            Int32 iRowID;

            foreach (IVertex oVertex in oVertices)
            {
            if ( !TryGetRowID(oVertex, out iRowID) )
            {
                continue;
            }

            VertexDegrees oVertexDegrees;

            if ( !oVertexDegreeDictionary.TryGetValue(oVertex.ID,
                out oVertexDegrees) )
            {
                Debug.Assert(false);
            }

            oInDegreeGraphMetricValues.Add(new GraphMetricValueWithID(
                iRowID, oVertexDegrees.InDegree) );

            oOutDegreeGraphMetricValues.Add(new GraphMetricValueWithID(
                iRowID, oVertexDegrees.OutDegree) );

            oDegreeGraphMetricValues.Add(new GraphMetricValueWithID(
                iRowID, oVertexDegrees.Degree) );

            Debug.Assert(oInDegreeGraphMetricValues.Count ==
                oOutDegreeGraphMetricValues.Count);

            oVertexIDDictionary.Add(oVertex.ID,
                oInDegreeGraphMetricValues.Count - 1);
            }

            // Figure out which columns to add.

            graphMetricColumns = FilterGraphMetricColumns(graph,
            calculateGraphMetricsContext, oInDegreeGraphMetricValues,
            oOutDegreeGraphMetricValues, oDegreeGraphMetricValues);

            return (true);
        }