Files
libreoffice/sc/source/ui/StatisticsDialogs/AnalysisOfVarianceDialog.cxx
Eike Rathke 9570a27d3e resolved fdo#73555 compile statistics templates using English grammar
The statistics templates' formula expressions are setup using English
function names, so compile the resulting expressions using an English
grammar merged with the current address conventions.

Change-Id: I7c782a42d007daeaaf99463beb8aa580c05c7363
2014-01-13 18:08:52 +01:00

282 lines
9.4 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*/
#include <sfx2/dispatch.hxx>
#include <svl/zforlist.hxx>
#include <svl/undo.hxx>
#include "formulacell.hxx"
#include "rangelst.hxx"
#include "scitems.hxx"
#include "docsh.hxx"
#include "document.hxx"
#include "uiitems.hxx"
#include "reffact.hxx"
#include "strload.hxx"
#include "random.hxx"
#include "docfunc.hxx"
#include "StatisticsDialogs.hrc"
#include "TableFillingAndNavigationTools.hxx"
#include "AnalysisOfVarianceDialog.hxx"
namespace
{
static sal_Int16 lclBasicStatisticsLabels[] =
{
STR_ANOVA_LABEL_GROUPS,
STRID_CALC_COUNT,
STRID_CALC_SUM,
STRID_CALC_MEAN,
STRID_CALC_VARIANCE,
0
};
static const char* lclBasicStatisticsFormula[] =
{
"=COUNT(%RANGE%)", "=SUM(%RANGE%)", "=AVERAGE(%RANGE%)", "=VAR(%RANGE%)", NULL
};
static sal_Int16 lclAnovaLabels[] =
{
STR_ANOVA_LABEL_SOURCE_OF_VARIATION,
STR_ANOVA_LABEL_SS,
STR_ANOVA_LABEL_DF,
STR_ANOVA_LABEL_MS,
STR_ANOVA_LABEL_F,
STR_ANOVA_LABEL_P_VALUE,
STR_ANOVA_LABEL_F_CRITICAL,
0
};
static const OUString strWildcardRange("%RANGE%");
static const OUString strWildcardNumber("%NUMBER%");
OUString lclCreateMultiParameterFormula(
ScRangeList& aRangeList, const OUString& aFormulaTemplate,
const OUString& aWildcard, ScDocument* pDocument,
ScAddress::Details& aAddressDetails)
{
OUString aResult;
for (size_t i = 0; i < aRangeList.size(); i++)
{
OUString aRangeString(aRangeList[i]->Format(SCR_ABS, pDocument, aAddressDetails));
OUString aFormulaString = aFormulaTemplate.replaceAll(aWildcard, aRangeString);
aResult += aFormulaString;
if(i != aRangeList.size() - 1) // Not Last
aResult+= ";";
}
return aResult;
}
}
ScAnalysisOfVarianceDialog::ScAnalysisOfVarianceDialog(
SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow,
Window* pParent, ScViewData* pViewData ) :
ScStatisticsInputOutputDialog(
pSfxBindings, pChildWindow, pParent, pViewData,
"AnalysisOfVarianceDialog", "modules/scalc/ui/analysisofvariancedialog.ui" )
{
get(mpAlpha, "alpha-spin");
}
ScAnalysisOfVarianceDialog::~ScAnalysisOfVarianceDialog()
{}
sal_Bool ScAnalysisOfVarianceDialog::Close()
{
return DoClose( ScAnalysisOfVarianceDialogWrapper::GetChildWindowId() );
}
sal_Int16 ScAnalysisOfVarianceDialog::GetUndoNameId()
{
return STR_ANALYSIS_OF_VARIANCE_UNDO_NAME;
}
ScRange ScAnalysisOfVarianceDialog::ApplyOutput(ScDocShell* pDocShell)
{
AddressWalkerWriter output(mOutputAddress, pDocShell, mDocument,
formula::FormulaGrammar::mergeToGrammar( formula::FormulaGrammar::GRAM_ENGLISH, mAddressDetails.eConv));
FormulaTemplate aTemplate(mDocument, mAddressDetails);
output.writeBoldString(SC_STRLOAD(RID_STATISTICS_DLGS, STR_ANOVA_SINGLE_FACTOR_LABEL));
output.nextRow();
output.nextRow();
// Write labels
for(sal_Int32 i = 0; lclBasicStatisticsLabels[i] != 0; i++)
{
output.writeString(SC_STRLOAD(RID_STATISTICS_DLGS, lclBasicStatisticsLabels[i]));
output.nextColumn();
}
output.nextRow();
ScRangeList aRangeList;
boost::scoped_ptr<DataRangeIterator> pIterator;
if (mGroupedBy == BY_COLUMN)
pIterator.reset(new DataRangeByColumnIterator(mInputRange));
else
pIterator.reset(new DataRangeByRowIterator(mInputRange));
// Write statistic formulas for rows/columns
for( ; pIterator->hasNext(); pIterator->next() )
{
output.resetColumn();
if (mGroupedBy == BY_COLUMN)
aTemplate.setTemplate(SC_STRLOAD(RID_STATISTICS_DLGS, STR_COLUMN_LABEL_TEMPLATE));
else
aTemplate.setTemplate(SC_STRLOAD(RID_STATISTICS_DLGS, STR_ROW_LABEL_TEMPLATE));
aTemplate.applyNumber(strWildcardNumber, pIterator->index() + 1);
output.writeString(aTemplate.getTemplate());
output.nextColumn();
ScRange aColumnRange = pIterator->get();
aRangeList.Append(aColumnRange);
for(sal_Int32 i = 0; lclBasicStatisticsFormula[i] != NULL; i++)
{
aTemplate.setTemplate(lclBasicStatisticsFormula[i]);
aTemplate.applyRange(strWildcardRange, aColumnRange);
output.writeFormula(aTemplate.getTemplate());
output.nextColumn();
}
output.nextRow();
}
output.nextRow(); // Blank row
// Write ANOVA labels
output.resetColumn();
for(sal_Int32 i = 0; lclAnovaLabels[i] != 0; i++)
{
output.writeString(SC_STRLOAD(RID_STATISTICS_DLGS, lclAnovaLabels[i]));
output.nextColumn();
}
output.nextRow();
// Between Groups
{
// Label
output.resetColumn();
output.writeString(SC_STRLOAD(RID_STATISTICS_DLGS, STR_ANOVA_LABEL_BETWEEN_GROUPS));
output.nextColumn();
// Sum of Squares
aTemplate.setTemplate("=%TOTAL% - %WITHIN%");
aTemplate.applyAddress("%TOTAL%", output.current(0, 2));
aTemplate.applyAddress("%WITHIN%", output.current(0, 1));
output.writeFormula(aTemplate.getTemplate());
output.nextColumn();
// Degree of freedom
aTemplate.setTemplate("=%TOTAL% - %WITHIN%");
aTemplate.applyAddress("%TOTAL%", output.current(0, 2));
aTemplate.applyAddress("%WITHIN%", output.current(0, 1));
output.writeFormula(aTemplate.getTemplate());
output.nextColumn();
// MS
aTemplate.setTemplate("=%SS_REF% / %DF_REF%");
aTemplate.applyAddress("%SS_REF%", output.current(-2, 0));
aTemplate.applyAddress("%DF_REF%", output.current(-1, 0));
output.writeFormula(aTemplate.getTemplate());
output.nextColumn();
// F
aTemplate.setTemplate("=%MS_BETWEEN% / %MS_WITHIN%");
aTemplate.applyAddress("%MS_BETWEEN%", output.current(-1, 0));
aTemplate.applyAddress("%MS_WITHIN%", output.current(-1, 1));
output.writeFormula(aTemplate.getTemplate());
output.nextColumn();
// P-value
aTemplate.setTemplate("=FDIST(%F_VAL%; %DF_BETWEEN%; %DF_WITHIN%");
aTemplate.applyAddress("%F_VAL%", output.current(-1, 0));
aTemplate.applyAddress("%DF_BETWEEN%", output.current(-3, 0));
aTemplate.applyAddress("%DF_WITHIN%", output.current(-3, 1));
output.writeFormula(aTemplate.getTemplate());
output.nextColumn();
// F critical
double aAlphaValue = mpAlpha->GetValue() / 100.0;
OUString aAlphaString = rtl::math::doubleToUString(
aAlphaValue, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
ScGlobal::pLocaleData->getNumDecimalSep()[0], true);
aTemplate.setTemplate("=FINV(%ALPHA%; %DF_BETWEEN%; %DF_WITHIN%");
aTemplate.applyString("%ALPHA%", aAlphaString);
aTemplate.applyAddress("%DF_BETWEEN%", output.current(-4, 0));
aTemplate.applyAddress("%DF_WITHIN%", output.current(-4, 1));
output.writeFormula(aTemplate.getTemplate());
}
output.nextRow();
// Within Groups
{
// Label
output.resetColumn();
output.writeString(SC_STRLOAD(RID_STATISTICS_DLGS, STR_ANOVA_LABEL_WITHIN_GROUPS));
output.nextColumn();
// Sum of Squares
OUString aSSPart = lclCreateMultiParameterFormula(aRangeList, OUString("DEVSQ(%RANGE%)"), strWildcardRange, mDocument, mAddressDetails);
aTemplate.setTemplate("=SUM(%RANGE%)");
aTemplate.applyString(strWildcardRange, aSSPart);
output.writeFormula(aTemplate.getTemplate());
output.nextColumn();
// Degree of freedom
OUString aDFPart = lclCreateMultiParameterFormula(aRangeList, OUString("COUNT(%RANGE%)-1"), strWildcardRange, mDocument, mAddressDetails);
aTemplate.setTemplate("=SUM(%RANGE%)");
aTemplate.applyString(strWildcardRange, aDFPart);
output.writeFormula(aTemplate.getTemplate());
output.nextColumn();
// MS
aTemplate.setTemplate("=%SS% / %DF%");
aTemplate.applyAddress("%SS%", output.current(-2, 0));
aTemplate.applyAddress("%DF%", output.current(-1, 0));
output.writeFormula(aTemplate.getTemplate());
}
output.nextRow();
// Total
{
// Label
output.resetColumn();
output.writeString(SC_STRLOAD(RID_STATISTICS_DLGS, STR_ANOVA_LABEL_TOTAL));
output.nextColumn();
// Sum of Squares
aTemplate.setTemplate("=DEVSQ(%RANGE%)");
aTemplate.applyRangeList(strWildcardRange, aRangeList);
output.writeFormula(aTemplate.getTemplate());
output.nextColumn();
// Degree of freedom
OUString aDFPart = lclCreateMultiParameterFormula(aRangeList, "COUNT(%RANGE%)", strWildcardRange, mDocument, mAddressDetails);
aTemplate.setTemplate("=SUM(%RANGE%) - 1");
aTemplate.applyString(strWildcardRange, aDFPart);
output.writeFormula(aTemplate.getTemplate());
}
output.nextRow();
return ScRange(output.mMinimumAddress, output.mMaximumAddress);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */