//************************************************************************* // Method: AddRow() // /// <summary> /// Adds a row with comments and a style to the overall metrics table. /// </summary> /// /// <param name="sMetricName"> /// Name of the metric. Can be empty but not null. /// </param> /// /// <param name="sMetricValue"> /// Value of the metric. Can be empty but not null. /// </param> /// /// <param name="sMetricComments"> /// Comments for the metric. Can be empty but not null. /// </param> /// /// <param name="sStyle"> /// Style of the row, or null to not apply a style. /// </param> /// /// <param name="oOverallMetricRows"> /// Contains the row data for the overall metrics table. /// </param> //************************************************************************* protected void AddRow( String sMetricName, String sMetricValue, String sMetricComments, String sStyle, OverallMetricRows oOverallMetricRows ) { Debug.Assert(sMetricName != null); Debug.Assert(sMetricValue != null); Debug.Assert(sMetricComments != null); Debug.Assert(oOverallMetricRows != null); AssertValid(); oOverallMetricRows.MetricNames.Add( new GraphMetricValueOrdered( sMetricName, sStyle) ); oOverallMetricRows.MetricValues.Add( new GraphMetricValueOrdered( sMetricValue, sStyle) ); oOverallMetricRows.MetricComments.Add( new GraphMetricValueOrdered( sMetricComments, sStyle) ); }
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 they // are now filled with good metric values. graphMetricColumns = new GraphMetricColumn[0]; if (!calculateGraphMetricsContext.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(OverallMetricNames.Directedness, oOverallMetrics.Directedness.ToString(), oOverallMetricRows); //********************************* // Vertex count //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.Vertices, oOverallMetrics.Vertices, oOverallMetricRows); //********************************* // Edge counts //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.UniqueEdges, oOverallMetrics.UniqueEdges, oOverallMetricRows); AddRow(OverallMetricNames.EdgesWithDuplicates, oOverallMetrics.EdgesWithDuplicates, oOverallMetricRows); AddRow(OverallMetricNames.TotalEdges, oOverallMetrics.TotalEdges, oOverallMetricRows); //********************************* // Self-loops //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.SelfLoops, oOverallMetrics.SelfLoops, oOverallMetricRows); //********************************* // Reciprocation ratios //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.ReciprocatedVertexPairRatio, NullableToGraphMetricValue <Double>( oOverallMetrics.ReciprocatedVertexPairRatio), oOverallMetricRows); AddRow(OverallMetricNames.ReciprocatedEdgeRatio, NullableToGraphMetricValue <Double>( oOverallMetrics.ReciprocatedEdgeRatio), oOverallMetricRows); //********************************* // Connected component counts //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.ConnectedComponents, oOverallMetrics.ConnectedComponents, oOverallMetricRows); AddRow(OverallMetricNames.SingleVertexConnectedComponents, oOverallMetrics.SingleVertexConnectedComponents, oOverallMetricRows); AddRow(OverallMetricNames.MaximumConnectedComponentVertices, oOverallMetrics.MaximumConnectedComponentVertices, oOverallMetricRows); AddRow(OverallMetricNames.MaximumConnectedComponentEdges, oOverallMetrics.MaximumConnectedComponentEdges, oOverallMetricRows); //********************************* // Geodesic distances //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.MaximumGeodesicDistance, NullableToGraphMetricValue <Int32>( oOverallMetrics.MaximumGeodesicDistance), oOverallMetricRows); AddRow(OverallMetricNames.AverageGeodesicDistance, NullableToGraphMetricValue <Double>( oOverallMetrics.AverageGeodesicDistance), oOverallMetricRows); //********************************* // Graph density //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.GraphDensity, NullableToGraphMetricValue <Double>(oOverallMetrics.GraphDensity), oOverallMetricRows); AddRow(OverallMetricNames.Modularity, NullableToGraphMetricValue <Double>(oOverallMetrics.Modularity), oOverallMetricRows); //********************************* // NodeXL version //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.NodeXLVersion, AssemblyUtil2.GetFileVersion(), oOverallMetricRows); graphMetricColumns = new GraphMetricColumn[] { CreateGraphMetricColumnOrdered( OverallMetricsTableColumnNames.Name, oOverallMetricRows.MetricNames), CreateGraphMetricColumnOrdered( OverallMetricsTableColumnNames.Value, oOverallMetricRows.MetricValues), }; return(true); }
//************************************************************************* // Method: AddRow() // /// <overloads> /// Adds a row to the overall metrics table. /// </overloads> /// /// <summary> /// Adds an empty row to the overall metrics table. /// </summary> /// /// <param name="oOverallMetricRows"> /// Contains the row data for the overall metrics table. /// </param> //************************************************************************* protected void AddRow( OverallMetricRows oOverallMetricRows ) { Debug.Assert(oOverallMetricRows != null); AssertValid(); AddRow(String.Empty, String.Empty, String.Empty, CellStyleNames.GraphMetricSeparatorRow, oOverallMetricRows); }
//************************************************************************* // Method: AddRow() // /// <summary> /// Adds a row to the overall metrics table. /// </summary> /// /// <param name="sMetricName"> /// Name of the metric. Can be empty but not null. /// </param> /// /// <param name="sMetricValue"> /// Value of the metric. Can be empty but not null. /// </param> /// /// <param name="oOverallMetricRows"> /// Contains the row data for the overall metrics table. /// </param> //************************************************************************* protected void AddRow( String sMetricName, String sMetricValue, OverallMetricRows oOverallMetricRows ) { Debug.Assert(sMetricName != null); Debug.Assert(sMetricValue != null); Debug.Assert(oOverallMetricRows != null); AssertValid(); AddRow(sMetricName, sMetricValue, String.Empty, null, oOverallMetricRows); }
//************************************************************************* // 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); }
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); }
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 they // are now filled with good metric values. graphMetricColumns = new GraphMetricColumn[0]; if ( !calculateGraphMetricsContext.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(OverallMetricNames.Directedness, oOverallMetrics.Directedness.ToString(), oOverallMetricRows); //********************************* // Vertex count //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.Vertices, oOverallMetrics.Vertices, oOverallMetricRows); //********************************* // Edge counts //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.UniqueEdges, oOverallMetrics.UniqueEdges, oOverallMetricRows); AddRow(OverallMetricNames.EdgesWithDuplicates, oOverallMetrics.EdgesWithDuplicates, oOverallMetricRows); AddRow(OverallMetricNames.TotalEdges, oOverallMetrics.TotalEdges, oOverallMetricRows); //********************************* // Self-loops //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.SelfLoops, oOverallMetrics.SelfLoops, oOverallMetricRows); //********************************* // Reciprocation ratios //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.ReciprocatedVertexPairRatio, NullableToGraphMetricValue<Double>( oOverallMetrics.ReciprocatedVertexPairRatio), oOverallMetricRows); AddRow(OverallMetricNames.ReciprocatedEdgeRatio, NullableToGraphMetricValue<Double>( oOverallMetrics.ReciprocatedEdgeRatio), oOverallMetricRows); //********************************* // Connected component counts //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.ConnectedComponents, oOverallMetrics.ConnectedComponents, oOverallMetricRows); AddRow(OverallMetricNames.SingleVertexConnectedComponents, oOverallMetrics.SingleVertexConnectedComponents, oOverallMetricRows); AddRow(OverallMetricNames.MaximumConnectedComponentVertices, oOverallMetrics.MaximumConnectedComponentVertices, oOverallMetricRows); AddRow(OverallMetricNames.MaximumConnectedComponentEdges, oOverallMetrics.MaximumConnectedComponentEdges, oOverallMetricRows); //********************************* // Geodesic distances //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.MaximumGeodesicDistance, NullableToGraphMetricValue<Int32>( oOverallMetrics.MaximumGeodesicDistance), oOverallMetricRows); AddRow(OverallMetricNames.AverageGeodesicDistance, NullableToGraphMetricValue<Double>( oOverallMetrics.AverageGeodesicDistance), oOverallMetricRows); //********************************* // Graph density //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.GraphDensity, NullableToGraphMetricValue<Double>(oOverallMetrics.GraphDensity), oOverallMetricRows); AddRow(OverallMetricNames.Modularity, NullableToGraphMetricValue<Double>(oOverallMetrics.Modularity), oOverallMetricRows); //********************************* // NodeXL version //********************************* AddRow(oOverallMetricRows); AddRow(OverallMetricNames.NodeXLVersion, AssemblyUtil2.GetFileVersion(), oOverallMetricRows); graphMetricColumns = new GraphMetricColumn[] { CreateGraphMetricColumnOrdered( OverallMetricsTableColumnNames.Name, oOverallMetricRows.MetricNames), CreateGraphMetricColumnOrdered( OverallMetricsTableColumnNames.Value, oOverallMetricRows.MetricValues), }; return (true); }
AddRow ( String sMetricName, Object oMetricValue, String sStyle, OverallMetricRows oOverallMetricRows ) { Debug.Assert(sMetricName != null); Debug.Assert(oMetricValue != null); Debug.Assert(oOverallMetricRows != null); AssertValid(); oOverallMetricRows.MetricNames.Add( new GraphMetricValueOrdered( sMetricName, sStyle) ); oOverallMetricRows.MetricValues.Add( new GraphMetricValueOrdered( oMetricValue, sStyle) ); }
AddRow ( String sMetricName, Object oMetricValue, OverallMetricRows oOverallMetricRows ) { Debug.Assert(sMetricName != null); Debug.Assert(oMetricValue != null); Debug.Assert(oOverallMetricRows != null); AssertValid(); AddRow(sMetricName, oMetricValue, CellStyleNames.GraphMetricGood, oOverallMetricRows); }