Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : */
10 :
11 : #include <sfx2/dispatch.hxx>
12 : #include <svl/zforlist.hxx>
13 : #include <svl/undo.hxx>
14 :
15 : #include "formulacell.hxx"
16 : #include "rangelst.hxx"
17 : #include "scitems.hxx"
18 : #include "docsh.hxx"
19 : #include "document.hxx"
20 : #include "uiitems.hxx"
21 : #include "reffact.hxx"
22 : #include "strload.hxx"
23 : #include "random.hxx"
24 : #include "docfunc.hxx"
25 : #include "StatisticsDialogs.hrc"
26 : #include "TableFillingAndNavigationTools.hxx"
27 :
28 : #include "AnalysisOfVarianceDialog.hxx"
29 :
30 : namespace
31 : {
32 :
33 : static sal_Int16 lclBasicStatisticsLabels[] =
34 : {
35 : STR_ANOVA_LABEL_GROUPS,
36 : STRID_CALC_COUNT,
37 : STRID_CALC_SUM,
38 : STRID_CALC_MEAN,
39 : STRID_CALC_VARIANCE,
40 : 0
41 : };
42 :
43 : static const char* lclBasicStatisticsFormula[] =
44 : {
45 : "=COUNT(%RANGE%)", "=SUM(%RANGE%)", "=AVERAGE(%RANGE%)", "=VAR(%RANGE%)", NULL
46 : };
47 :
48 : static sal_Int16 lclAnovaLabels[] =
49 : {
50 : STR_ANOVA_LABEL_SOURCE_OF_VARIATION,
51 : STR_ANOVA_LABEL_SS,
52 : STR_ANOVA_LABEL_DF,
53 : STR_ANOVA_LABEL_MS,
54 : STR_ANOVA_LABEL_F,
55 : STR_ANOVA_LABEL_P_VALUE,
56 : STR_ANOVA_LABEL_F_CRITICAL,
57 : 0
58 : };
59 :
60 0 : static const OUString strWildcardRange("%RANGE%");
61 0 : static const OUString strWildcardNumber("%NUMBER%");
62 :
63 0 : OUString lclCreateMultiParameterFormula(
64 : ScRangeList& aRangeList, const OUString& aFormulaTemplate,
65 : const OUString& aWildcard, ScDocument* pDocument,
66 : ScAddress::Details& aAddressDetails)
67 : {
68 0 : OUString aResult;
69 0 : for (size_t i = 0; i < aRangeList.size(); i++)
70 : {
71 0 : OUString aRangeString(aRangeList[i]->Format(SCR_ABS, pDocument, aAddressDetails));
72 0 : OUString aFormulaString = aFormulaTemplate.replaceAll(aWildcard, aRangeString);
73 0 : aResult += aFormulaString;
74 0 : if(i != aRangeList.size() - 1) // Not Last
75 0 : aResult+= ";";
76 0 : }
77 0 : return aResult;
78 : }
79 :
80 : }
81 :
82 0 : ScAnalysisOfVarianceDialog::ScAnalysisOfVarianceDialog(
83 : SfxBindings* pSfxBindings, SfxChildWindow* pChildWindow,
84 : Window* pParent, ScViewData* pViewData ) :
85 : ScStatisticsInputOutputDialog(
86 : pSfxBindings, pChildWindow, pParent, pViewData,
87 0 : "AnalysisOfVarianceDialog", "modules/scalc/ui/analysisofvariancedialog.ui" )
88 : {
89 0 : get(mpAlpha, "alpha-spin");
90 0 : }
91 :
92 0 : ScAnalysisOfVarianceDialog::~ScAnalysisOfVarianceDialog()
93 0 : {}
94 :
95 0 : bool ScAnalysisOfVarianceDialog::Close()
96 : {
97 0 : return DoClose( ScAnalysisOfVarianceDialogWrapper::GetChildWindowId() );
98 : }
99 :
100 0 : sal_Int16 ScAnalysisOfVarianceDialog::GetUndoNameId()
101 : {
102 0 : return STR_ANALYSIS_OF_VARIANCE_UNDO_NAME;
103 : }
104 :
105 0 : ScRange ScAnalysisOfVarianceDialog::ApplyOutput(ScDocShell* pDocShell)
106 : {
107 : AddressWalkerWriter output(mOutputAddress, pDocShell, mDocument,
108 0 : formula::FormulaGrammar::mergeToGrammar( formula::FormulaGrammar::GRAM_ENGLISH, mAddressDetails.eConv));
109 0 : FormulaTemplate aTemplate(mDocument, mAddressDetails);
110 :
111 0 : output.writeBoldString(SC_STRLOAD(RID_STATISTICS_DLGS, STR_ANOVA_SINGLE_FACTOR_LABEL));
112 0 : output.nextRow();
113 0 : output.nextRow();
114 :
115 : // Write labels
116 0 : for(sal_Int32 i = 0; lclBasicStatisticsLabels[i] != 0; i++)
117 : {
118 0 : output.writeString(SC_STRLOAD(RID_STATISTICS_DLGS, lclBasicStatisticsLabels[i]));
119 0 : output.nextColumn();
120 : }
121 0 : output.nextRow();
122 :
123 0 : ScRangeList aRangeList;
124 :
125 0 : boost::scoped_ptr<DataRangeIterator> pIterator;
126 0 : if (mGroupedBy == BY_COLUMN)
127 0 : pIterator.reset(new DataRangeByColumnIterator(mInputRange));
128 : else
129 0 : pIterator.reset(new DataRangeByRowIterator(mInputRange));
130 :
131 : // Write statistic formulas for rows/columns
132 0 : for( ; pIterator->hasNext(); pIterator->next() )
133 : {
134 0 : output.resetColumn();
135 :
136 0 : if (mGroupedBy == BY_COLUMN)
137 0 : aTemplate.setTemplate(SC_STRLOAD(RID_STATISTICS_DLGS, STR_COLUMN_LABEL_TEMPLATE));
138 : else
139 0 : aTemplate.setTemplate(SC_STRLOAD(RID_STATISTICS_DLGS, STR_ROW_LABEL_TEMPLATE));
140 :
141 0 : aTemplate.applyNumber(strWildcardNumber, pIterator->index() + 1);
142 0 : output.writeString(aTemplate.getTemplate());
143 :
144 0 : output.nextColumn();
145 :
146 0 : ScRange aColumnRange = pIterator->get();
147 :
148 0 : aRangeList.Append(aColumnRange);
149 :
150 0 : for(sal_Int32 i = 0; lclBasicStatisticsFormula[i] != NULL; i++)
151 : {
152 0 : aTemplate.setTemplate(lclBasicStatisticsFormula[i]);
153 0 : aTemplate.applyRange(strWildcardRange, aColumnRange);
154 0 : output.writeFormula(aTemplate.getTemplate());
155 0 : output.nextColumn();
156 : }
157 0 : output.nextRow();
158 : }
159 :
160 0 : output.nextRow(); // Blank row
161 :
162 : // Write ANOVA labels
163 0 : output.resetColumn();
164 0 : for(sal_Int32 i = 0; lclAnovaLabels[i] != 0; i++)
165 : {
166 0 : output.writeString(SC_STRLOAD(RID_STATISTICS_DLGS, lclAnovaLabels[i]));
167 0 : output.nextColumn();
168 : }
169 0 : output.nextRow();
170 :
171 : // Between Groups
172 : {
173 : // Label
174 0 : output.resetColumn();
175 0 : output.writeString(SC_STRLOAD(RID_STATISTICS_DLGS, STR_ANOVA_LABEL_BETWEEN_GROUPS));
176 0 : output.nextColumn();
177 :
178 : // Sum of Squares
179 0 : aTemplate.setTemplate("=%TOTAL% - %WITHIN%");
180 0 : aTemplate.applyAddress("%TOTAL%", output.current(0, 2));
181 0 : aTemplate.applyAddress("%WITHIN%", output.current(0, 1));
182 0 : output.writeFormula(aTemplate.getTemplate());
183 0 : output.nextColumn();
184 :
185 : // Degree of freedom
186 0 : aTemplate.setTemplate("=%TOTAL% - %WITHIN%");
187 0 : aTemplate.applyAddress("%TOTAL%", output.current(0, 2));
188 0 : aTemplate.applyAddress("%WITHIN%", output.current(0, 1));
189 0 : output.writeFormula(aTemplate.getTemplate());
190 0 : output.nextColumn();
191 :
192 : // MS
193 0 : aTemplate.setTemplate("=%SS_REF% / %DF_REF%");
194 0 : aTemplate.applyAddress("%SS_REF%", output.current(-2, 0));
195 0 : aTemplate.applyAddress("%DF_REF%", output.current(-1, 0));
196 0 : output.writeFormula(aTemplate.getTemplate());
197 0 : output.nextColumn();
198 :
199 : // F
200 0 : aTemplate.setTemplate("=%MS_BETWEEN% / %MS_WITHIN%");
201 0 : aTemplate.applyAddress("%MS_BETWEEN%", output.current(-1, 0));
202 0 : aTemplate.applyAddress("%MS_WITHIN%", output.current(-1, 1));
203 0 : output.writeFormula(aTemplate.getTemplate());
204 0 : output.nextColumn();
205 :
206 : // P-value
207 0 : aTemplate.setTemplate("=FDIST(%F_VAL%; %DF_BETWEEN%; %DF_WITHIN%");
208 0 : aTemplate.applyAddress("%F_VAL%", output.current(-1, 0));
209 0 : aTemplate.applyAddress("%DF_BETWEEN%", output.current(-3, 0));
210 0 : aTemplate.applyAddress("%DF_WITHIN%", output.current(-3, 1));
211 0 : output.writeFormula(aTemplate.getTemplate());
212 0 : output.nextColumn();
213 :
214 : // F critical
215 0 : double aAlphaValue = mpAlpha->GetValue() / 100.0;
216 : OUString aAlphaString = rtl::math::doubleToUString(
217 : aAlphaValue, rtl_math_StringFormat_Automatic, rtl_math_DecimalPlaces_Max,
218 0 : ScGlobal::pLocaleData->getNumDecimalSep()[0], true);
219 :
220 0 : aTemplate.setTemplate("=FINV(%ALPHA%; %DF_BETWEEN%; %DF_WITHIN%");
221 0 : aTemplate.applyString("%ALPHA%", aAlphaString);
222 0 : aTemplate.applyAddress("%DF_BETWEEN%", output.current(-4, 0));
223 0 : aTemplate.applyAddress("%DF_WITHIN%", output.current(-4, 1));
224 0 : output.writeFormula(aTemplate.getTemplate());
225 : }
226 0 : output.nextRow();
227 :
228 : // Within Groups
229 : {
230 : // Label
231 0 : output.resetColumn();
232 0 : output.writeString(SC_STRLOAD(RID_STATISTICS_DLGS, STR_ANOVA_LABEL_WITHIN_GROUPS));
233 0 : output.nextColumn();
234 :
235 : // Sum of Squares
236 0 : OUString aSSPart = lclCreateMultiParameterFormula(aRangeList, OUString("DEVSQ(%RANGE%)"), strWildcardRange, mDocument, mAddressDetails);
237 0 : aTemplate.setTemplate("=SUM(%RANGE%)");
238 0 : aTemplate.applyString(strWildcardRange, aSSPart);
239 0 : output.writeFormula(aTemplate.getTemplate());
240 0 : output.nextColumn();
241 :
242 : // Degree of freedom
243 0 : OUString aDFPart = lclCreateMultiParameterFormula(aRangeList, OUString("COUNT(%RANGE%)-1"), strWildcardRange, mDocument, mAddressDetails);
244 0 : aTemplate.setTemplate("=SUM(%RANGE%)");
245 0 : aTemplate.applyString(strWildcardRange, aDFPart);
246 0 : output.writeFormula(aTemplate.getTemplate());
247 0 : output.nextColumn();
248 :
249 : // MS
250 0 : aTemplate.setTemplate("=%SS% / %DF%");
251 0 : aTemplate.applyAddress("%SS%", output.current(-2, 0));
252 0 : aTemplate.applyAddress("%DF%", output.current(-1, 0));
253 0 : output.writeFormula(aTemplate.getTemplate());
254 : }
255 0 : output.nextRow();
256 :
257 : // Total
258 : {
259 : // Label
260 0 : output.resetColumn();
261 0 : output.writeString(SC_STRLOAD(RID_STATISTICS_DLGS, STR_ANOVA_LABEL_TOTAL));
262 0 : output.nextColumn();
263 :
264 : // Sum of Squares
265 0 : aTemplate.setTemplate("=DEVSQ(%RANGE%)");
266 0 : aTemplate.applyRangeList(strWildcardRange, aRangeList);
267 0 : output.writeFormula(aTemplate.getTemplate());
268 0 : output.nextColumn();
269 :
270 : // Degree of freedom
271 0 : OUString aDFPart = lclCreateMultiParameterFormula(aRangeList, "COUNT(%RANGE%)", strWildcardRange, mDocument, mAddressDetails);
272 0 : aTemplate.setTemplate("=SUM(%RANGE%) - 1");
273 0 : aTemplate.applyString(strWildcardRange, aDFPart);
274 0 : output.writeFormula(aTemplate.getTemplate());
275 : }
276 0 : output.nextRow();
277 :
278 0 : return ScRange(output.mMinimumAddress, output.mMaximumAddress);
279 0 : }
280 :
281 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|