Version 6.1.4.1, tag libreoffice-6.1.4.1
[LibreOffice.git] / chart2 / source / view / axes / DateScaling.cxx
blob28b66633628d87c66118c4cb0b24a058145cf735
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "DateScaling.hxx"
21 #include <com/sun/star/chart/TimeUnit.hpp>
22 #include <rtl/math.hxx>
23 #include <com/sun/star/uno/RuntimeException.hpp>
24 #include <cppuhelper/supportsservice.hxx>
26 namespace
29 static const char lcl_aServiceName_DateScaling[] = "com.sun.star.chart2.DateScaling";
30 static const char lcl_aServiceName_InverseDateScaling[] = "com.sun.star.chart2.InverseDateScaling";
32 static const double lcl_fNumberOfMonths = 12.0;//todo: this needs to be offered by basic tools Date class if it should be more generic
35 namespace chart
37 using namespace ::com::sun::star;
38 using namespace ::com::sun::star::chart2;
39 using ::com::sun::star::chart::TimeUnit::DAY;
40 using ::com::sun::star::chart::TimeUnit::MONTH;
41 using ::com::sun::star::chart::TimeUnit::YEAR;
43 DateScaling::DateScaling( const Date& rNullDate, sal_Int32 nTimeUnit, bool bShifted )
44 : m_aNullDate( rNullDate )
45 , m_nTimeUnit( nTimeUnit )
46 , m_bShifted( bShifted )
50 DateScaling::~DateScaling()
54 double SAL_CALL DateScaling::doScaling( double value )
56 double fResult(value);
57 if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
58 ::rtl::math::setNan( & fResult );
59 else
61 Date aDate(m_aNullDate);
62 aDate.AddDays(::rtl::math::approxFloor(value));
63 switch( m_nTimeUnit )
65 case DAY:
66 fResult = value;
67 if(m_bShifted)
68 fResult+=0.5;
69 break;
70 case YEAR:
71 case MONTH:
72 default:
73 fResult = aDate.GetYear();
74 fResult *= lcl_fNumberOfMonths;//assuming equal count of months in each year
75 fResult += aDate.GetMonth();
77 double fDayOfMonth = aDate.GetDay();
78 fDayOfMonth -= 1.0;
79 double fDaysInMonth = aDate.GetDaysInMonth();
80 fResult += fDayOfMonth/fDaysInMonth;
81 if(m_bShifted)
83 if( m_nTimeUnit==YEAR )
84 fResult += 0.5*lcl_fNumberOfMonths;
85 else
86 fResult += 0.5;
88 break;
91 return fResult;
94 uno::Reference< XScaling > SAL_CALL DateScaling::getInverseScaling()
96 return new InverseDateScaling( m_aNullDate, m_nTimeUnit, m_bShifted );
99 OUString SAL_CALL DateScaling::getServiceName()
101 return OUString(lcl_aServiceName_DateScaling);
104 OUString SAL_CALL DateScaling::getImplementationName()
106 return OUString(lcl_aServiceName_DateScaling);
109 sal_Bool SAL_CALL DateScaling::supportsService( const OUString& rServiceName )
111 return cppu::supportsService(this, rServiceName);
114 css::uno::Sequence< OUString > SAL_CALL DateScaling::getSupportedServiceNames()
116 return { lcl_aServiceName_DateScaling };
119 InverseDateScaling::InverseDateScaling( const Date& rNullDate, sal_Int32 nTimeUnit, bool bShifted )
120 : m_aNullDate( rNullDate )
121 , m_nTimeUnit( nTimeUnit )
122 , m_bShifted( bShifted )
126 InverseDateScaling::~InverseDateScaling()
130 double SAL_CALL InverseDateScaling::doScaling( double value )
132 double fResult(value);
133 if( ::rtl::math::isNan( value ) || ::rtl::math::isInf( value ) )
134 ::rtl::math::setNan( & fResult );
135 else
137 switch( m_nTimeUnit )
139 case DAY:
140 if(m_bShifted)
141 value -= 0.5;
142 fResult = value;
143 break;
144 case YEAR:
145 case MONTH:
146 default:
147 //Date aDate(m_aNullDate);
148 if(m_bShifted)
150 if( m_nTimeUnit==YEAR )
151 value -= 0.5*lcl_fNumberOfMonths;
152 else
153 value -= 0.5;
155 Date aDate( Date::EMPTY );
156 double fYear = ::rtl::math::approxFloor(value/lcl_fNumberOfMonths);
157 double fMonth = ::rtl::math::approxFloor(value-(fYear*lcl_fNumberOfMonths));
158 if( fMonth==0.0 )
160 fYear--;
161 fMonth=12.0;
163 aDate.SetYear( static_cast<sal_uInt16>(fYear) );
164 aDate.SetMonth( static_cast<sal_uInt16>(fMonth) );
165 aDate.SetDay( 1 );
166 double fMonthCount = (fYear*lcl_fNumberOfMonths)+fMonth;
167 double fDay = (value-fMonthCount)*aDate.GetDaysInMonth();
168 fDay += 1.0;
169 aDate.SetDay( static_cast<sal_uInt16>(::rtl::math::round(fDay)) );
170 fResult = aDate - m_aNullDate;
171 break;
174 return fResult;
177 uno::Reference< XScaling > SAL_CALL InverseDateScaling::getInverseScaling()
179 return new DateScaling( m_aNullDate, m_nTimeUnit, m_bShifted );
182 OUString SAL_CALL InverseDateScaling::getServiceName()
184 return OUString(lcl_aServiceName_InverseDateScaling);
187 OUString SAL_CALL InverseDateScaling::getImplementationName()
189 return OUString(lcl_aServiceName_InverseDateScaling);
192 sal_Bool SAL_CALL InverseDateScaling::supportsService( const OUString& rServiceName )
194 return cppu::supportsService(this, rServiceName);
197 css::uno::Sequence< OUString > SAL_CALL InverseDateScaling::getSupportedServiceNames()
199 return { lcl_aServiceName_InverseDateScaling };
202 } //namespace chart
204 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */