//************************************************************************* // Constructor: ReadabilityMetricsDialog() // /// <summary> /// Initializes a new instance of the <see /// cref="ReadabilityMetricsDialog" /> class. /// </summary> /// /// <param name="nodeXLControl"> /// NodeXLControl containing the graph. /// </param> /// /// <param name="workbook"> /// Workbook containing the graph data. /// </param> //************************************************************************* public ReadabilityMetricsDialog ( NodeXLControl nodeXLControl, Microsoft.Office.Interop.Excel.Workbook workbook ) { InitializeComponent(); m_oNodeXLControl = nodeXLControl; m_oWorkbook = workbook; m_oReadabilityMetricUserSettings = new ReadabilityMetricUserSettings(); // Instantiate an object that saves and retrieves the user settings for // this dialog. Note that the object automatically saves the settings // when the form closes. m_oReadabilityMetricsDialogUserSettings = new ReadabilityMetricsDialogUserSettings(this); DoDataExchange(false); m_oNodeXLControl.VerticesMoved += new VerticesMovedEventHandler(this.OnVerticesMoved); m_oNodeXLControl.GraphLaidOut += new AsyncCompletedEventHandler(this.OnGraphLaidOut); AssertValid(); }
TryCalculatePerEdgeAndPerVertexMetrics ( IGraph oGraphClone, IGraph oGraph, ReadabilityMetricUserSettings oReadabilityMetricUserSettings, BackgroundWorker oBackgroundWorker, Dictionary<IEdge, Int32> oEdgeInformation, Dictionary<IVertex, VertexInformation> oVertexInformations, LinkedList<GraphMetricColumn> oGraphMetricColumns ) { Debug.Assert(oGraphClone != null); Debug.Assert(oGraph != null); Debug.Assert(oReadabilityMetricUserSettings != null); Debug.Assert(oBackgroundWorker != null); Debug.Assert(oEdgeInformation != null); Debug.Assert(oVertexInformations != null); Debug.Assert(oGraphMetricColumns != null); AssertValid(); ICollection<GraphMetricValueWithID> oGraphMetricValuesWithID; if ( oReadabilityMetricUserSettings.ShouldCalculateReadabilityMetrics( ReadabilityMetrics.PerEdgeEdgeCrossings) ) { if ( !TryCalculatePerEdgeEdgeCrossings(oGraphClone, oGraph, oBackgroundWorker, oEdgeInformation, out oGraphMetricValuesWithID) ) { return (false); } oGraphMetricColumns.AddLast( new GraphMetricColumnWithID( WorksheetNames.Edges, TableNames.Edges, EdgeTableColumnNames.EdgeCrossings, ExcelTableUtil.AutoColumnWidth, NumericFormat, CellStyleNames.GraphMetricGood, oGraphMetricValuesWithID.ToArray() ) ); } if ( oReadabilityMetricUserSettings.ShouldCalculateReadabilityMetrics( ReadabilityMetrics.PerVertexEdgeCrossings) ) { if ( !TryCalculatePerVertexEdgeCrossings(oGraphClone, oBackgroundWorker, oEdgeInformation, oVertexInformations, out oGraphMetricValuesWithID) ) { return (false); } oGraphMetricColumns.AddLast( new GraphMetricColumnWithID( WorksheetNames.Vertices, TableNames.Vertices, VertexTableColumnNames.EdgeCrossings, ExcelTableUtil.AutoColumnWidth, NumericFormat, CellStyleNames.GraphMetricGood, oGraphMetricValuesWithID.ToArray() ) ); } if ( oReadabilityMetricUserSettings.ShouldCalculateReadabilityMetrics( ReadabilityMetrics.PerVertexVertexOverlap) ) { if ( !TryCalculatePerVertexVertexOverlap(oGraphClone, oBackgroundWorker, oVertexInformations, out oGraphMetricValuesWithID) ) { return (false); } oGraphMetricColumns.AddLast( new GraphMetricColumnWithID( WorksheetNames.Vertices, TableNames.Vertices, VertexTableColumnNames.VertexOverlap, ExcelTableUtil.AutoColumnWidth, NumericFormat, CellStyleNames.GraphMetricGood, oGraphMetricValuesWithID.ToArray() ) ); } return (true); }
TryCalculateGraphMetrics ( IGraph graph, CalculateGraphMetricsContext calculateGraphMetricsContext, out GraphMetricColumn [] graphMetricColumns ) { Debug.Assert(graph != null); Debug.Assert(calculateGraphMetricsContext != null); AssertValid(); graphMetricColumns = new GraphMetricColumn[0]; BackgroundWorker oBackgroundWorker = calculateGraphMetricsContext.BackgroundWorker; ReadabilityMetricUserSettings oReadabilityMetricUserSettings = new ReadabilityMetricUserSettings(); IGraph oGraphClone = CloneAndFilterGraph(graph); // The key is an IEdge and the value is the number of edges that cross // the edge. Dictionary<IEdge, Int32> oEdgeInformation; // The key is an IVertex and the value is a VertexInformation object. Dictionary<IVertex, VertexInformation> oVertexInformations; // Future improvement: Calculate edge and vertex information only when // necessary, based on the metrics selected by the user. LinkedList<GraphMetricColumn> oGraphMetricColumns = new LinkedList<GraphMetricColumn>(); if ( !TryCalculateEdgeInformation(oGraphClone, oBackgroundWorker, out oEdgeInformation) || !TryCalculateVertexInformations(oGraphClone, oBackgroundWorker, out oVertexInformations) || !TryCalculatePerEdgeAndPerVertexMetrics(oGraphClone, graph, oReadabilityMetricUserSettings, oBackgroundWorker, oEdgeInformation, oVertexInformations, oGraphMetricColumns) || !TryCalculateOverallMetrics(oGraphClone, oReadabilityMetricUserSettings, oBackgroundWorker, oEdgeInformation, oVertexInformations, oGraphMetricColumns) ) { // The user cancelled. return (false); } graphMetricColumns = oGraphMetricColumns.ToArray(); return (true); }
TryCalculateOverallMetrics ( IGraph oGraphClone, ReadabilityMetricUserSettings oReadabilityMetricUserSettings, BackgroundWorker oBackgroundWorker, Dictionary<IEdge, Int32> oEdgeInformation, Dictionary<IVertex, VertexInformation> oVertexInformations, LinkedList<GraphMetricColumn> oGraphMetricColumns ) { AssertValid(); Boolean bCalculateOverallEdgeCrossings = oReadabilityMetricUserSettings.ShouldCalculateReadabilityMetrics( ReadabilityMetrics.OverallEdgeCrossings); Boolean bCalculateOverallVertexOverlap = oReadabilityMetricUserSettings.ShouldCalculateReadabilityMetrics( ReadabilityMetrics.OverallVertexOverlap); Boolean bCalculateGraphRectangleCoverage = oReadabilityMetricUserSettings.ShouldCalculateReadabilityMetrics( ReadabilityMetrics.GraphRectangleCoverage); if (!bCalculateOverallEdgeCrossings && !bCalculateOverallVertexOverlap && !bCalculateGraphRectangleCoverage) { return (true); } Nullable<Double> dOverallEdgeCrossings = null; Nullable<Double> dOverallVertexOverlap = null; Nullable<Double> dGraphRectangleCoverage = null; if ( ( bCalculateOverallEdgeCrossings && !TryCalculateOverallEdgeCrossings(oGraphClone, oBackgroundWorker, oEdgeInformation, oVertexInformations, out dOverallEdgeCrossings) ) || ( bCalculateOverallVertexOverlap && !TryCalculateOverallVertexOverlap(oGraphClone, oBackgroundWorker, oVertexInformations, out dOverallVertexOverlap) ) || ( bCalculateGraphRectangleCoverage && !TryCalculateGraphRectangleCoverage(oGraphClone, oBackgroundWorker, oVertexInformations, out dGraphRectangleCoverage) ) ) { // The user cancelled. return (false); } // Known problem: // // The following code will calculate either or both of the two overall // readability metrics, depending on the user's settings. If it // doesn't calculate one of them, it writes an empty string to the // corresponding value cell in the OverallReadabilityMetrics table // instead of leaving any existing value untouched. // // This differs from what occurs when other readability metrics don't // get calculated. In the other cases, any metrics that have already // been calculated do not get overwritten. // // Fixing this will require modifying the way that // GraphMetricColumnOrdered objects get written to the workbook by // GraphMetricWriter.WriteGraphMetricColumnOrderedToWorkbook(). oGraphMetricColumns.AddLast( new GraphMetricColumnOrdered( WorksheetNames.OverallMetrics, TableNames.OverallReadabilityMetrics, OverallReadabilityMetricsTableColumnNames.Name, ExcelTableUtil.AutoColumnWidth, null, CellStyleNames.GraphMetricGood, new GraphMetricValueOrdered [] { new GraphMetricValueOrdered("Edge Crossing Readability"), new GraphMetricValueOrdered("Vertex Overlap Readability"), new GraphMetricValueOrdered("Graph Pane Coverage"), } ) ); oGraphMetricColumns.AddLast( new GraphMetricColumnOrdered(WorksheetNames.OverallMetrics, TableNames.OverallReadabilityMetrics, OverallReadabilityMetricsTableColumnNames.Value, ExcelTableUtil.AutoColumnWidth, NumericFormat, CellStyleNames.GraphMetricGood, new GraphMetricValueOrdered [] { new GraphMetricValueOrdered( bCalculateOverallEdgeCrossings ? NullableToGraphMetricValue<Double>( dOverallEdgeCrossings) : String.Empty), new GraphMetricValueOrdered( bCalculateOverallVertexOverlap ? NullableToGraphMetricValue<Double>( dOverallVertexOverlap) : String.Empty), new GraphMetricValueOrdered( bCalculateGraphRectangleCoverage ? NullableToGraphMetricValue<Double>( dGraphRectangleCoverage) : String.Empty), } ) ); return (true); }