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_chartview.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
DateScaling(const Date & rNullDate,sal_Int32 nTimeUnit,bool bShifted)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
~DateScaling()64 DateScaling::~DateScaling()
65 {
66 }
67
doScaling(double value)68 double SAL_CALL DateScaling::doScaling( double value )
69 {
70 double fResult(value);
71 if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
72 ::rtl::math::setNan( & fResult );
73 else
74 {
75 Date aDate(m_aNullDate);
76 aDate += static_cast<long>(::rtl::math::approxFloor(value));
77 switch( m_nTimeUnit )
78 {
79 case DAY:
80 fResult = value;
81 if(m_bShifted)
82 fResult+=0.5;
83 break;
84 case YEAR:
85 case MONTH:
86 default:
87 fResult = aDate.GetYear();
88 fResult *= lcl_fNumberOfMonths;//asssuming equal count of months in each year
89 fResult += aDate.GetMonth();
90
91 double fDayOfMonth = aDate.GetDay();
92 fDayOfMonth -= 1.0;
93 double fDaysInMonth = aDate.GetDaysInMonth();
94 fResult += fDayOfMonth/fDaysInMonth;
95 if(m_bShifted)
96 {
97 if( YEAR==m_nTimeUnit )
98 fResult += 0.5*lcl_fNumberOfMonths;
99 else
100 fResult += 0.5;
101 }
102 break;
103 }
104 }
105 return fResult;
106 }
107
getInverseScaling()108 uno::Reference< XScaling > SAL_CALL DateScaling::getInverseScaling()
109 {
110 return new InverseDateScaling( m_aNullDate, m_nTimeUnit, m_bShifted );
111 }
112
getServiceName()113 ::rtl::OUString SAL_CALL DateScaling::getServiceName()
114 {
115 return lcl_aServiceName_DateScaling;
116 }
117
getSupportedServiceNames_Static()118 uno::Sequence< ::rtl::OUString > DateScaling::getSupportedServiceNames_Static()
119 {
120 return uno::Sequence< ::rtl::OUString >( & lcl_aServiceName_DateScaling, 1 );
121 }
122
123 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
APPHELPER_XSERVICEINFO_IMPL(DateScaling,lcl_aServiceName_DateScaling)124 APPHELPER_XSERVICEINFO_IMPL( DateScaling, lcl_aServiceName_DateScaling )
125
126 // ----------------------------------------
127
128 InverseDateScaling::InverseDateScaling( const Date& rNullDate, sal_Int32 nTimeUnit, bool bShifted )
129 : m_aNullDate( rNullDate )
130 , m_nTimeUnit( nTimeUnit )
131 , m_bShifted( bShifted )
132 {
133 }
134
~InverseDateScaling()135 InverseDateScaling::~InverseDateScaling()
136 {
137 }
138
doScaling(double value)139 double SAL_CALL InverseDateScaling::doScaling( double value )
140 {
141 double fResult(value);
142 if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
143 ::rtl::math::setNan( & fResult );
144 else
145 {
146 switch( m_nTimeUnit )
147 {
148 case DAY:
149 if(m_bShifted)
150 value -= 0.5;
151 fResult = value;
152 break;
153 case YEAR:
154 case MONTH:
155 default:
156 //Date aDate(m_aNullDate);
157 if(m_bShifted)
158 {
159 if( YEAR==m_nTimeUnit )
160 value -= 0.5*lcl_fNumberOfMonths;
161 else
162 value -= 0.5;
163 }
164 Date aDate;
165 double fYear = ::rtl::math::approxFloor(value/lcl_fNumberOfMonths);
166 double fMonth = ::rtl::math::approxFloor(value-(fYear*lcl_fNumberOfMonths));
167 if( fMonth==0.0 )
168 {
169 fYear--;
170 fMonth=12.0;
171 }
172 aDate.SetYear( static_cast<sal_uInt16>(fYear) );
173 aDate.SetMonth( static_cast<sal_uInt16>(fMonth) );
174 aDate.SetDay( 1 );
175 double fMonthCount = (fYear*lcl_fNumberOfMonths)+fMonth;
176 double fDay = (value-fMonthCount)*aDate.GetDaysInMonth();
177 fDay += 1.0;
178 aDate.SetDay( static_cast<sal_uInt16>(::rtl::math::round(fDay)) );
179 fResult = aDate - m_aNullDate;
180 break;
181 }
182 }
183 return fResult;
184 }
185
getInverseScaling()186 uno::Reference< XScaling > SAL_CALL InverseDateScaling::getInverseScaling()
187 {
188 return new DateScaling( m_aNullDate, m_nTimeUnit, m_bShifted );
189 }
190
getServiceName()191 ::rtl::OUString SAL_CALL InverseDateScaling::getServiceName()
192 {
193 return lcl_aServiceName_InverseDateScaling;
194 }
195
getSupportedServiceNames_Static()196 uno::Sequence< ::rtl::OUString > InverseDateScaling::getSupportedServiceNames_Static()
197 {
198 return uno::Sequence< ::rtl::OUString >( & lcl_aServiceName_InverseDateScaling, 1 );
199 }
200
201 // implement XServiceInfo methods basing upon getSupportedServiceNames_Static
202 APPHELPER_XSERVICEINFO_IMPL( InverseDateScaling, lcl_aServiceName_InverseDateScaling )
203
204 //.............................................................................
205 } //namespace chart
206 //.............................................................................
207