[Libreoffice-commits] .: chart2/source

Kohei Yoshida kohei at kemper.freedesktop.org
Tue Dec 13 16:52:12 PST 2011


 chart2/source/view/charttypes/VSeriesPlotter.cxx |   57 ++++++++++++++++-------
 1 file changed, 42 insertions(+), 15 deletions(-)

New commits:
commit 70afe780231dc086a07494db97a2bac2ca0a0939
Author: Kohei Yoshida <kohei.yoshida at suse.com>
Date:   Tue Dec 13 19:46:31 2011 -0500

    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.

diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx b/chart2/source/view/charttypes/VSeriesPlotter.cxx
index 9a01b95..2d1c7bb 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


More information about the Libreoffice-commits mailing list