Example #1
0
 /// <summary>
 /// Copy Constructor
 /// </summary>
 public CrosstabParameters(CrosstabParameters parameters)
     : base(parameters)
 {
     TreatOutcomeAsContinuous = parameters.TreatOutcomeAsContinuous;
     StrataSummaryOnly        = parameters.StrataSummaryOnly;
     SmartTable               = parameters.SmartTable;
     ShowPercents             = parameters.ShowPercents;
     UsePromptsForColumnNames = parameters.UsePromptsForColumnNames;//EI-83
     YesValues = new List <string>();
     foreach (string YVal in parameters.YesValues)
     {
         YesValues.Add(YVal);
     }
     NoValues = new List <string>();
     foreach (string NVal in parameters.NoValues)
     {
         NoValues.Add(NVal);
     }
     HorizontalDisplayMode = parameters.HorizontalDisplayMode;
     MaxColumnNameLength   = parameters.MaxColumnNameLength;
     ConditionalShading    = parameters.ConditionalShading;
     LoColorFill           = parameters.LoColorFill;
     HiColorFill           = parameters.HiColorFill;
     BreakType             = parameters.BreakType;
     Break1       = parameters.Break1;
     Break2       = parameters.Break2;
     Break3       = parameters.Break3;
     Break4       = parameters.Break4;
     Break5       = parameters.Break5;
     DisplayChiSq = parameters.DisplayChiSq; //EI-146
     OutcomeSwap  = parameters.OutcomeSwap;
     ExposureSwap = parameters.ExposureSwap;
 }
 /// <summary>
 /// Copy Constructor
 /// </summary>
 public CrosstabParameters(CrosstabParameters parameters)
     : base(parameters)
 {
     TreatOutcomeAsContinuous = parameters.TreatOutcomeAsContinuous;
     StrataSummaryOnly = parameters.StrataSummaryOnly;
     SmartTable = parameters.SmartTable;
     ShowPercents = parameters.ShowPercents;
     UsePromptsForColumnNames = parameters.UsePromptsForColumnNames;//EI-83
     YesValues = new List<string>();
     foreach (string YVal in parameters.YesValues)
     {
         YesValues.Add(YVal);
     }
     NoValues = new List<string>();
     foreach (string NVal in parameters.NoValues)
     {
         NoValues.Add(NVal);
     }
     HorizontalDisplayMode = parameters.HorizontalDisplayMode;
     MaxColumnNameLength = parameters.MaxColumnNameLength;
     ConditionalShading = parameters.ConditionalShading;
     LoColorFill = parameters.LoColorFill;
     HiColorFill = parameters.HiColorFill;
     BreakType = parameters.BreakType;
     Break1 = parameters.Break1;
     Break2 = parameters.Break2;
     Break3 = parameters.Break3;
     Break4 = parameters.Break4;
     Break5 = parameters.Break5;
     DisplayChiSq = parameters.DisplayChiSq; //EI-146
 }
        public CrosstabProperties(
            DashboardHelper dashboardHelper, 
            IGadget gadget, 
            CrosstabParameters parameters, 
            List<Grid> strataGridList
            )
        {
            InitializeComponent();
            this.DashboardHelper = dashboardHelper;
            this.Gadget = gadget;
            this.Parameters = parameters;
            this.StrataGridList = strataGridList;

            List<string> fields = new List<string>();
            List<string> weightFields = new List<string>();
            List<string> strataItems = new List<string>();

            //Variable fields
            fields.Add(String.Empty);
            ColumnDataType columnDataType = ColumnDataType.Boolean | ColumnDataType.DateTime | ColumnDataType.Numeric | ColumnDataType.Text | ColumnDataType.UserDefined;
            foreach (string fieldName in DashboardHelper.GetFieldsAsList(columnDataType))
            {
                if (DashboardHelper.IsUsingEpiProject)
                {
                    if (!(fieldName == "RecStatus"))
                        fields.Add(fieldName);
                }
                else
                {
                    fields.Add(fieldName);
                }
            }

            if (fields.Contains("SYSTEMDATE"))
            {
                fields.Remove("SYSTEMDATE");
            }

            //Weight Fields
            weightFields.Add(String.Empty);
            columnDataType = ColumnDataType.Numeric | ColumnDataType.UserDefined;
            foreach (string fieldName in DashboardHelper.GetFieldsAsList(columnDataType))
            {
                if (DashboardHelper.IsUsingEpiProject)
                {
                    if (!(fieldName == "RecStatus")) weightFields.Add(fieldName);
                }
                else
                {
                    weightFields.Add(fieldName);
                }
            }
            weightFields.Sort();

            //Strata Fields
            strataItems.Add(String.Empty);
            columnDataType = ColumnDataType.Numeric | ColumnDataType.Boolean | ColumnDataType.Text | ColumnDataType.UserDefined;
            foreach (string fieldName in DashboardHelper.GetFieldsAsList(columnDataType))
            {
                if (DashboardHelper.IsUsingEpiProject)
                {
                    if (!(fieldName == "RecStatus" || fieldName == "FKEY" || fieldName == "GlobalRecordId")) strataItems.Add(fieldName);
                }
                else
                {
                    strataItems.Add(fieldName);
                }
            }

            if (DashboardHelper.IsUsingEpiProject)
            {
                if (fields.Contains("RecStatus")) fields.Remove("RecStatus");
                if (weightFields.Contains("RecStatus")) weightFields.Remove("RecStatus");

                if (strataItems.Contains("RecStatus")) strataItems.Remove("RecStatus");
                if (strataItems.Contains("FKEY")) strataItems.Remove("FKEY");
                if (strataItems.Contains("GlobalRecordId")) strataItems.Remove("GlobalRecordId");
            }

            List<string> allFieldNames = new List<string>();
            allFieldNames.AddRange(fields);
            allFieldNames.AddRange(DashboardHelper.GetAllGroupsAsList());

            cbxExposureField.ItemsSource = allFieldNames;
            cbxOutcomeField.ItemsSource = fields;
            cbxFieldWeight.ItemsSource = weightFields;
            lbxFieldStrata.ItemsSource = strataItems;

            if (cbxExposureField.Items.Count > 0)
            {
                cbxExposureField.SelectedIndex = -1;
                cbxOutcomeField.SelectedIndex = -1;
            }

            if (cbxFieldWeight.Items.Count > 0)
            {
                cbxFieldWeight.SelectedIndex = -1;
            }

            CollectionView view = (CollectionView)CollectionViewSource.GetDefaultView(cbxExposureField.ItemsSource);
            PropertyGroupDescription groupDescription = new PropertyGroupDescription("VariableCategory");
            view.GroupDescriptions.Add(groupDescription);

            RowFilterControl = new RowFilterControl(this.DashboardHelper, Dialogs.FilterDialogMode.ConditionalMode, (gadget as CrosstabControl).DataFilters, true);
            RowFilterControl.HorizontalAlignment = System.Windows.HorizontalAlignment.Left;
            panelFilters.Children.Add(RowFilterControl);

            txtMaxColumnLength.PreviewKeyDown += new KeyEventHandler(txtInput_PositiveIntegerOnly_PreviewKeyDown);

            #region Translation

            //lblConfigExpandedTitle.Content = DashboardSharedStrings.GADGET_CONFIG_TITLE_FREQUENCY;
            ////expanderAdvancedOptions.Header = DashboardSharedStrings.GADGET_ADVANCED_OPTIONS;
            ////expanderDisplayOptions.Header = DashboardSharedStrings.GADGET_DISPLAY_OPTIONS;
            //tblockMainVariable.Text = DashboardSharedStrings.GADGET_FREQUENCY_VARIABLE;
            //tblockStrataVariable.Text = DashboardSharedStrings.GADGET_STRATA_VARIABLE;
            //tblockWeightVariable.Text = DashboardSharedStrings.GADGET_WEIGHT_VARIABLE;

            ////checkboxAllValues.Content = DashboardSharedStrings.GADGET_ALL_LIST_VALUES;
            ////checkboxCommentLegalLabels.Content = DashboardSharedStrings.GADGET_LIST_LABELS;
            //checkboxIncludeMissing.Content = DashboardSharedStrings.GADGET_INCLUDE_MISSING;

            //checkboxSortHighLow.Content = DashboardSharedStrings.GADGET_SORT_HI_LOW;
            //checkboxUsePrompts.Content = DashboardSharedStrings.GADGET_USE_FIELD_PROMPT;
            ////tblockOutputColumns.Text = DashboardSharedStrings.GADGET_OUTPUT_COLUMNS_DISPLAY;
            ////tblockPrecision.Text = DashboardSharedStrings.GADGET_DECIMALS_TO_DISPLAY;

            //tblockRows.Text = DashboardSharedStrings.GADGET_MAX_ROWS_TO_DISPLAY;
            //tblockBarWidth.Text = DashboardSharedStrings.GADGET_MAX_PERCENT_BAR_WIDTH;

            ////btnRun.Content = DashboardSharedStrings.GADGET_RUN_BUTTON;
            #endregion // Translation
        }
        protected override void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            lock (syncLock)
            {
                //Dictionary<string, string> inputVariableList = ((GadgetParameters)e.Argument).InputVariableList;

                //Stopwatch stopwatch = new Stopwatch();
                //stopwatch.Start();

                CrosstabParameters crosstabParameters = (CrosstabParameters)Parameters;

                this.Dispatcher.BeginInvoke(new SimpleCallback(SetGadgetToProcessingState));
                this.Dispatcher.BeginInvoke(new SimpleCallback(ClearResults));

                AddFreqGridDelegate addGrid = new AddFreqGridDelegate(AddFreqGrid);
                SetGridTextDelegate setText = new SetGridTextDelegate(SetGridText);
                AddGridRowDelegate addRow = new AddGridRowDelegate(AddGridRow);
                RenderFrequencyHeaderDelegate renderHeader = new RenderFrequencyHeaderDelegate(RenderFrequencyHeader);
                DrawFrequencyBordersDelegate drawBorders = new DrawFrequencyBordersDelegate(DrawOutputGridBorders);

                string freqVar = string.Empty;
                string weightVar = string.Empty;
                string strataVar = string.Empty;
                List<string> stratas = new List<string>();
                string crosstabVar = string.Empty;
                bool includeMissing = false;
                bool outcomeContinuous = false;
                bool showStrataSummaryOnly = false;

                //if (inputVariableList.ContainsKey("freqvar"))
                //{
                //    freqVar = inputVariableList["freqvar"];
                //}
                if (!String.IsNullOrEmpty(crosstabParameters.ColumnNames[0]))
                    freqVar = crosstabParameters.ColumnNames[0];

                //if (inputVariableList.ContainsKey("crosstabvar"))
                //{
                //    crosstabVar = inputVariableList["crosstabvar"];
                //}
                if (!String.IsNullOrEmpty(crosstabParameters.CrosstabVariableName))
                    crosstabVar = crosstabParameters.CrosstabVariableName;

                //if (inputVariableList.ContainsKey("weightvar"))
                //{
                //    weightVar = inputVariableList["weightvar"];
                //}
                if (!String.IsNullOrEmpty(crosstabParameters.WeightVariableName))
                    weightVar = crosstabParameters.WeightVariableName;

                //if (inputVariableList.ContainsKey("stratavar"))
                //{
                //    strataVar = inputVariableList["stratavar"];
                //}
                if (crosstabParameters.StrataVariableNames.Count > 0)
                {
                    stratas = crosstabParameters.StrataVariableNames;
                }

                //if (inputVariableList.ContainsKey("includemissing"))
                //{
                //    if (inputVariableList["includemissing"].Equals("true"))
                //    {
                //        includeMissing = true;
                //    }
                //}
                includeMissing = crosstabParameters.IncludeMissing;

                //if (inputVariableList.ContainsKey("stratasummaryonly"))
                //{
                //    if (inputVariableList["stratasummaryonly"].Equals("true"))
                //    {
                //        showStrataSummaryOnly = true;
                //    }
                //}
                showStrataSummaryOnly = crosstabParameters.StrataSummaryOnly;

                //if (inputVariableList.ContainsKey("treatoutcomeascontinuous"))
                //{
                //    if (inputVariableList["treatoutcomeascontinuous"].Equals("true"))
                //    {
                //        outcomeContinuous = true;
                //    }
                //}
                outcomeContinuous = crosstabParameters.TreatOutcomeAsContinuous;

                //List<string> stratas = new List<string>();
                //if (!string.IsNullOrEmpty(strataVar))
                //{
                //    stratas.Add(strataVar);
                //}

                try
                {
                    crosstabParameters.GadgetStatusUpdate += new GadgetStatusUpdateHandler(requestUpdateStatus);
                    crosstabParameters.GadgetCheckForCancellation += new GadgetCheckForCancellationHandler(checkForCancellation);

                    if (this.DataFilters != null && this.DataFilters.Count > 0)
                    {
                        //GadgetOptions.CustomFilter = this.DataFilters.GenerateDataFilterString(false);
                        crosstabParameters.CustomFilter = this.DataFilters.GenerateDataFilterString(false);
                    }
                    else
                    {
                        crosstabParameters.CustomFilter = string.Empty;
                    }

                    bool runGroup = false;

                    Dictionary<DataTable, List<DescriptiveStatistics>> stratifiedFrequencyTables = new Dictionary<DataTable, List<DescriptiveStatistics>>();

                    List<string> allGroupFields = DashboardHelper.GetAllGroupsAsList();

                    //if (GadgetOptions.MainVariableNames != null && GadgetOptions.MainVariableNames.Count > 0)
                    if (crosstabParameters.ColumnNames[0] != null && crosstabParameters.ColumnNames.Count > 0 &&
                        !(allGroupFields.Contains(crosstabParameters.ColumnNames[0])))
                    {
                        Dictionary<DataTable, List<DescriptiveStatistics>> grpTables = new Dictionary<DataTable, List<DescriptiveStatistics>>();
                        CrosstabParameters newOptions = new CrosstabParameters(crosstabParameters);

                        foreach (string mainVariableName in crosstabParameters.ColumnNames)
                        {
                            //GadgetParameters newOptions = new GadgetParameters(GadgetOptions);
                            //CrosstabParameters newOptions = new CrosstabParameters(crosstabParameters);
                            //newOptions.MainVariableNames = null;
                            //newOptions.MainVariableName = mainVariableName;
                            //newOptions.ColumnNames[0] = null;
                            //newOptions.ColumnNames[0] = mainVariableName;

                            grpTables = DashboardHelper.GenerateFrequencyTable(newOptions);

                            foreach (KeyValuePair<DataTable, List<DescriptiveStatistics>> kvp in grpTables)
                            {
                                stratifiedFrequencyTables.Add(kvp.Key, kvp.Value);
                            }
                        }
                        //grpTables = DashboardHelper.GenerateFrequencyTable(newOptions);

                        //foreach (KeyValuePair<DataTable, List<DescriptiveStatistics>> kvp in grpTables)
                        //{
                        //    stratifiedFrequencyTables.Add(kvp.Key, kvp.Value);
                        //}
                        runGroup = true;
                    }
                    //                  else if (allGroupFields.Contains(GadgetOptions.MainVariableName))
                    else if (allGroupFields.Contains(crosstabParameters.ColumnNames[0]))
                    {
                        Dictionary<DataTable, List<DescriptiveStatistics>> grpTables = new Dictionary<DataTable, List<DescriptiveStatistics>>();

                        //foreach (string variableName in DashboardHelper.GetVariablesInGroup(GadgetOptions.MainVariableName))
                        foreach (string variableName in DashboardHelper.GetVariablesInGroup(crosstabParameters.ColumnNames[0]))
                        {
                            if (!allGroupFields.Contains(variableName) && DashboardHelper.TableColumnNames.ContainsKey(variableName))
                            {
                                //                              GadgetParameters newOptions = new GadgetParameters(GadgetOptions);
                                CrosstabParameters newOptions = new CrosstabParameters(crosstabParameters);
                                //newOptions.MainVariableNames = null;
                                //newOptions.MainVariableName = variableName;
                                newOptions.ColumnNames[0] = null;
                                newOptions.ColumnNames[0] = variableName;

                                grpTables = DashboardHelper.GenerateFrequencyTable(newOptions);

                                foreach (KeyValuePair<DataTable, List<DescriptiveStatistics>> kvp in grpTables)
                                {
                                    stratifiedFrequencyTables.Add(kvp.Key, kvp.Value);
                                }
                            }
                        }
                        runGroup = true;
                    }
                    else
                    {
                        //                      stratifiedFrequencyTables = DashboardHelper.GenerateFrequencyTable(GadgetOptions/*, freqVar, weightVar, stratas, crosstabVar, useAllPossibleValues, sortHighLow, includeMissing, false*/);
                        stratifiedFrequencyTables = DashboardHelper.GenerateFrequencyTable(crosstabParameters/*, freqVar, weightVar, stratas, crosstabVar, useAllPossibleValues, sortHighLow, includeMissing, false*/);
                        runGroup = false;
                    }

                    if (runGroup) showStrataSummaryOnly = false;

                    if (stratifiedFrequencyTables == null || stratifiedFrequencyTables.Count == 0)
                    {
                        this.Dispatcher.BeginInvoke(new RenderFinishWithErrorDelegate(RenderFinishWithError), DashboardSharedStrings.GADGET_MSG_NO_DATA);
                        this.Dispatcher.BeginInvoke(new SimpleCallback(SetGadgetToFinishedState));
                        return;
                    }
                    else if (worker.CancellationPending)
                    {
                        this.Dispatcher.BeginInvoke(new RenderFinishWithErrorDelegate(RenderFinishWithError), SharedStrings.DASHBOARD_GADGET_STATUS_OPERATION_CANCELLED);
                        this.Dispatcher.BeginInvoke(new SimpleCallback(SetGadgetToFinishedState));
                        //Debug.Print("Thread cancelled");
                        return;
                    }
                    else
                    {
                        string formatString = string.Empty;

                        foreach (KeyValuePair<DataTable, List<DescriptiveStatistics>> tableKvp in stratifiedFrequencyTables)
                        {
                            CreateSmartTable(tableKvp.Key);

                            string strataValue = tableKvp.Key.TableName;

                            double count = 0;
                            foreach (DescriptiveStatistics ds in tableKvp.Value)
                            {
                                count = count + ds.observations;
                            }

                            if (count == 0 && stratifiedFrequencyTables.Count == 1)
                            {
                                // this is the only table and there are no records, so let the user know
                                this.Dispatcher.BeginInvoke(new RenderFinishWithErrorDelegate(RenderFinishWithError), SharedStrings.NO_RECORDS_SELECTED);
                                this.Dispatcher.BeginInvoke(new SimpleCallback(SetGadgetToFinishedState));
                                return;
                            }
                            else if (count == 0)
                            {
                                continue;
                            }
                            DataTable frequencies = tableKvp.Key;

                            if (YesValues.Count > 0 && NoValues.Count > 0)
                            {
                                frequencies = ApplyRowValueMappings(frequencies);
                                frequencies = ApplyColumnValueMappings(frequencies);
                            }

                            if (frequencies.Rows.Count == 0)
                            {
                                continue;
                            }

                            if (outcomeContinuous)
                            {
                                if (frequencies.Columns.Count <= 128)
                                {
                                    int min;
                                    int max;

                                    if (int.TryParse(frequencies.Columns[1].ColumnName, out min) && int.TryParse(frequencies.Columns[frequencies.Columns.Count - 1].ColumnName, out max))
                                    {
                                        bool addedColumns = false;

                                        for (int i = min; i <= max; i++)
                                        {
                                            if (!frequencies.Columns.Contains(i.ToString()))
                                            {
                                                DataColumn newColumn = new DataColumn(i.ToString(), typeof(double));
                                                newColumn.DefaultValue = 0;
                                                frequencies.Columns.Add(newColumn);
                                                addedColumns = true;
                                            }
                                        }

                                        if (addedColumns)
                                        {
                                            int ordinal = 1;
                                            for (int i = min; i <= max; i++)
                                            {
                                                if (frequencies.Columns.Contains(i.ToString()))
                                                {
                                                    frequencies.Columns[i.ToString()].SetOrdinal(ordinal);
                                                    ordinal++;
                                                }
                                            }
                                        }
                                    }
                                }
                            }

                            this.Dispatcher.BeginInvoke(addGrid, strataVar, frequencies.TableName, crosstabVar, frequencies.Columns[0].ToString(), frequencies);
                        }

                        foreach (KeyValuePair<DataTable, List<DescriptiveStatistics>> tableKvp in stratifiedFrequencyTables)
                        {
                            if (runGroup)
                            {
                                freqVar = tableKvp.Key.Columns[0].ColumnName;
                            }

                            string strataValue = tableKvp.Key.TableName;

                            double count = 0;
                            foreach (DescriptiveStatistics ds in tableKvp.Value)
                            {
                                count = count + ds.observations;
                            }

                            if (count == 0)
                            {
                                continue;
                            }
                            DataTable frequencies = tableKvp.Key;

                            if (YesValues.Count > 0 && NoValues.Count > 0)
                            {
                                frequencies = ApplyRowValueMappings(frequencies);
                                frequencies = ApplyColumnValueMappings(frequencies);
                            }

                            if (frequencies.Rows.Count == 0)
                            {
                                continue;
                            }

                            string tableHeading = frequencies.TableName;

                            if (stratifiedFrequencyTables.Count > 1)
                            {
                                tableHeading = freqVar;
                            }

                            this.Dispatcher.BeginInvoke(renderHeader, strataValue, tableHeading, frequencies.Columns);

                            rowCount = 1;

                            int[] totals = new int[frequencies.Columns.Count - 1];
                            columnCount = 1;

                            DataRow[] SortedRows = new DataRow[frequencies.Rows.Count];
                            int rowcounter = 0;
                            foreach (System.Data.DataRow row in frequencies.Rows)
                            {
                                SortedRows[rowcounter++] = row;
                                if (!row[freqVar].Equals(DBNull.Value) || (row[freqVar].Equals(DBNull.Value) && includeMissing == true))
                                {
                                    this.Dispatcher.Invoke(addRow, strataValue, -1);
                                    string displayValue = row[freqVar].ToString();

                                    if (DashboardHelper.IsUserDefinedColumn(freqVar))
                                    {
                                        displayValue = DashboardHelper.GetFormattedOutput(freqVar, row[freqVar]);
                                    }
                                    else
                                    {
                                        if (DashboardHelper.IsUsingEpiProject && View.Fields[freqVar] is YesNoField)
                                        {
                                            if (row[freqVar].ToString().Equals("1"))
                                                displayValue = "Yes";
                                            else if (row[freqVar].ToString().Equals("0"))
                                                displayValue = "No";
                                        }
                                        else if (DashboardHelper.IsUsingEpiProject && View.Fields[freqVar] is DateField)
                                        {
                                            displayValue = string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0:d}", row[freqVar]);
                                        }
                                        else if (DashboardHelper.IsUsingEpiProject && View.Fields[freqVar] is TimeField)
                                        {
                                            displayValue = string.Format(System.Globalization.CultureInfo.CurrentCulture, "{0:T}", row[freqVar]);
                                        }
                                        else
                                        {
                                            displayValue = DashboardHelper.GetFormattedOutput(freqVar, row[freqVar]);
                                        }
                                    }

                                    if (string.IsNullOrEmpty(displayValue))
                                    {
                                        Configuration config = DashboardHelper.Config;
                                        displayValue = config.Settings.RepresentationOfMissing;
                                    }

                                    this.Dispatcher.BeginInvoke(setText, strataValue, new TextBlockConfig(displayValue, new Thickness(4, 0, 4, 0), VerticalAlignment.Center, HorizontalAlignment.Left, TextAlignment.Left, rowCount, 0, System.Windows.Visibility.Visible), FontWeights.Normal, count);

                                    int rowTotal = 0;
                                    columnCount = 1;

                                    foreach (DataColumn column in frequencies.Columns)
                                    {
                                        if (column.ColumnName.Equals(freqVar))
                                        {
                                            continue;
                                        }

                                        this.Dispatcher.BeginInvoke(setText, strataValue, new TextBlockConfig(row[column.ColumnName].ToString(), new Thickness(4, 0, 4, 0), VerticalAlignment.Center, HorizontalAlignment.Right, TextAlignment.Right, rowCount, columnCount, System.Windows.Visibility.Visible), FontWeights.Normal, count);
                                        columnCount++;

                                        int rowValue = 0;
                                        bool success = int.TryParse(row[column.ColumnName].ToString(), out rowValue);
                                        if (success)
                                        {
                                            totals[columnCount - 2] = totals[columnCount - 2] + rowValue;
                                            rowTotal = rowTotal + rowValue;
                                        }
                                    }
                                    this.Dispatcher.BeginInvoke(setText, strataValue, new TextBlockConfig(rowTotal.ToString(), new Thickness(4, 0, 4, 0), VerticalAlignment.Center, HorizontalAlignment.Right, TextAlignment.Right, rowCount, columnCount, System.Windows.Visibility.Visible), FontWeights.Bold, count);
                                    rowCount++;
                                }
                            }

                            double[] tableChiSq = Epi.Statistics.SingleMxN.CalcChiSq(SortedRows, false);
                            double tableChiSqDF = (double)(SortedRows.Length - 1) * (SortedRows[0].ItemArray.Length - 2);
                            double tableChiSqP = Epi.Statistics.SharedResources.PValFromChiSq(tableChiSq[0], tableChiSqDF);
                            String disclaimer = "";
                            if (tableChiSq[1] == 5.0)
                                disclaimer = "An expected cell value is <5. X" + '\u00B2' + " may not be valid.";
                            if (tableChiSq[1] == 1.0)
                                disclaimer = "An expected cell value is <1. X" + '\u00B2' + " may not be valid.";

                            this.Dispatcher.BeginInvoke(new AddChiSquareDelegate(RenderChiSquare), tableChiSq[0], tableChiSqDF, tableChiSqP, disclaimer, strataValue);
                            this.Dispatcher.BeginInvoke(new AddGridFooterDelegate(RenderFrequencyFooter), strataValue, rowCount, totals);
                            this.Dispatcher.BeginInvoke(drawBorders, strataValue);
                        }
                    }

                    this.Dispatcher.BeginInvoke(new SimpleCallback(RenderFinish));
                    this.Dispatcher.BeginInvoke(new SimpleCallback(SetGadgetToFinishedState));

                    // check for existence of 2x2 table...
                    if (rowCount == 3 && columnCount == 3)
                    {
                    }

                    stratifiedFrequencyTables.Clear();
                }
                catch (Exception ex)
                {
                    this.Dispatcher.BeginInvoke(new RenderFinishWithErrorDelegate(RenderFinishWithError), ex.Message);
                    this.Dispatcher.BeginInvoke(new SimpleCallback(SetGadgetToFinishedState));
                }
                finally
                {
                    //stopwatch.Stop();
                    //Debug.Print("Crosstab gadget took " + stopwatch.Elapsed.ToString() + " seconds to complete with " + dashboardHelper.RecordCount.ToString() + " records and the following filters:");
                    //Debug.Print(dashboardHelper.DataFilters.GenerateDataFilterString());
                }
            }
        }