summaryrefslogtreecommitdiff
path: root/chart2
diff options
context:
space:
mode:
authorKohei Yoshida <kohei.yoshida@suse.com>2011-12-13 19:46:31 -0500
committerKohei Yoshida <kohei.yoshida@suse.com>2011-12-13 19:52:26 -0500
commit70afe780231dc086a07494db97a2bac2ca0a0939 (patch)
tree4c6b503d252862283a5c9a1478d62d757529f485 /chart2
parentf56780576fa8c28cd212ddfffc554cee40698009 (diff)
fdo#43681: Set correct auto scaling for stacked data series.
With this change, the automatic y-axis scaling should be more accurate for stacked charts (i.e. stacked line, area, bar charts) with dates on the x-axis. The previous algorithm only calculated the max and min y-values of the individual data, without taking into account the stacking type when the x-axis type was date.
Diffstat (limited to 'chart2')
-rw-r--r--chart2/source/view/charttypes/VSeriesPlotter.cxx57
1 files changed, 42 insertions, 15 deletions
diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx b/chart2/source/view/charttypes/VSeriesPlotter.cxx
index 9a01b9580ca6..2d1c7bba0550 100644
--- a/chart2/source/view/charttypes/VSeriesPlotter.cxx
+++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx
@@ -1378,7 +1378,7 @@ void VSeriesPlotter::getMinimumAndMaximiumYInContinuousXRange( double& rfMinY, d
::std::vector< ::std::vector< VDataSeriesGroup > >::const_iterator aZSlotIter = m_aZSlots.begin();
const ::std::vector< ::std::vector< VDataSeriesGroup > >::const_iterator aZSlotEnd = m_aZSlots.end();
- for( ; aZSlotIter != aZSlotEnd; aZSlotIter++ )
+ for( ; aZSlotIter != aZSlotEnd; ++aZSlotIter )
{
::std::vector< VDataSeriesGroup >::const_iterator aXSlotIter = aZSlotIter->begin();
const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = aZSlotIter->end();
@@ -1499,16 +1499,24 @@ void VDataSeriesGroup::getMinimumAndMaximiumX( double& rfMinimum, double& rfMaxi
if(::rtl::math::isInf(rfMaximum))
::rtl::math::setNan(&rfMaximum);
}
-void VDataSeriesGroup::getMinimumAndMaximiumYInContinuousXRange( double& rfMinY, double& rfMaxY, double fMinX, double fMaxX, sal_Int32 nAxisIndex ) const
+
+void VDataSeriesGroup::getMinimumAndMaximiumYInContinuousXRange(
+ double& rfMinY, double& rfMaxY, double fMinX, double fMaxX, sal_Int32 nAxisIndex ) const
{
- const ::std::vector< VDataSeries* >* pSeriesList = &this->m_aSeriesVector;
+ ::rtl::math::setNan(&rfMinY);
+ ::rtl::math::setNan(&rfMaxY);
- ::std::vector< VDataSeries* >::const_iterator aSeriesIter = pSeriesList->begin();
- const ::std::vector< VDataSeries* >::const_iterator aSeriesEnd = pSeriesList->end();
+ if (m_aSeriesVector.empty())
+ // No data series. Bail out.
+ return;
- ::rtl::math::setInf(&rfMinY, false);
- ::rtl::math::setInf(&rfMaxY, true);
+ // Collect minimum y-value and accumulative maximum y-value for each
+ // x-value first, in case of stacked data series.
+ typedef boost::unordered_map<double, std::pair<double,double> > MinMaxPerXType;
+ MinMaxPerXType aStore;
+ std::vector<VDataSeries*>::const_iterator aSeriesIter = m_aSeriesVector.begin();
+ const std::vector<VDataSeries*>::const_iterator aSeriesEnd = m_aSeriesVector.end();
for( ; aSeriesIter != aSeriesEnd; ++aSeriesIter )
{
sal_Int32 nPointCount = (*aSeriesIter)->getTotalPointCount();
@@ -1525,16 +1533,35 @@ void VDataSeriesGroup::getMinimumAndMaximiumYInContinuousXRange( double& rfMinY,
double fY = (*aSeriesIter)->getYValue( nN );
if( ::rtl::math::isNan(fY) )
continue;
- if(rfMaxY<fY)
- rfMaxY=fY;
- if(rfMinY>fY)
- rfMinY=fY;
+
+ MinMaxPerXType::iterator itr = aStore.find(fX);
+ if (itr == aStore.end())
+ aStore.insert(MinMaxPerXType::value_type(fX, std::pair<double,double>(fY, fY)));
+ else
+ {
+ std::pair<double,double>& r = itr->second;
+ if (fY < r.first)
+ r.first = fY; // min y-value
+
+ r.second += fY; // accumulative max y-value.
+ }
}
}
- if(::rtl::math::isInf(rfMinY))
- ::rtl::math::setNan(&rfMinY);
- if(::rtl::math::isInf(rfMaxY))
- ::rtl::math::setNan(&rfMaxY);
+
+ if (aStore.empty())
+ // No data within the specified x range.
+ return;
+
+ MinMaxPerXType::const_iterator itr = aStore.begin(), itrEnd = aStore.end();
+ rfMinY = itr->second.first;
+ rfMaxY = itr->second.second;
+ for (++itr; itr != itrEnd; ++itr)
+ {
+ if (rfMinY > itr->second.first)
+ rfMinY = itr->second.first;
+ if (rfMaxY < itr->second.second)
+ rfMaxY = itr->second.second;
+ }
}
void VDataSeriesGroup::calculateYMinAndMaxForCategory( sal_Int32 nCategoryIndex