Created
January 25, 2025 12:02
-
-
Save varshneydevansh/419288986d3948c605a6338fa7eb43d3 to your computer and use it in GitHub Desktop.
regina_post_comment_histogram.diff
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/chart2/qa/extras/data/fods/tdf82716_HistogramChart.fods b/chart2/qa/extras/data/fods/tdf82716_HistogramChart.fods | |
index 47d80627ff6d..5defc4498704 100644 | |
--- a/chart2/qa/extras/data/fods/tdf82716_HistogramChart.fods | |
+++ b/chart2/qa/extras/data/fods/tdf82716_HistogramChart.fods | |
@@ -316,7 +316,7 @@ | |
<table:table-cell office:value-type="string"> | |
<text:p>1</text:p> | |
</table:table-cell> | |
- <table:table-cell office:value-type="float" office:value="12"> | |
+ <table:table-cell office:value-type="float" office:value="10"> | |
<text:p>10</text:p> | |
<draw:g> | |
<svg:desc>Sheet1.A1:Sheet1.A5</svg:desc></draw:g> | |
@@ -326,7 +326,7 @@ | |
<table:table-cell office:value-type="string"> | |
<text:p>2</text:p> | |
</table:table-cell> | |
- <table:table-cell office:value-type="float" office:value="13"> | |
+ <table:table-cell office:value-type="float" office:value="12"> | |
<text:p>12</text:p> | |
</table:table-cell> | |
</table:table-row> | |
@@ -334,7 +334,7 @@ | |
<table:table-cell office:value-type="string"> | |
<text:p>3</text:p> | |
</table:table-cell> | |
- <table:table-cell office:value-type="float" office:value="15"> | |
+ <table:table-cell office:value-type="float" office:value="13"> | |
<text:p>13</text:p> | |
</table:table-cell> | |
</table:table-row> | |
@@ -342,7 +342,7 @@ | |
<table:table-cell office:value-type="string"> | |
<text:p>4</text:p> | |
</table:table-cell> | |
- <table:table-cell office:value-type="float" office:value="16"> | |
+ <table:table-cell office:value-type="float" office:value="14"> | |
<text:p>14</text:p> | |
</table:table-cell> | |
</table:table-row> | |
@@ -350,7 +350,7 @@ | |
<table:table-cell office:value-type="string"> | |
<text:p>5</text:p> | |
</table:table-cell> | |
- <table:table-cell office:value-type="float" office:value="10"> | |
+ <table:table-cell office:value-type="float" office:value="16"> | |
<text:p>16</text:p> | |
</table:table-cell> | |
</table:table-row> | |
diff --git a/chart2/source/model/template/HistogramCalculator.cxx b/chart2/source/model/template/HistogramCalculator.cxx | |
index ac0455196a53..3c6fedaeea00 100644 | |
--- a/chart2/source/model/template/HistogramCalculator.cxx | |
+++ b/chart2/source/model/template/HistogramCalculator.cxx | |
@@ -14,104 +14,232 @@ | |
namespace chart | |
{ | |
-HistogramCalculator::HistogramCalculator() = default; | |
- | |
-void HistogramCalculator::computeBinFrequencyHistogram(const std::vector<double>& rDataPoints) | |
+//HistogramCalculator::HistogramCalculator() = default; | |
+ | |
+// void HistogramCalculator::computeBinFrequencyHistogram(const std::vector<double>& rDataPoints) | |
+// { | |
+// if (rDataPoints.empty()) | |
+// return; | |
+ | |
+// mnBins = 1; | |
+// mfBinWidth = 1.0; | |
+// maBinRanges.clear(); | |
+// maBinFrequencies.clear(); | |
+ | |
+// // Calculate statistics | |
+// double fSum = 0.0; | |
+// double fSquareSum = 0.0; | |
+// double fMinValue = rDataPoints[0]; | |
+// double fMaxValue = rDataPoints[0]; | |
+// sal_Int32 nValidCount = 0; | |
+ | |
+// // Compute min and max values, ignoring non-finite values | |
+// for (const auto& rValue : rDataPoints) | |
+// { | |
+// if (std::isfinite(rValue)) | |
+// { | |
+// fSum += rValue; | |
+// fSquareSum += rValue * rValue; | |
+// fMinValue = std::min(fMinValue, rValue); | |
+// fMaxValue = std::max(fMaxValue, rValue); | |
+// ++nValidCount; | |
+// } | |
+// } | |
+ | |
+// if (nValidCount < 2 || fMinValue == fMaxValue) // Need at least two points for variance | |
+// { | |
+// mnBins = 1; | |
+// mfBinWidth = 1.0; | |
+// maBinRanges = { { std::floor(fMinValue), std::ceil(fMinValue + 1.0) } }; | |
+// maBinFrequencies = { nValidCount }; | |
+// return; | |
+// } | |
+ | |
+// double fMean = fSum / nValidCount; | |
+// double fVariance = (fSquareSum - fSum * fMean) / (nValidCount - 1); | |
+// double fStdDev = std::sqrt(fVariance); | |
+ | |
+// // Apply Scott's rule for bin width | |
+// mfBinWidth = (3.5 * fStdDev) / std::cbrt(nValidCount); | |
+ | |
+// // Calculate number of bins | |
+// mnBins = static_cast<sal_Int32>(std::ceil((fMaxValue - fMinValue) / mfBinWidth)); | |
+// mnBins = std::max<sal_Int32>(mnBins, 1); // Ensure at least one bin | |
+ | |
+// // Set up bin ranges | |
+// maBinRanges.reserve(mnBins); | |
+// double fBinStart = fMinValue; | |
+ | |
+// for (sal_Int32 i = 0; i < mnBins; ++i) | |
+// { | |
+// double fBinEnd = fBinStart + mfBinWidth; | |
+ | |
+// // Correct rounding to avoid discrepancies | |
+// fBinStart = std::round(fBinStart * 100.0) / 100.0; | |
+// fBinEnd = std::round(fBinEnd * 100.0) / 100.0; | |
+ | |
+// if (i == 0) | |
+// { | |
+// // First bin includes the minimum value, so use closed interval [fMinValue, fBinEnd] | |
+// maBinRanges.emplace_back(fMinValue, fBinEnd); | |
+// } | |
+// else | |
+// { | |
+// // Subsequent bins use half-open interval (fBinStart, fBinEnd] | |
+// maBinRanges.emplace_back(fBinStart, fBinEnd); | |
+// } | |
+// fBinStart = fBinEnd; | |
+// } | |
+ | |
+// // Adjust the last bin end to be inclusive | |
+// maBinRanges.back().second = std::max(maBinRanges.back().second, fMaxValue); | |
+ | |
+// // Calculate frequencies | |
+// maBinFrequencies.assign(mnBins, 0); | |
+// for (double fValue : rDataPoints) | |
+// { | |
+// if (std::isfinite(fValue)) | |
+// { | |
+// for (size_t i = 0; i < maBinRanges.size(); ++i) | |
+// { | |
+// if (i == 0 && fValue >= maBinRanges[i].first && fValue <= maBinRanges[i].second) | |
+// { | |
+// maBinFrequencies[i]++; | |
+// break; | |
+// } | |
+// else if (i > 0 && fValue > maBinRanges[i].first && fValue <= maBinRanges[i].second) | |
+// { | |
+// maBinFrequencies[i]++; | |
+// break; | |
+// } | |
+// } | |
+// } | |
+// } | |
+// } | |
+ | |
+ | |
+void HistogramCalculator::computeBins( | |
+ const std::vector<double>& rData, | |
+ sal_Int8 nFrequencyType, | |
+ sal_Int32 nBinCount, | |
+ double fBinWidth, | |
+ bool bIntervalClosed, | |
+ double fOverflowValue, | |
+ double fUnderflowValue) | |
{ | |
- if (rDataPoints.empty()) | |
- return; | |
- | |
- mnBins = 1; | |
- mfBinWidth = 1.0; | |
maBinRanges.clear(); | |
maBinFrequencies.clear(); | |
- // Calculate statistics | |
- double fSum = 0.0; | |
- double fSquareSum = 0.0; | |
- double fMinValue = rDataPoints[0]; | |
- double fMaxValue = rDataPoints[0]; | |
- sal_Int32 nValidCount = 0; | |
+ if (rData.empty()) | |
+ return; | |
- // Compute min and max values, ignoring non-finite values | |
- for (const auto& rValue : rDataPoints) | |
+ // PART A: Compute main bins | |
+ switch (nFrequencyType) | |
{ | |
- if (std::isfinite(rValue)) | |
- { | |
- fSum += rValue; | |
- fSquareSum += rValue * rValue; | |
- fMinValue = std::min(fMinValue, rValue); | |
- fMaxValue = std::max(fMaxValue, rValue); | |
- ++nValidCount; | |
- } | |
+ case 0: // Automatic (Scott's rule) | |
+ computeScottBins(rData); | |
+ break; | |
+ case 1: // Fixed Bin Width | |
+ computeFixedWidthBins(rData, fBinWidth); | |
+ break; | |
+ case 2: // Fixed Bin Count | |
+ computeFixedCountBins(rData, nBinCount); | |
+ break; | |
+ default: | |
+ SAL_WARN("chart2", "Invalid FrequencyType: " << nFrequencyType); | |
+ computeScottBins(rData); | |
+ break; | |
} | |
- if (nValidCount < 2 || fMinValue == fMaxValue) // Need at least two points for variance | |
+ // PART B: Handle Overflow/Underflow | |
+ if (!std::isnan(fOverflowValue)) | |
{ | |
- mnBins = 1; | |
- mfBinWidth = 1.0; | |
- maBinRanges = { { std::floor(fMinValue), std::ceil(fMinValue + 1.0) } }; | |
- maBinFrequencies = { nValidCount }; | |
- return; | |
+ size_t nOverflow = countOverflow(rData, fOverflowValue); | |
+ maBinRanges.emplace_back(fOverflowValue, std::numeric_limits<double>::infinity()); | |
+ maBinFrequencies.push_back(nOverflow); | |
+ } | |
+ if (!std::isnan(fUnderflowValue)) | |
+ { | |
+ size_t nUnderflow = countUnderflow(rData, fUnderflowValue); | |
+ maBinRanges.insert(maBinRanges.begin(), | |
+ std::make_pair(-std::numeric_limits<double>::infinity(), fUnderflowValue)); | |
+ maBinFrequencies.insert(maBinFrequencies.begin(), nUnderflow); | |
} | |
- double fMean = fSum / nValidCount; | |
- double fVariance = (fSquareSum - fSum * fMean) / (nValidCount - 1); | |
- double fStdDev = std::sqrt(fVariance); | |
- | |
- // Apply Scott's rule for bin width | |
- mfBinWidth = (3.5 * fStdDev) / std::cbrt(nValidCount); | |
- | |
- // Calculate number of bins | |
- mnBins = static_cast<sal_Int32>(std::ceil((fMaxValue - fMinValue) / mfBinWidth)); | |
- mnBins = std::max<sal_Int32>(mnBins, 1); // Ensure at least one bin | |
+ // PART C: Calculate frequencies considering interval closure | |
+ calculateFrequencies(rData, bIntervalClosed); | |
+} | |
- // Set up bin ranges | |
- maBinRanges.reserve(mnBins); | |
- double fBinStart = fMinValue; | |
+void HistogramCalculator::computeScottBins(const std::vector<double>& rData) | |
+{ | |
+ // Original Scott's rule logic from computeBinFrequencyHistogram | |
+ double fMin = *std::min_element(rData.begin(), rData.end()); | |
+ double fMax = *std::max_element(rData.begin(), rData.end()); | |
+ double fStdDev = computeStandardDeviation(rData); | |
+ double fBinWidth = (3.5 * fStdDev) / std::cbrt(rData.size()); | |
+ | |
+ computeFixedWidthBins(rData, fBinWidth); | |
+} | |
- for (sal_Int32 i = 0; i < mnBins; ++i) | |
+void HistogramCalculator::computeFixedWidthBins( | |
+ const std::vector<double>& rData, | |
+ double fBinWidth) | |
+{ | |
+ if (fBinWidth <= 0) | |
{ | |
- double fBinEnd = fBinStart + mfBinWidth; | |
+ SAL_WARN("chart2", "Invalid BinWidth: " << fBinWidth); | |
+ return; | |
+ } | |
- // Correct rounding to avoid discrepancies | |
- fBinStart = std::round(fBinStart * 100.0) / 100.0; | |
- fBinEnd = std::round(fBinEnd * 100.0) / 100.0; | |
+ double fMin = *std::min_element(rData.begin(), rData.end()); | |
+ double fCurrent = fMin; | |
- if (i == 0) | |
- { | |
- // First bin includes the minimum value, so use closed interval [fMinValue, fBinEnd] | |
- maBinRanges.emplace_back(fMinValue, fBinEnd); | |
- } | |
- else | |
- { | |
- // Subsequent bins use half-open interval (fBinStart, fBinEnd] | |
- maBinRanges.emplace_back(fBinStart, fBinEnd); | |
- } | |
- fBinStart = fBinEnd; | |
+ while (fCurrent < fMax) | |
+ { | |
+ maBinRanges.emplace_back(fCurrent, fCurrent + fBinWidth); | |
+ fCurrent += fBinWidth; | |
} | |
+} | |
- // Adjust the last bin end to be inclusive | |
- maBinRanges.back().second = std::max(maBinRanges.back().second, fMaxValue); | |
+size_t HistogramCalculator::countOverflow( | |
+ const std::vector<double>& rData, | |
+ double fThreshold) | |
+{ | |
+ return std::count_if(rData.begin(), rData.end(), | |
+ [fThreshold](double val) { return val > fThreshold; }); | |
+} | |
+ | |
+size_t HistogramCalculator::countUnderflow( | |
+ const std::vector<double>& rData, | |
+ double fThreshold) | |
+{ | |
+ return std::count_if(rData.begin(), rData.end(), | |
+ [fThreshold](double val) { return val <= fThreshold; }); | |
+} | |
- // Calculate frequencies | |
- maBinFrequencies.assign(mnBins, 0); | |
- for (double fValue : rDataPoints) | |
+void HistogramCalculator::calculateFrequencies( | |
+ const std::vector<double>& rData, | |
+ bool bIntervalClosed) | |
+{ | |
+ maBinFrequencies.assign(maBinRanges.size(), 0); | |
+ for (double fValue : rData) | |
{ | |
- if (std::isfinite(fValue)) | |
+ for (size_t i = 0; i < maBinRanges.size(); ++i) | |
{ | |
- for (size_t i = 0; i < maBinRanges.size(); ++i) | |
+ double fStart = maBinRanges[i].first; | |
+ double fEnd = maBinRanges[i].second; | |
+ | |
+ // Check if value falls into this bin | |
+ bool bInBin = false; | |
+ if (i == 0 && fValue >= fStart && (bIntervalClosed ? fValue <= fEnd : fValue < fEnd)) | |
+ bInBin = true; | |
+ else if (fValue > fStart && (bIntervalClosed ? fValue <= fEnd : fValue < fEnd)) | |
+ bInBin = true; | |
+ | |
+ if (bInBin) | |
{ | |
- if (i == 0 && fValue >= maBinRanges[i].first && fValue <= maBinRanges[i].second) | |
- { | |
- maBinFrequencies[i]++; | |
- break; | |
- } | |
- else if (i > 0 && fValue > maBinRanges[i].first && fValue <= maBinRanges[i].second) | |
- { | |
- maBinFrequencies[i]++; | |
- break; | |
- } | |
+ maBinFrequencies[i]++; | |
+ break; | |
} | |
} | |
} | |
diff --git a/chart2/source/model/template/HistogramChartType.cxx b/chart2/source/model/template/HistogramChartType.cxx | |
index 32bf04e8e788..5867335d4a0c 100644 | |
--- a/chart2/source/model/template/HistogramChartType.cxx | |
+++ b/chart2/source/model/template/HistogramChartType.cxx | |
@@ -41,6 +41,8 @@ enum | |
PROP_HISTOGRAMCHARTTYPE_BINWIDTH, | |
PROP_HISTOGRAMCHARTTYPE_BINRANGE, | |
PROP_HISTOGRAMCHARTTYPE_FREQUENCYTYPE, | |
+ PROP_HISTOGRAMCHARTTYPE_SOURCERANGE, | |
+ PROP_HISTOGRAM_SOURCE_RANGE, | |
PROP_HISTOGRAMCHARTTYPE_OVERLAP_SEQUENCE, | |
PROP_HISTOGRAMCHARTTYPE_GAPWIDTH_SEQUENCE | |
}; | |
@@ -59,6 +61,14 @@ void lcl_AddPropertiesToVector(std::vector<Property>& rOutProperties) | |
"FrequencyType", PROP_HISTOGRAMCHARTTYPE_FREQUENCYTYPE, cppu::UnoType<sal_Int8>::get(), | |
beans::PropertyAttribute::BOUND | beans::PropertyAttribute::MAYBEDEFAULT); | |
+ rOutProperties.emplace_back( | |
+ "OriginalSourceRange", PROP_HISTOGRAMCHARTTYPE_SOURCERANGE, cppu::UnoType<OUString>::get(), | |
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::READONLY); | |
+ | |
+ rOutProperties.emplace_back( | |
+ "SourceCellRange", PROP_HISTOGRAM_SOURCE_RANGE, cppu::UnoType<OUString>::get(), | |
+ beans::PropertyAttribute::BOUND | beans::PropertyAttribute::MAYBEDEFAULT); | |
+ | |
rOutProperties.emplace_back("OverlapSequence", PROP_HISTOGRAMCHARTTYPE_OVERLAP_SEQUENCE, | |
cppu::UnoType<Sequence<sal_Int32>>::get(), | |
beans::PropertyAttribute::BOUND | |
@@ -171,6 +181,8 @@ void HistogramChartType::GetDefaultValue(sal_Int32 nHandle, uno::Any& rAny) cons | |
1.0); | |
::chart::PropertyHelper::setPropertyValueDefault( | |
aTmp, PROP_HISTOGRAMCHARTTYPE_FREQUENCYTYPE, sal_Int32(0)); | |
+ ::chart::PropertyHelper::setPropertyValueDefault( | |
+ aTmp, PROP_HISTOGRAMCHARTTYPE_SOURCERANGE, OUString()); | |
return aTmp; | |
}(); | |
@@ -203,23 +215,23 @@ css::uno::Sequence<OUString> SAL_CALL HistogramChartType::getSupportedServiceNam | |
return { CHART2_SERVICE_NAME_CHARTTYPE_HISTOGRAM, "com.sun.star.chart2.ChartType" }; | |
} | |
-namespace | |
-{ | |
-void setRoleToTheSequence(uno::Reference<chart2::data::XDataSequence> const& xSequence, | |
- OUString const& rRole) | |
-{ | |
- if (!xSequence.is()) | |
- return; | |
- try | |
- { | |
- uno::Reference<beans::XPropertySet> xProperty(xSequence, uno::UNO_QUERY_THROW); | |
- xProperty->setPropertyValue(u"Role"_ustr, uno::Any(rRole)); | |
- } | |
- catch (const uno::Exception&) | |
- { | |
- } | |
-} | |
-} | |
+// namespace | |
+// { | |
+// void setRoleToTheSequence(uno::Reference<chart2::data::XDataSequence> const& xSequence, | |
+// OUString const& rRole) | |
+// { | |
+// if (!xSequence.is()) | |
+// return; | |
+// try | |
+// { | |
+// uno::Reference<beans::XPropertySet> xProperty(xSequence, uno::UNO_QUERY_THROW); | |
+// xProperty->setPropertyValue(u"Role"_ustr, uno::Any(rRole)); | |
+// } | |
+// catch (const uno::Exception&) | |
+// { | |
+// } | |
+// } | |
+// } | |
void HistogramChartType::createCalculatedDataSeries() | |
{ | |
@@ -232,56 +244,61 @@ void HistogramChartType::createCalculatedDataSeries() | |
if (aDataSequences.empty() || !aDataSequences[0].is()) | |
return; | |
- // Extract raw data from the spreadsheet | |
- std::vector<double> rawData; | |
- uno::Reference<chart2::data::XDataSequence> xValues = aDataSequences[0]->getValues(); | |
- | |
- uno::Sequence<uno::Any> aRawAnyValues = xValues->getData(); | |
- for (const auto& aAny : aRawAnyValues) | |
+ // STEP 1: Preserve original data | |
+ uno::Reference<chart2::data::XDataSequence> xSourceSeq = aSequences[0]->getValues(); | |
+ xSeries->setPropertyValue("SourceRange", uno::Any(xSourceSeq->getSourceRangeRepresentation())); | |
+ | |
+ uno::Sequence<uno::Any> aOriginalData = xSourceSeq->getData(); | |
+ xSeries->setPropertyValue("OriginalValues", uno::Any(aOriginalData)); | |
+ | |
+ // STEP 2: Get current histogram settings | |
+ sal_Int8 nFreqType = 0; | |
+ double fBinWidth = 0.0; | |
+ sal_Int32 nBinCount = 0; | |
+ bool bIntervalClosed = false; | |
+ double fOverflow = std::numeric_limits<double>::quiet_NaN(); | |
+ double fUnderflow = std::numeric_limits<double>::quiet_NaN(); | |
+ | |
+ xSeries->getPropertyValue("FrequencyType") >>= nFreqType; | |
+ xSeries->getPropertyValue("BinWidth") >>= fBinWidth; | |
+ xSeries->getPropertyValue("BinCount") >>= nBinCount; | |
+ xSeries->getPropertyValue("IntervalClosed") >>= bIntervalClosed; | |
+ xSeries->getPropertyValue("OverflowBinValue") >>= fOverflow; | |
+ xSeries->getPropertyValue("UnderflowBinValue") >>= fUnderflow; | |
+ | |
+ // STEP 3: Convert original data to vector | |
+ std::vector<double> vRawData; | |
+ for (const auto& rAny : aOriginalData) | |
{ | |
double fValue = 0.0; | |
- if (aAny >>= fValue) // Extract double from Any | |
- { | |
- rawData.push_back(fValue); | |
- } | |
+ if (rAny >>= fValue) | |
+ vRawData.push_back(fValue); | |
} | |
- // Perform histogram calculations | |
- HistogramCalculator aHistogramCalculator; | |
- aHistogramCalculator.computeBinFrequencyHistogram(rawData); | |
- | |
- // Get bin ranges and frequencies | |
- const auto& binRanges = aHistogramCalculator.getBinRanges(); | |
- const auto& binFrequencies = aHistogramCalculator.getBinFrequencies(); | |
- | |
- // Create labels and values for HistogramDataSequence | |
- std::vector<OUString> aLabels; | |
- std::vector<double> aValues; | |
- for (size_t i = 0; i < binRanges.size(); ++i) | |
- { | |
- OUString aLabel; | |
- if (i == 0) | |
- { | |
- aLabel = u"["_ustr + OUString::number(binRanges[i].first) + u"-"_ustr | |
- + OUString::number(binRanges[i].second) + u"]"_ustr; | |
- } | |
- else | |
- { | |
- aLabel = u"("_ustr + OUString::number(binRanges[i].first) + u"-"_ustr | |
- + OUString::number(binRanges[i].second) + u"]"_ustr; | |
- } | |
- aLabels.push_back(aLabel); | |
- aValues.push_back(static_cast<double>(binFrequencies[i])); | |
- } | |
- | |
- rtl::Reference<HistogramDataSequence> aValuesDataSequence = new HistogramDataSequence(); | |
- aValuesDataSequence->setValues(comphelper::containerToSequence(aValues)); | |
- aValuesDataSequence->setLabels(comphelper::containerToSequence(aLabels)); | |
- | |
- uno::Reference<chart2::data::XDataSequence> aDataSequence = aValuesDataSequence; | |
- setRoleToTheSequence(aDataSequence, u"values-y"_ustr); | |
- | |
- m_aDataSeries[0]->addDataSequence(new LabeledDataSequence(aDataSequence)); | |
+ // STEP 4: Compute bins with current settings | |
+ HistogramCalculator aCalc; | |
+ aCalc.computeBins( | |
+ vRawData, | |
+ nFreqType, | |
+ nBinCount, | |
+ fBinWidth, | |
+ bIntervalClosed, | |
+ fOverflow, | |
+ fUnderflow | |
+ ); | |
+ | |
+ // STEP 5: Store bin metadata (not replacing data) | |
+ xSeries->setPropertyValue("BinRanges", uno::Any(comphelper::containerToSequence(aCalc.getBinRanges()))); | |
+ xSeries->setPropertyValue("BinFrequencies", uno::Any(comphelper::containerToSequence(aCalc.getBinFrequencies()))); | |
+ | |
+ // rtl::Reference<HistogramDataSequence> aValuesDataSequence = new HistogramDataSequence(); | |
+ // aValuesDataSequence->setValues(comphelper::containerToSequence(aValues)); | |
+ // aValuesDataSequence->setLabels(comphelper::containerToSequence(aLabels)); | |
+ | |
+ // uno::Reference<chart2::data::XDataSequence> aDataSequence = aValuesDataSequence; | |
+ // setRoleToTheSequence(aDataSequence, u"values-y"_ustr); | |
+ | |
+ // m_aDataSeries[0]->addDataSequence(new LabeledDataSequence(aDataSequence)); | |
} | |
} // namespace chart | |
diff --git a/chart2/source/tools/HistogramDataSequence.cxx b/chart2/source/tools/HistogramDataSequence.cxx | |
index c98a6c92fd33..ff91b9bef42b 100644 | |
--- a/chart2/source/tools/HistogramDataSequence.cxx | |
+++ b/chart2/source/tools/HistogramDataSequence.cxx | |
@@ -8,6 +8,7 @@ | |
*/ | |
#include <HistogramDataSequence.hxx> | |
+#include <HistogramCalculator.hxx> | |
#include <CommonFunctors.hxx> | |
#include <ModifyListenerHelper.hxx> | |
@@ -89,7 +90,51 @@ uno::Sequence<double> SAL_CALL HistogramDataSequence::getNumericalData() | |
{ | |
std::unique_lock<std::mutex> aGuard; | |
- return mxValues; | |
+ if (!m_xSeries.is()) | |
+ return mxValues; | |
+ | |
+ // STEP 1: Get original data from series | |
+ uno::Sequence<uno::Any> aOriginalData; | |
+ m_xSeries->getPropertyValue("OriginalValues") >>= aOriginalData; | |
+ | |
+ std::vector<double> vData; | |
+ for (const auto& rAny : aOriginalData) | |
+ { | |
+ double fVal; | |
+ if (rAny >>= fVal) | |
+ vData.push_back(fVal); | |
+ } | |
+ | |
+ // STEP 2: Get current settings | |
+ sal_Int8 nFreqType = 0; | |
+ double fBinWidth = 0.0; | |
+ sal_Int32 nBinCount = 0; | |
+ bool bIntervalClosed = false; | |
+ double fOverflow = std::numeric_limits<double>::quiet_NaN(); | |
+ double fUnderflow = std::numeric_limits<double>::quiet_NaN(); | |
+ | |
+ m_xSeries->getPropertyValue("FrequencyType") >>= nFreqType; | |
+ m_xSeries->getPropertyValue("BinWidth") >>= fBinWidth; | |
+ m_xSeries->getPropertyValue("BinCount") >>= nBinCount; | |
+ m_xSeries->getPropertyValue("IntervalClosed") >>= bIntervalClosed; | |
+ m_xSeries->getPropertyValue("OverflowBinValue") >>= fOverflow; | |
+ m_xSeries->getPropertyValue("UnderflowBinValue") >>= fUnderflow; | |
+ | |
+ // STEP 3: Compute bins dynamically | |
+ HistogramCalculator aCalc; | |
+ aCalc.computeBins( | |
+ vData, | |
+ nFreqType, | |
+ nBinCount, | |
+ fBinWidth, | |
+ bIntervalClosed, | |
+ fOverflow, | |
+ fUnderflow | |
+ ); | |
+ | |
+ // STEP 4: Return frequencies as numerical data | |
+ const auto& vFrequencies = aCalc.getBinFrequencies(); | |
+ return comphelper::containerToSequence(vFrequencies); | |
} | |
// XTextualDataSequence | |
diff --git a/offapi/com/sun/star/chart/HistogramDiagram.idl b/offapi/com/sun/star/chart/HistogramDiagram.idl | |
index a6986ed6ee5a..f2411c9c83b6 100644 | |
--- a/offapi/com/sun/star/chart/HistogramDiagram.idl | |
+++ b/offapi/com/sun/star/chart/HistogramDiagram.idl | |
@@ -40,7 +40,7 @@ service HistogramDiagram | |
* 2: Number of bins (BinCount) - A specific number of bins are created. | |
* TODO: 3: By Category - Bins are determined by data categories, making BinWidth and BinCount irrelevant. | |
*/ | |
- [property] short FrequencyType; | |
+ [property] byte FrequencyType; | |
/** Indicates whether the histogram should include an overflow bin. | |
When set to true, specifies that values above a certain threshold are grouped into one bin. | |
@@ -58,12 +58,27 @@ service HistogramDiagram | |
/** Defines the threshold value for the underflow bin. Only applicable if UnderflowBin is true. */ | |
[property, optional] double UnderflowBinValue; | |
+ | |
/** Specifies whether the bin intervals are closed on the upper boundary. | |
- true: The upper boundary is included in the bin. | |
- false: The upper boundary is excluded from the bin (open interval). | |
- This mimics the Excel 'intervalClosed' attribute for precise bin definition. | |
+ This mimics the Excel 'intervalClosed' attribute for precise bin definition, | |
+ affecting how data points at bin boundaries are counted. | |
*/ | |
[property, optional] boolean IntervalClosed; | |
+ | |
+ /** | |
+ * Original data reference (cell range). This property stores the location of the data | |
+ * within the spreadsheet, enabling the chart to fetch and update from the correct source when needed. | |
+ */ | |
+ [optional, property] string SourceCellRange; | |
+ | |
+ /** | |
+ * Cached original values (transient, not for persistence). This sequence holds the | |
+ * raw data values as they were when the chart was initially created or last updated, | |
+ * allowing for dynamic recalculation of bins without storing this data in the document's XML. | |
+ */ | |
+ [optional, property, transient] sequence<double> OriginalValues; | |
}; | |
}; }; }; }; | |
diff --git a/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng b/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng | |
index 3fc69be5a87b..038681e653b1 100644 | |
--- a/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng | |
+++ b/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng | |
@@ -4104,4 +4104,3 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1. | |
</rng:element> | |
</rng:define> | |
</rng:grammar> | |
- |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment