1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_chart2.hxx" 26 #include "DateScaling.hxx" 27 #include <com/sun/star/chart/TimeUnit.hpp> 28 #include <rtl/math.hxx> 29 #include "com/sun/star/uno/RuntimeException.hpp" 30 31 namespace 32 { 33 34 static const ::rtl::OUString lcl_aServiceName_DateScaling( 35 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.DateScaling" )); 36 static const ::rtl::OUString lcl_aServiceName_InverseDateScaling( 37 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.chart2.InverseDateScaling" )); 38 39 static const ::rtl::OUString lcl_aImplementationName_DateScaling( 40 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.DateScaling" )); 41 static const ::rtl::OUString lcl_aImplementationName_InverseDateScaling( 42 RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.chart2.InverseDateScaling" )); 43 44 static const double lcl_fNumberOfMonths = 12.0;//todo: this needs to be offered by basic tools Date class if it should be more generic 45 } 46 47 //............................................................................. 48 namespace chart 49 { 50 //............................................................................. 51 using namespace ::com::sun::star; 52 using namespace ::com::sun::star::chart2; 53 using ::com::sun::star::chart::TimeUnit::DAY; 54 using ::com::sun::star::chart::TimeUnit::MONTH; 55 using ::com::sun::star::chart::TimeUnit::YEAR; 56 57 DateScaling::DateScaling( const Date& rNullDate, sal_Int32 nTimeUnit, bool bShifted ) 58 : m_aNullDate( rNullDate ) 59 , m_nTimeUnit( nTimeUnit ) 60 , m_bShifted( bShifted ) 61 { 62 } 63 64 DateScaling::~DateScaling() 65 { 66 } 67 68 double SAL_CALL DateScaling::doScaling( double value ) 69 throw (uno::RuntimeException) 70 { 71 double fResult(value); 72 if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) ) 73 ::rtl::math::setNan( & fResult ); 74 else 75 { 76 Date aDate(m_aNullDate); 77 aDate += static_cast<long>(::rtl::math::approxFloor(value)); 78 switch( m_nTimeUnit ) 79 { 80 case DAY: 81 fResult = value; 82 if(m_bShifted) 83 fResult+=0.5; 84 break; 85 case YEAR: 86 case MONTH: 87 default: 88 fResult = aDate.GetYear(); 89 fResult *= lcl_fNumberOfMonths;//asssuming equal count of months in each year 90 fResult += aDate.GetMonth(); 91 92 double fDayOfMonth = aDate.GetDay(); 93 fDayOfMonth -= 1.0; 94 double fDaysInMonth = aDate.GetDaysInMonth(); 95 fResult += fDayOfMonth/fDaysInMonth; 96 if(m_bShifted) 97 { 98 if( YEAR==m_nTimeUnit ) 99 fResult += 0.5*lcl_fNumberOfMonths; 100 else 101 fResult += 0.5; 102 } 103 break; 104 } 105 } 106 return fResult; 107 } 108 109 uno::Reference< XScaling > SAL_CALL DateScaling::getInverseScaling() 110 throw (uno::RuntimeException) 111 { 112 return new InverseDateScaling( m_aNullDate, m_nTimeUnit, m_bShifted ); 113 } 114 115 ::rtl::OUString SAL_CALL DateScaling::getServiceName() 116 throw (uno::RuntimeException) 117 { 118 return lcl_aServiceName_DateScaling; 119 } 120 121 uno::Sequence< ::rtl::OUString > DateScaling::getSupportedServiceNames_Static() 122 { 123 return uno::Sequence< ::rtl::OUString >( & lcl_aServiceName_DateScaling, 1 ); 124 } 125 126 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static 127 APPHELPER_XSERVICEINFO_IMPL( DateScaling, lcl_aServiceName_DateScaling ) 128 129 // ---------------------------------------- 130 131 InverseDateScaling::InverseDateScaling( const Date& rNullDate, sal_Int32 nTimeUnit, bool bShifted ) 132 : m_aNullDate( rNullDate ) 133 , m_nTimeUnit( nTimeUnit ) 134 , m_bShifted( bShifted ) 135 { 136 } 137 138 InverseDateScaling::~InverseDateScaling() 139 { 140 } 141 142 double SAL_CALL InverseDateScaling::doScaling( double value ) 143 throw (uno::RuntimeException) 144 { 145 double fResult(value); 146 if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) ) 147 ::rtl::math::setNan( & fResult ); 148 else 149 { 150 switch( m_nTimeUnit ) 151 { 152 case DAY: 153 if(m_bShifted) 154 value -= 0.5; 155 fResult = value; 156 break; 157 case YEAR: 158 case MONTH: 159 default: 160 //Date aDate(m_aNullDate); 161 if(m_bShifted) 162 { 163 if( YEAR==m_nTimeUnit ) 164 value -= 0.5*lcl_fNumberOfMonths; 165 else 166 value -= 0.5; 167 } 168 Date aDate; 169 double fYear = ::rtl::math::approxFloor(value/lcl_fNumberOfMonths); 170 double fMonth = ::rtl::math::approxFloor(value-(fYear*lcl_fNumberOfMonths)); 171 if( fMonth==0.0 ) 172 { 173 fYear--; 174 fMonth=12.0; 175 } 176 aDate.SetYear( static_cast<sal_uInt16>(fYear) ); 177 aDate.SetMonth( static_cast<sal_uInt16>(fMonth) ); 178 aDate.SetDay( 1 ); 179 double fMonthCount = (fYear*lcl_fNumberOfMonths)+fMonth; 180 double fDay = (value-fMonthCount)*aDate.GetDaysInMonth(); 181 fDay += 1.0; 182 aDate.SetDay( static_cast<sal_uInt16>(::rtl::math::round(fDay)) ); 183 fResult = aDate - m_aNullDate; 184 break; 185 } 186 } 187 return fResult; 188 } 189 190 uno::Reference< XScaling > SAL_CALL InverseDateScaling::getInverseScaling() 191 throw (uno::RuntimeException) 192 { 193 return new DateScaling( m_aNullDate, m_nTimeUnit, m_bShifted ); 194 } 195 196 ::rtl::OUString SAL_CALL InverseDateScaling::getServiceName() 197 throw (uno::RuntimeException) 198 { 199 return lcl_aServiceName_InverseDateScaling; 200 } 201 202 uno::Sequence< ::rtl::OUString > InverseDateScaling::getSupportedServiceNames_Static() 203 { 204 return uno::Sequence< ::rtl::OUString >( & lcl_aServiceName_InverseDateScaling, 1 ); 205 } 206 207 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static 208 APPHELPER_XSERVICEINFO_IMPL( InverseDateScaling, lcl_aServiceName_InverseDateScaling ) 209 210 //............................................................................. 211 } //namespace chart 212 //............................................................................. 213