diff options
author | Jens-Heiner Rechtien <hr@openoffice.org> | 2009-07-28 10:25:31 +0000 |
---|---|---|
committer | Jens-Heiner Rechtien <hr@openoffice.org> | 2009-07-28 10:25:31 +0000 |
commit | ab8dd2505c7486eed6f9ab9d4a4fba6e586ce81b (patch) | |
tree | 69f8546e6e783a489bb959c7479bebc944f88bd5 /chart2 | |
parent | 5099046dccb69af04e2a3adafad8e06c0832bd06 (diff) |
CWS-TOOLING: integrate CWS chart39
2009-06-30 16:55:46 +0200 iha r273522 : #i103209# im-/export attribute xlink:href at chart:chart element + some cleanup in naming
2009-06-30 16:45:59 +0200 iha r273521 : #i102701# apply patch for P1 issue on dev300m50 to be able to save again
2009-06-30 16:32:32 +0200 iha r273520 : #i103209# im-/export attribute xlink:href at chart:chart element + some cleanup in naming
2009-06-29 10:04:34 +0200 iha r273454 : #i103147# ODF, workaround broken files with a missing table:cell-range-address at the plot-area
2009-06-26 19:31:16 +0200 iha r273437 : #i103147# ODF, workaround broken files with a missing table:cell-range-address at the plot-area
2009-06-25 10:36:28 +0200 iha r273367 : #i101968# text values in data range cause incorrect x values
2009-06-24 17:34:18 +0200 iha r273357 : #i102428# x values are wrong in xy-scatter-chart with own data table if empty cells are contained in x values
2009-06-24 10:16:25 +0200 iha r273317 : #i99915# wrong matrix translation causes broken chart display for small values
2009-06-19 17:20:06 +0200 iha r273174 : #i78025# charts own borders are not completely visible
2009-06-19 17:18:41 +0200 iha r273172 : #i102950# don't paint additional borders for charts
2009-06-11 16:27:54 +0200 iha r272884 : CWS-TOOLING: rebase CWS chart39 to trunk@272827 (milestone: DEV300:m50)
2009-06-09 17:50:10 +0200 iha r272790 : #i97222# when converting a chart via API to 3D categories get lost and for line,area&xy the stacking mode is wrong
2009-06-09 16:00:27 +0200 iha r272775 : #i98319# data point properties get lost while copying charts from calc to impress
2009-06-09 10:26:51 +0200 iha r272755 : #i98392# correct orienation of gradient fillings on 3D walls
2009-05-29 10:35:16 +0200 iha r272436 : #i100529# Plot missing values - leave gap fails for smoothed lines
2009-05-04 18:20:31 +0200 iha r271478 : #i99841# Title with Vertically stacked attribute is wrong after editing
2009-05-04 18:03:01 +0200 iha r271477 : #i101050# avoid a corner in closed lines, which are smoothed by spline
2009-05-04 16:45:18 +0200 iha r271472 : #i101050# avoid crash in case the normals sequence has less points than the polygon
Diffstat (limited to 'chart2')
-rw-r--r-- | chart2/source/inc/ChartTypeHelper.hxx | 2 | ||||
-rw-r--r-- | chart2/source/inc/CommonFunctors.hxx | 5 | ||||
-rw-r--r-- | chart2/source/tools/ChartTypeHelper.cxx | 16 | ||||
-rw-r--r-- | chart2/source/tools/DiagramHelper.cxx | 18 | ||||
-rw-r--r-- | chart2/source/tools/TitleHelper.cxx | 36 | ||||
-rw-r--r-- | chart2/source/view/charttypes/Splines.cxx | 350 | ||||
-rw-r--r-- | chart2/source/view/diagram/VDiagram.cxx | 10 | ||||
-rw-r--r-- | chart2/source/view/inc/ShapeFactory.hxx | 2 | ||||
-rw-r--r-- | chart2/source/view/inc/Stripe.hxx | 2 | ||||
-rw-r--r-- | chart2/source/view/main/PlottingPositionHelper.cxx | 34 | ||||
-rw-r--r-- | chart2/source/view/main/ShapeFactory.cxx | 5 | ||||
-rw-r--r-- | chart2/source/view/main/Stripe.cxx | 47 | ||||
-rw-r--r-- | chart2/source/view/main/VDataSeries.cxx | 26 |
13 files changed, 342 insertions, 211 deletions
diff --git a/chart2/source/inc/ChartTypeHelper.hxx b/chart2/source/inc/ChartTypeHelper.hxx index e46aaa5406a5..df43e24a9482 100644 --- a/chart2/source/inc/ChartTypeHelper.hxx +++ b/chart2/source/inc/ChartTypeHelper.hxx @@ -95,6 +95,8 @@ public: static bool shouldLabelNumberFormatKeyBeDetectedFromYAxis( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType ); + + static bool isSupportingOnlyDeepStackingFor3D( const ::com::sun::star::uno::Reference< ::com::sun::star::chart2::XChartType >& xChartType ); }; //............................................................................. diff --git a/chart2/source/inc/CommonFunctors.hxx b/chart2/source/inc/CommonFunctors.hxx index 1c4a76efd229..2ec4efa41b8c 100644 --- a/chart2/source/inc/CommonFunctors.hxx +++ b/chart2/source/inc/CommonFunctors.hxx @@ -100,8 +100,11 @@ struct OOO_DLLPUBLIC_CHARTTOOLS AnyToString : public ::std::unary_function< ::co ::com::sun::star::uno::TypeClass eClass( rAny.getValueType().getTypeClass() ); if( eClass == ::com::sun::star::uno::TypeClass_DOUBLE ) { + const double* pDouble = reinterpret_cast< const double * >( rAny.getValue() ); + if( ::rtl::math::isNan(*pDouble) ) + return ::rtl::OUString(); return ::rtl::math::doubleToUString( - * reinterpret_cast< const double * >( rAny.getValue() ), + * pDouble, rtl_math_StringFormat_Automatic, -1, // use maximum decimal places available sal_Char( '.' ), // decimal separator diff --git a/chart2/source/tools/ChartTypeHelper.cxx b/chart2/source/tools/ChartTypeHelper.cxx index deecf6bfc4d8..357cf5c43d92 100644 --- a/chart2/source/tools/ChartTypeHelper.cxx +++ b/chart2/source/tools/ChartTypeHelper.cxx @@ -641,6 +641,22 @@ bool ChartTypeHelper::shouldLabelNumberFormatKeyBeDetectedFromYAxis( const uno:: return bRet; } +bool ChartTypeHelper::isSupportingOnlyDeepStackingFor3D( const uno::Reference< XChartType >& xChartType ) +{ + bool bRet = false; + if( !xChartType.is() ) + return bRet; + + rtl::OUString aChartTypeName = xChartType->getChartType(); + if( aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_LINE) || + aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER) || + aChartTypeName.match(CHART2_SERVICE_NAME_CHARTTYPE_AREA) ) + { + bRet = true; + } + return bRet; +} + //............................................................................. } //namespace chart //............................................................................. diff --git a/chart2/source/tools/DiagramHelper.cxx b/chart2/source/tools/DiagramHelper.cxx index 8af5b412c5c1..ac2a32f93298 100644 --- a/chart2/source/tools/DiagramHelper.cxx +++ b/chart2/source/tools/DiagramHelper.cxx @@ -503,8 +503,12 @@ void DiagramHelper::setDimension( try { - //change all coordinate systems: + bool rbFound = false; + bool rbAmbiguous = true; + StackMode eStackMode = DiagramHelper::getStackMode( xDiagram, rbFound, rbAmbiguous ); + bool bIsSupportingOnlyDeepStackingFor3D=false; + //change all coordinate systems: Reference< XCoordinateSystemContainer > xCooSysContainer( xDiagram, uno::UNO_QUERY_THROW ); Sequence< Reference< XCoordinateSystem > > aCooSysList( xCooSysContainer->getCoordinateSystems() ); for( sal_Int32 nCS = 0; nCS < aCooSysList.getLength(); ++nCS ) @@ -520,6 +524,7 @@ void DiagramHelper::setDimension( for( sal_Int32 nT = 0; nT < aChartTypeList.getLength(); ++nT ) { Reference< XChartType > xChartType( aChartTypeList[nT], uno::UNO_QUERY ); + bIsSupportingOnlyDeepStackingFor3D = ChartTypeHelper::isSupportingOnlyDeepStackingFor3D( xChartType ); if(!xNewCooSys.is()) { xNewCooSys = xChartType->createCoordinateSystem( nNewDimensionCount ); @@ -533,6 +538,12 @@ void DiagramHelper::setDimension( // replace the old coordinate system at all places where it was used DiagramHelper::replaceCoordinateSystem( xDiagram, xOldCooSys, xNewCooSys ); } + + //correct stack mode if necessary + if( nNewDimensionCount==3 && eStackMode != StackMode_Z_STACKED && bIsSupportingOnlyDeepStackingFor3D ) + DiagramHelper::setStackMode( xDiagram, StackMode_Z_STACKED ); + else if( nNewDimensionCount==2 && eStackMode == StackMode_Z_STACKED ) + DiagramHelper::setStackMode( xDiagram, StackMode_NONE ); } catch( uno::Exception & ex ) { @@ -556,6 +567,8 @@ void DiagramHelper::replaceCoordinateSystem( { try { + Reference< chart2::data::XLabeledDataSequence > xCategories = DiagramHelper::getCategoriesFromDiagram( xDiagram ); + // move chart types of xCooSysToReplace to xReplacement Reference< XChartTypeContainer > xCTCntCooSys( xCooSysToReplace, uno::UNO_QUERY_THROW ); Reference< XChartTypeContainer > xCTCntReplacement( xReplacement, uno::UNO_QUERY_THROW ); @@ -563,6 +576,9 @@ void DiagramHelper::replaceCoordinateSystem( xCont->removeCoordinateSystem( xCooSysToReplace ); xCont->addCoordinateSystem( xReplacement ); + + if( xCategories.is() ) + DiagramHelper::setCategoriesToDiagram( xCategories, xDiagram ); } catch( uno::Exception & ex ) { diff --git a/chart2/source/tools/TitleHelper.cxx b/chart2/source/tools/TitleHelper.cxx index 43006920951a..fe10c92e78cc 100644 --- a/chart2/source/tools/TitleHelper.cxx +++ b/chart2/source/tools/TitleHelper.cxx @@ -36,6 +36,7 @@ #include "AxisHelper.hxx" #include "DiagramHelper.hxx" #include <com/sun/star/chart2/XChartDocument.hpp> +#include <rtl/ustrbuf.hxx> //............................................................................. namespace chart @@ -269,13 +270,44 @@ void TitleHelper::setCompleteString( const rtl::OUString& rNewText if(!xTitle.is()) return; + rtl::OUString aNewText = rNewText; + + bool bStacked = false; + uno::Reference< beans::XPropertySet > xTitleProperties( xTitle, uno::UNO_QUERY ); + if( xTitleProperties.is() ) + xTitleProperties->getPropertyValue( C2U( "StackCharacters" ) ) >>= bStacked; + + if( bStacked ) + { + //#i99841# remove linebreaks that were added for vertical stacking + rtl::OUStringBuffer aUnstackedStr; + rtl::OUStringBuffer aSource(rNewText); + + bool bBreakIgnored = false; + sal_Int32 nLen = rNewText.getLength(); + for( sal_Int32 nPos = 0; nPos < nLen; ++nPos ) + { + sal_Unicode aChar = aSource.charAt( nPos ); + if( aChar != '\n' ) + { + aUnstackedStr.append( aChar ); + bBreakIgnored = false; + } + else if( aChar == '\n' && bBreakIgnored ) + aUnstackedStr.append( aChar ); + else + bBreakIgnored = true; + } + aNewText = aUnstackedStr.makeStringAndClear(); + } + uno::Sequence< uno::Reference< XFormattedString > > aNewStringList(1); uno::Sequence< uno::Reference< XFormattedString > > aOldStringList = xTitle->getText(); if( aOldStringList.getLength() ) { aNewStringList[0].set( aOldStringList[0] ); - aNewStringList[0]->setString( rNewText ); + aNewStringList[0]->setString( aNewText ); } else { @@ -286,7 +318,7 @@ void TitleHelper::setCompleteString( const rtl::OUString& rNewText if(xFormattedString.is()) { - xFormattedString->setString( rNewText ); + xFormattedString->setString( aNewText ); aNewStringList[0].set( xFormattedString ); if( pDefaultCharHeight != 0 ) { diff --git a/chart2/source/view/charttypes/Splines.cxx b/chart2/source/view/charttypes/Splines.cxx index a684b9a3228e..6d37d7444868 100644 --- a/chart2/source/view/charttypes/Splines.cxx +++ b/chart2/source/view/charttypes/Splines.cxx @@ -318,108 +318,133 @@ void SplineCalculater::CalculateCubicSplines( , sal_Int32 nGranularity ) { DBG_ASSERT( nGranularity > 0, "Granularity is invalid" ); + rResult.SequenceX.realloc(0); rResult.SequenceY.realloc(0); rResult.SequenceZ.realloc(0); - if( !rInput.SequenceX.getLength() ) + sal_Int32 nOuterCount = rInput.SequenceX.getLength();
+ if( !nOuterCount )
return; - if( rInput.SequenceX[0].getLength() <= 1 ) - return; //we need at least two points - - sal_Int32 nMaxIndexPoints = rInput.SequenceX[0].getLength()-1; // is >=1 - const double* pOldX = rInput.SequenceX[0].getConstArray(); - const double* pOldY = rInput.SequenceY[0].getConstArray(); - const double* pOldZ = rInput.SequenceZ[0].getConstArray(); - - // #i13699# The curve gets a parameter and then for each coordinate a - // separate spline will be calculated using the parameter as first argument - // and the point coordinate as second argument. Therefore the points need - // not to be sorted in its x-coordinates. The parameter is sorted by - // construction. - - ::std::vector < double > aParameter(nMaxIndexPoints+1); - aParameter[0]=0.0; - for( sal_Int32 nIndex=1; nIndex<=nMaxIndexPoints; nIndex++ ) - { - // The euclidian distance leads to curve loops for functions having single extreme points -// aParameter[nIndex]=aParameter[nIndex-1]+ -// sqrt( (pOldX[nIndex]-pOldX[nIndex-1])*(pOldX[nIndex]-pOldX[nIndex-1])+ -// (pOldY[nIndex]-pOldY[nIndex-1])*(pOldY[nIndex]-pOldY[nIndex-1])+ -// (pOldZ[nIndex]-pOldZ[nIndex-1])*(pOldZ[nIndex]-pOldZ[nIndex-1])); - - // use increment of 1 instead - aParameter[nIndex]=aParameter[nIndex-1]+1; - } - // Split the calculation to X, Y and Z coordinate - tPointVecType aInputX; - aInputX.resize(nMaxIndexPoints+1); - tPointVecType aInputY; - aInputY.resize(nMaxIndexPoints+1); - tPointVecType aInputZ; - aInputZ.resize(nMaxIndexPoints+1); - for (sal_Int32 nN=0;nN<=nMaxIndexPoints; nN++ ) - { - aInputX[ nN ].first=aParameter[nN]; - aInputX[ nN ].second=pOldX[ nN ]; - aInputY[ nN ].first=aParameter[nN]; - aInputY[ nN ].second=pOldY[ nN ]; - aInputZ[ nN ].first=aParameter[nN]; - aInputZ[ nN ].second=pOldZ[ nN ]; - } - // generate a spline for each coordinate. It holds the complete - // information to calculate each point of the curve - - // generate the kind "natural spline" - double fInfty; - ::rtl::math::setInf( &fInfty, sal_False ); - lcl_SplineCalculation aSplineX( aInputX, fInfty, fInfty ); - lcl_SplineCalculation aSplineY( aInputY, fInfty, fInfty ); - lcl_SplineCalculation aSplineZ( aInputZ, fInfty, fInfty ); - - // fill result polygon with calculated values - rResult.SequenceX.realloc(1); - rResult.SequenceY.realloc(1); - rResult.SequenceZ.realloc(1); - rResult.SequenceX[0].realloc( nMaxIndexPoints*nGranularity + 1); - rResult.SequenceY[0].realloc( nMaxIndexPoints*nGranularity + 1); - rResult.SequenceZ[0].realloc( nMaxIndexPoints*nGranularity + 1); - - double* pNewX = rResult.SequenceX[0].getArray(); - double* pNewY = rResult.SequenceY[0].getArray(); - double* pNewZ = rResult.SequenceZ[0].getArray(); - - sal_Int32 nNewPointIndex = 0; // Index in result points - // needed for inner loop - double fInc; // step for intermediate points - sal_Int32 nj; // for loop - double fParam; // a intermediate parameter value - - for( sal_Int32 ni = 0; ni < nMaxIndexPoints; ni++ ) - { - // given point is surely a curve point - pNewX[nNewPointIndex] = pOldX[ni]; - pNewY[nNewPointIndex] = pOldY[ni]; - pNewZ[nNewPointIndex] = pOldZ[ni]; - nNewPointIndex++; - - // calculate intermediate points - fInc = ( aParameter[ ni+1 ] - aParameter[ni] ) / static_cast< double >( nGranularity ); - for(nj = 1; nj < nGranularity; nj++) + rResult.SequenceX.realloc(nOuterCount);
+ rResult.SequenceY.realloc(nOuterCount);
+ rResult.SequenceZ.realloc(nOuterCount); + + for( sal_Int32 nOuter = 0; nOuter < nOuterCount; ++nOuter )
+ {
+ if( rInput.SequenceX[nOuter].getLength() <= 1 )
+ continue; //we need at least two points + + sal_Int32 nMaxIndexPoints = rInput.SequenceX[nOuter].getLength()-1; // is >=1 + const double* pOldX = rInput.SequenceX[nOuter].getConstArray(); + const double* pOldY = rInput.SequenceY[nOuter].getConstArray(); + const double* pOldZ = rInput.SequenceZ[nOuter].getConstArray(); + + // #i13699# The curve gets a parameter and then for each coordinate a + // separate spline will be calculated using the parameter as first argument + // and the point coordinate as second argument. Therefore the points need + // not to be sorted in its x-coordinates. The parameter is sorted by + // construction. + + ::std::vector < double > aParameter(nMaxIndexPoints+1); + aParameter[0]=0.0; + for( sal_Int32 nIndex=1; nIndex<=nMaxIndexPoints; nIndex++ ) + { + // The euclidian distance leads to curve loops for functions having single extreme points + //aParameter[nIndex]=aParameter[nIndex-1]+ + //sqrt( (pOldX[nIndex]-pOldX[nIndex-1])*(pOldX[nIndex]-pOldX[nIndex-1])+ + //(pOldY[nIndex]-pOldY[nIndex-1])*(pOldY[nIndex]-pOldY[nIndex-1])+ + //(pOldZ[nIndex]-pOldZ[nIndex-1])*(pOldZ[nIndex]-pOldZ[nIndex-1])); + + // use increment of 1 instead + aParameter[nIndex]=aParameter[nIndex-1]+1; + } + // Split the calculation to X, Y and Z coordinate + tPointVecType aInputX; + aInputX.resize(nMaxIndexPoints+1); + tPointVecType aInputY; + aInputY.resize(nMaxIndexPoints+1); + tPointVecType aInputZ; + aInputZ.resize(nMaxIndexPoints+1); + for (sal_Int32 nN=0;nN<=nMaxIndexPoints; nN++ ) { - fParam = aParameter[ni] + ( fInc * static_cast< double >( nj ) ); + aInputX[ nN ].first=aParameter[nN]; + aInputX[ nN ].second=pOldX[ nN ]; + aInputY[ nN ].first=aParameter[nN]; + aInputY[ nN ].second=pOldY[ nN ]; + aInputZ[ nN ].first=aParameter[nN]; + aInputZ[ nN ].second=pOldZ[ nN ]; + } - pNewX[nNewPointIndex]=aSplineX.GetInterpolatedValue( fParam ); - pNewY[nNewPointIndex]=aSplineY.GetInterpolatedValue( fParam ); - pNewZ[nNewPointIndex]=aSplineZ.GetInterpolatedValue( fParam ); + // generate a spline for each coordinate. It holds the complete + // information to calculate each point of the curve + double fXDerivation; + double fYDerivation; + double fZDerivation; + if( pOldX[ 0 ] == pOldX[nMaxIndexPoints] && + pOldY[ 0 ] == pOldY[nMaxIndexPoints] && + pOldZ[ 0 ] == pOldZ[nMaxIndexPoints] ) + { + // #i101050# avoid a corner in closed lines, which are smoothed by spline + // This derivation are special for parameter of kind 0,1,2,3... If you + // change generating parameters (see above), then adapt derivations too.) + fXDerivation = 0.5 * (pOldX[1]-pOldX[nMaxIndexPoints-1]); + fYDerivation = 0.5 * (pOldY[1]-pOldY[nMaxIndexPoints-1]); + fZDerivation = 0.5 * (pOldZ[1]-pOldZ[nMaxIndexPoints-1]); + } + else // generate the kind "natural spline" + { + double fInfty; + ::rtl::math::setInf( &fInfty, sal_False ); + fXDerivation = fInfty; + fYDerivation = fInfty; + fZDerivation = fInfty; + } + lcl_SplineCalculation aSplineX( aInputX, fXDerivation, fXDerivation ); + lcl_SplineCalculation aSplineY( aInputY, fYDerivation, fYDerivation ); + lcl_SplineCalculation aSplineZ( aInputZ, fZDerivation, fZDerivation ); + + // fill result polygon with calculated values + rResult.SequenceX[nOuter].realloc( nMaxIndexPoints*nGranularity + 1); + rResult.SequenceY[nOuter].realloc( nMaxIndexPoints*nGranularity + 1); + rResult.SequenceZ[nOuter].realloc( nMaxIndexPoints*nGranularity + 1); + + double* pNewX = rResult.SequenceX[nOuter].getArray(); + double* pNewY = rResult.SequenceY[nOuter].getArray(); + double* pNewZ = rResult.SequenceZ[nOuter].getArray(); + + sal_Int32 nNewPointIndex = 0; // Index in result points + // needed for inner loop + double fInc; // step for intermediate points + sal_Int32 nj; // for loop + double fParam; // a intermediate parameter value + + for( sal_Int32 ni = 0; ni < nMaxIndexPoints; ni++ ) + { + // given point is surely a curve point + pNewX[nNewPointIndex] = pOldX[ni]; + pNewY[nNewPointIndex] = pOldY[ni]; + pNewZ[nNewPointIndex] = pOldZ[ni]; nNewPointIndex++; + + // calculate intermediate points + fInc = ( aParameter[ ni+1 ] - aParameter[ni] ) / static_cast< double >( nGranularity ); + for(nj = 1; nj < nGranularity; nj++) + { + fParam = aParameter[ni] + ( fInc * static_cast< double >( nj ) ); + + pNewX[nNewPointIndex]=aSplineX.GetInterpolatedValue( fParam ); + pNewY[nNewPointIndex]=aSplineY.GetInterpolatedValue( fParam ); + pNewZ[nNewPointIndex]=aSplineZ.GetInterpolatedValue( fParam ); + nNewPointIndex++; + } } + // add last point + pNewX[nNewPointIndex] = pOldX[nMaxIndexPoints]; + pNewY[nNewPointIndex] = pOldY[nMaxIndexPoints]; + pNewZ[nNewPointIndex] = pOldZ[nMaxIndexPoints]; } - // add last point - pNewX[nNewPointIndex] = pOldX[nMaxIndexPoints]; - pNewY[nNewPointIndex] = pOldY[nMaxIndexPoints]; - pNewZ[nNewPointIndex] = pOldZ[nMaxIndexPoints]; } void SplineCalculater::CalculateBSplines( @@ -436,80 +461,85 @@ void SplineCalculater::CalculateBSplines( rResult.SequenceY.realloc(0); rResult.SequenceZ.realloc(0); - if( !rInput.SequenceX.getLength() ) + sal_Int32 nOuterCount = rInput.SequenceX.getLength();
+ if( !nOuterCount )
return; // no input - if( rInput.SequenceX[0].getLength() <= 1 ) - return; // need at least 2 control points - - sal_Int32 n = rInput.SequenceX[0].getLength()-1; // maximum index of control points - - double fCurveparam =0.0; // parameter for the curve - // 0<= fCurveparam < fMaxCurveparam - double fMaxCurveparam = 2.0+ n - k; - if (fMaxCurveparam <= 0.0) - return; // not enough control points for desired spline order - - if (nGranularity < 1) - return; //need at least 1 line for each part beween the control points - - const double* pOldX = rInput.SequenceX[0].getConstArray(); - const double* pOldY = rInput.SequenceY[0].getConstArray(); - const double* pOldZ = rInput.SequenceZ[0].getConstArray(); - - // keep this amount of steps to go well with old version - sal_Int32 nNewSectorCount = nGranularity * n; - double fCurveStep = fMaxCurveparam/static_cast< double >(nNewSectorCount); - - double *b = new double [n + k + 1]; // values of blending functions - - const double* t = createTVector(n, k); // knot vector - - rResult.SequenceX.realloc(1); - rResult.SequenceY.realloc(1); - rResult.SequenceZ.realloc(1); - rResult.SequenceX[0].realloc(nNewSectorCount+1); - rResult.SequenceY[0].realloc(nNewSectorCount+1); - rResult.SequenceZ[0].realloc(nNewSectorCount+1); - double* pNewX = rResult.SequenceX[0].getArray(); - double* pNewY = rResult.SequenceY[0].getArray(); - double* pNewZ = rResult.SequenceZ[0].getArray(); - - // variables needed inside loop, when calculating one point of output - sal_Int32 nPointIndex =0; //index of given contol points - double fX=0.0; - double fY=0.0; - double fZ=0.0; //coordinates of a new BSpline point - - for(sal_Int32 nNewSector=0; nNewSector<nNewSectorCount; nNewSector++) - { // in first looping fCurveparam has value 0.0 - - // Calculate the values of the blending functions for actual curve parameter - BVector(fCurveparam, n, k, b, t); - - // output point(fCurveparam) = sum over {input point * value of blending function} - fX = 0.0; - fY = 0.0; - fZ = 0.0; - for (nPointIndex=0;nPointIndex<=n;nPointIndex++) - { - fX +=pOldX[nPointIndex]*b[nPointIndex]; - fY +=pOldY[nPointIndex]*b[nPointIndex]; - fZ +=pOldZ[nPointIndex]*b[nPointIndex]; + rResult.SequenceX.realloc(nOuterCount);
+ rResult.SequenceY.realloc(nOuterCount);
+ rResult.SequenceZ.realloc(nOuterCount); + + for( sal_Int32 nOuter = 0; nOuter < nOuterCount; ++nOuter )
+ {
+ if( rInput.SequenceX[nOuter].getLength() <= 1 )
+ continue; // need at least 2 control points + + sal_Int32 n = rInput.SequenceX[nOuter].getLength()-1; // maximum index of control points + + double fCurveparam =0.0; // parameter for the curve + // 0<= fCurveparam < fMaxCurveparam + double fMaxCurveparam = 2.0+ n - k; + if (fMaxCurveparam <= 0.0) + return; // not enough control points for desired spline order + + if (nGranularity < 1) + return; //need at least 1 line for each part beween the control points + + const double* pOldX = rInput.SequenceX[nOuter].getConstArray(); + const double* pOldY = rInput.SequenceY[nOuter].getConstArray(); + const double* pOldZ = rInput.SequenceZ[nOuter].getConstArray(); + + // keep this amount of steps to go well with old version + sal_Int32 nNewSectorCount = nGranularity * n; + double fCurveStep = fMaxCurveparam/static_cast< double >(nNewSectorCount); + + double *b = new double [n + k + 1]; // values of blending functions + + const double* t = createTVector(n, k); // knot vector + + rResult.SequenceX[nOuter].realloc(nNewSectorCount+1); + rResult.SequenceY[nOuter].realloc(nNewSectorCount+1); + rResult.SequenceZ[nOuter].realloc(nNewSectorCount+1); + double* pNewX = rResult.SequenceX[nOuter].getArray(); + double* pNewY = rResult.SequenceY[nOuter].getArray(); + double* pNewZ = rResult.SequenceZ[nOuter].getArray(); + + // variables needed inside loop, when calculating one point of output + sal_Int32 nPointIndex =0; //index of given contol points + double fX=0.0; + double fY=0.0; + double fZ=0.0; //coordinates of a new BSpline point + + for(sal_Int32 nNewSector=0; nNewSector<nNewSectorCount; nNewSector++) + { // in first looping fCurveparam has value 0.0 + + // Calculate the values of the blending functions for actual curve parameter + BVector(fCurveparam, n, k, b, t); + + // output point(fCurveparam) = sum over {input point * value of blending function} + fX = 0.0; + fY = 0.0; + fZ = 0.0; + for (nPointIndex=0;nPointIndex<=n;nPointIndex++) + { + fX +=pOldX[nPointIndex]*b[nPointIndex]; + fY +=pOldY[nPointIndex]*b[nPointIndex]; + fZ +=pOldZ[nPointIndex]*b[nPointIndex]; + } + pNewX[nNewSector] = fX; + pNewY[nNewSector] = fY; + pNewZ[nNewSector] = fZ; + + fCurveparam += fCurveStep; //for next looping } - pNewX[nNewSector] = fX; - pNewY[nNewSector] = fY; - pNewZ[nNewSector] = fZ; + // add last control point to BSpline curve + pNewX[nNewSectorCount] = pOldX[n]; + pNewY[nNewSectorCount] = pOldY[n]; + pNewZ[nNewSectorCount] = pOldZ[n]; - fCurveparam += fCurveStep; //for next looping + delete[] t; + delete[] b; } - // add last control point to BSpline curve - pNewX[nNewSectorCount] = pOldX[n]; - pNewY[nNewSectorCount] = pOldY[n]; - pNewZ[nNewSectorCount] = pOldZ[n]; - - delete[] t; - delete[] b; } //............................................................................. diff --git a/chart2/source/view/diagram/VDiagram.cxx b/chart2/source/view/diagram/VDiagram.cxx index 70f930aa8623..5e0db2644cc5 100644 --- a/chart2/source/view/diagram/VDiagram.cxx +++ b/chart2/source/view/diagram/VDiagram.cxx @@ -553,13 +553,13 @@ void VDiagram::createShapes_3d() CuboidPlanePosition eLeftWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardLeftWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) ); if( CuboidPlanePosition_Right==eLeftWallPos ) xPos = FIXED_SIZE_FOR_3D_CHART_VOLUME; - Stripe aStripe( drawing::Position3D(xPos,0,0) - , drawing::Direction3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,0) + Stripe aStripe( drawing::Position3D(xPos,FIXED_SIZE_FOR_3D_CHART_VOLUME,0) + , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) , drawing::Direction3D(0,0,FIXED_SIZE_FOR_3D_CHART_VOLUME) ); uno::Reference< drawing::XShape > xShape = m_pShapeFactory->createStripe( xWallGroup_Shapes, aStripe - , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), true ); + , xWallProp, PropertyMapper::getPropertyNameMapForFillAndLineProperties(), true, true ); if( !bAddFloorAndWall ) { //we always need this object as dummy object for correct scene dimensions @@ -573,9 +573,9 @@ void VDiagram::createShapes_3d() CuboidPlanePosition eBackWallPos( ThreeDHelper::getAutomaticCuboidPlanePositionForStandardBackWall( uno::Reference< beans::XPropertySet >( m_xDiagram, uno::UNO_QUERY ) ) ); if( CuboidPlanePosition_Front==eBackWallPos ) zPos = FIXED_SIZE_FOR_3D_CHART_VOLUME; - Stripe aStripe( drawing::Position3D(0,0,zPos) + Stripe aStripe( drawing::Position3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,zPos) , drawing::Direction3D(FIXED_SIZE_FOR_3D_CHART_VOLUME,0,0) - , drawing::Direction3D(0,FIXED_SIZE_FOR_3D_CHART_VOLUME,0) ); + , drawing::Direction3D(0,-FIXED_SIZE_FOR_3D_CHART_VOLUME,0) ); uno::Reference< drawing::XShape > xShape = m_pShapeFactory->createStripe(xWallGroup_Shapes, aStripe diff --git a/chart2/source/view/inc/ShapeFactory.hxx b/chart2/source/view/inc/ShapeFactory.hxx index 7e7e564ab3b8..a03bbd3237d8 100644 --- a/chart2/source/view/inc/ShapeFactory.hxx +++ b/chart2/source/view/inc/ShapeFactory.hxx @@ -122,7 +122,7 @@ public: , const Stripe& rStripe , const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet >& xSourceProp , const tPropertyNameMap& rPropertyNameMap - , sal_Bool bDoubleSided = true); + , sal_Bool bDoubleSided = true, bool bRotatedTexture=false ); ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape > createArea3D( const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShapes >& xTarget diff --git a/chart2/source/view/inc/Stripe.hxx b/chart2/source/view/inc/Stripe.hxx index fe3a728daa02..dc017fc7aaba 100644 --- a/chart2/source/view/inc/Stripe.hxx +++ b/chart2/source/view/inc/Stripe.hxx @@ -65,7 +65,7 @@ public: ::com::sun::star::uno::Any getPolyPolygonShape3D() const; ::com::sun::star::uno::Any getNormalsPolygon() const; - ::com::sun::star::uno::Any getTexturePolygon() const; + ::com::sun::star::uno::Any getTexturePolygon( bool bRotatedTexture ) const; ::com::sun::star::drawing::Position3D GetPosition1() const { return m_aPoint1; } ::com::sun::star::drawing::Position3D GetPosition2() const { return m_aPoint2; } diff --git a/chart2/source/view/main/PlottingPositionHelper.cxx b/chart2/source/view/main/PlottingPositionHelper.cxx index 2d58a25f3808..e99c260c6d04 100644 --- a/chart2/source/view/main/PlottingPositionHelper.cxx +++ b/chart2/source/view/main/PlottingPositionHelper.cxx @@ -142,19 +142,6 @@ uno::Reference< XTransformation > PlottingPositionHelper::getTransformationScale std::swap(nXAxisOrientation,nYAxisOrientation); } - if( AxisOrientation_MATHEMATICAL==nXAxisOrientation ) - aMatrix.translate(-MinX, 0.0, 0.0); - else - aMatrix.translate(-MaxX, 0.0, 0.0); - if( AxisOrientation_MATHEMATICAL==nYAxisOrientation ) - aMatrix.translate(0.0, -MinY, 0.0); - else - aMatrix.translate(0.0, -MaxY, 0.0); - if( AxisOrientation_MATHEMATICAL==nZAxisOrientation ) - aMatrix.translate(0.0, 0.0, -MaxZ);//z direction in draw is reverse mathematical direction - else - aMatrix.translate(0.0, 0.0, -MinZ); - double fWidthX = MaxX - MinX; double fWidthY = MaxY - MinY; double fWidthZ = MaxZ - MinZ; @@ -163,9 +150,24 @@ uno::Reference< XTransformation > PlottingPositionHelper::getTransformationScale double fScaleDirectionY = AxisOrientation_MATHEMATICAL==nYAxisOrientation ? 1.0 : -1.0; double fScaleDirectionZ = AxisOrientation_MATHEMATICAL==nZAxisOrientation ? -1.0 : 1.0; - aMatrix.scale(fScaleDirectionX*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthX, - fScaleDirectionY*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthY, - fScaleDirectionZ*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthZ); + double fScaleX = fScaleDirectionX*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthX; + double fScaleY = fScaleDirectionY*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthY; + double fScaleZ = fScaleDirectionZ*FIXED_SIZE_FOR_3D_CHART_VOLUME/fWidthZ; + + aMatrix.scale(fScaleX, fScaleY, fScaleZ); + + if( AxisOrientation_MATHEMATICAL==nXAxisOrientation ) + aMatrix.translate(-MinX*fScaleX, 0.0, 0.0); + else + aMatrix.translate(-MaxX*fScaleX, 0.0, 0.0); + if( AxisOrientation_MATHEMATICAL==nYAxisOrientation ) + aMatrix.translate(0.0, -MinY*fScaleY, 0.0); + else + aMatrix.translate(0.0, -MaxY*fScaleY, 0.0); + if( AxisOrientation_MATHEMATICAL==nZAxisOrientation ) + aMatrix.translate(0.0, 0.0, -MaxZ*fScaleZ);//z direction in draw is reverse mathematical direction + else + aMatrix.translate(0.0, 0.0, -MinZ*fScaleZ); aMatrix = m_aMatrixScreenToScene*aMatrix; diff --git a/chart2/source/view/main/ShapeFactory.cxx b/chart2/source/view/main/ShapeFactory.cxx index 2e286499ccc3..8a19e66334fb 100644 --- a/chart2/source/view/main/ShapeFactory.cxx +++ b/chart2/source/view/main/ShapeFactory.cxx @@ -1023,7 +1023,8 @@ uno::Reference< drawing::XShape > , const Stripe& rStripe , const uno::Reference< beans::XPropertySet >& xSourceProp , const tPropertyNameMap& rPropertyNameMap - , sal_Bool bDoubleSided ) + , sal_Bool bDoubleSided + , bool bRotatedTexture ) { if( !xTarget.is() ) return 0; @@ -1047,7 +1048,7 @@ uno::Reference< drawing::XShape > //TexturePolygon xProp->setPropertyValue( C2U( UNO_NAME_3D_TEXTUREPOLYGON3D ) - , rStripe.getTexturePolygon() ); + , rStripe.getTexturePolygon( bRotatedTexture ) ); //Normals Polygon diff --git a/chart2/source/view/main/Stripe.cxx b/chart2/source/view/main/Stripe.cxx index 67b2396682aa..cb35e0e010b9 100644 --- a/chart2/source/view/main/Stripe.cxx +++ b/chart2/source/view/main/Stripe.cxx @@ -161,7 +161,7 @@ uno::Any Stripe::getNormalsPolygon() const return uno::Any( &aPP, ::getCppuType((const drawing::PolyPolygonShape3D*)0) ); } -uno::Any Stripe::getTexturePolygon() const +uno::Any Stripe::getTexturePolygon( bool bRotatedTexture ) const { drawing::PolyPolygonShape3D aPP; @@ -181,21 +181,42 @@ uno::Any Stripe::getTexturePolygon() const double* pInnerSequenceY = pOuterSequenceY->getArray(); double* pInnerSequenceZ = pOuterSequenceZ->getArray(); - *pInnerSequenceX++ = 0.0; - *pInnerSequenceY++ = 0.0; - *pInnerSequenceZ++ = 0.0; + if( !bRotatedTexture ) + { + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; - *pInnerSequenceX++ = 1.0; - *pInnerSequenceY++ = 0.0; - *pInnerSequenceZ++ = 0.0; + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; - *pInnerSequenceX++ = 1.0; - *pInnerSequenceY++ = 1.0; - *pInnerSequenceZ++ = 0.0; + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; + } + else + { + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; - *pInnerSequenceX++ = 0.0; - *pInnerSequenceY++ = 1.0; - *pInnerSequenceZ++ = 0.0; + *pInnerSequenceX++ = 1.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 1.0; + *pInnerSequenceZ++ = 0.0; + + *pInnerSequenceX++ = 0.0; + *pInnerSequenceY++ = 0.0; + *pInnerSequenceZ++ = 0.0; + } return uno::Any( &aPP, ::getCppuType((const drawing::PolyPolygonShape3D*)0) ); } diff --git a/chart2/source/view/main/VDataSeries.cxx b/chart2/source/view/main/VDataSeries.cxx index 76ba65e2e97d..d2456110b79b 100644 --- a/chart2/source/view/main/VDataSeries.cxx +++ b/chart2/source/view/main/VDataSeries.cxx @@ -124,20 +124,28 @@ struct lcl_LessXOfPoint } }; -void lcl_clearIfTextIsContained( VDataSequence& rData, const uno::Reference<data::XDataSequence>& xDataSequence ) +void lcl_clearIfNoValuesButTextIsContained( VDataSequence& rData, const uno::Reference<data::XDataSequence>& xDataSequence ) { + //#i71686#, #i101968#, #i102428# + sal_Int32 nCount = rData.Doubles.getLength(); + for( sal_Int32 i = 0; i < nCount; ++i ) + { + if( !::rtl::math::isNan( rData.Doubles[i] ) ) + return; + } + //no double value is countained + //is there any text? uno::Sequence< rtl::OUString > aStrings( DataSequenceToStringSequence( xDataSequence ) ); - for( sal_Int32 i = 0; i < rData.Doubles.getLength(); ++i ) + sal_Int32 nTextCount = aStrings.getLength(); + for( sal_Int32 j = 0; j < nTextCount; ++j ) { - if( ::rtl::math::isNan( rData.Doubles[i] ) ) + if( aStrings[j].getLength() ) { - if( i < aStrings.getLength() && aStrings[i].getLength() ) - { - rData.clear(); - break; - } + rData.clear(); + return; } } + //no content at all } void lcl_maybeReplaceNanWithZero( double& rfValue, sal_Int32 nMissingValueTreatment ) @@ -228,7 +236,7 @@ VDataSeries::VDataSeries( const uno::Reference< XDataSeries >& xDataSeries ) if( aRole.equals(C2U("values-x")) ) { m_aValues_X.init( xDataSequence ); - lcl_clearIfTextIsContained( m_aValues_X, xDataSequence ); + lcl_clearIfNoValuesButTextIsContained( m_aValues_X, xDataSequence ); } else if( aRole.equals(C2U("values-y")) ) m_aValues_Y.init( xDataSequence ); |