Skip to content

Instantly share code, notes, and snippets.

@varshneydevansh
Created January 25, 2025 12:02
Show Gist options
  • Save varshneydevansh/419288986d3948c605a6338fa7eb43d3 to your computer and use it in GitHub Desktop.
Save varshneydevansh/419288986d3948c605a6338fa7eb43d3 to your computer and use it in GitHub Desktop.
regina_post_comment_histogram.diff
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