diff options
Diffstat (limited to 'chart2/source/view/charttypes/VSeriesPlotter.cxx')
-rwxr-xr-x[-rw-r--r--] | chart2/source/view/charttypes/VSeriesPlotter.cxx | 215 |
1 files changed, 149 insertions, 66 deletions
diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx b/chart2/source/view/charttypes/VSeriesPlotter.cxx index c37842e19888..1077591dfce8 100644..100755 --- a/chart2/source/view/charttypes/VSeriesPlotter.cxx +++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx @@ -75,6 +75,7 @@ #include <rtl/math.hxx> #include <tools/debug.hxx> #include <basegfx/vector/b2dvector.hxx> +#include <com/sun/star/drawing/LineStyle.hpp> #include <com/sun/star/util/XCloneable.hpp> #include <svx/unoshape.hxx> @@ -107,7 +108,6 @@ VDataSeriesGroup::VDataSeriesGroup() , m_bMaxPointCountDirty(true) , m_nMaxPointCount(0) , m_aListOfCachedYValues() - { } @@ -461,13 +461,30 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re //------------------------------------------------ //prepare legend symbol + float fViewFontSize( 10.0 ); + { + uno::Reference< beans::XPropertySet > xProps( rDataSeries.getPropertiesOfPoint( nPointIndex ) ); + if( xProps.is() ) + xProps->getPropertyValue( C2U( "CharHeight" )) >>= fViewFontSize; + // pt -> 1/100th mm + fViewFontSize *= (2540.0 / 72.0); + } Reference< drawing::XShape > xSymbol; if(pLabel->ShowLegendSymbol) { + sal_Int32 nSymbolHeigth = static_cast< sal_Int32 >( fViewFontSize * 0.6 ); + awt::Size aCurrentRatio = this->getPreferredLegendKeyAspectRatio(); + sal_Int32 nSymbolWidth = aCurrentRatio.Width; + if( aCurrentRatio.Height > 0 ) + { + nSymbolWidth = nSymbolHeigth* aCurrentRatio.Width/aCurrentRatio.Height; + } + awt::Size aMaxSymbolExtent( nSymbolWidth, nSymbolHeigth ); + if( rDataSeries.isVaryColorsByPoint() ) - xSymbol.set( VSeriesPlotter::createLegendSymbolForPoint( rDataSeries, nPointIndex, xTarget_, m_xShapeFactory ) ); + xSymbol.set( VSeriesPlotter::createLegendSymbolForPoint( aMaxSymbolExtent, rDataSeries, nPointIndex, xTarget_, m_xShapeFactory ) ); else - xSymbol.set( VSeriesPlotter::createLegendSymbolForSeries( rDataSeries, xTarget_, m_xShapeFactory ) ); + xSymbol.set( VSeriesPlotter::createLegendSymbolForSeries( aMaxSymbolExtent, rDataSeries, xTarget_, m_xShapeFactory ) ); } //prepare text @@ -567,25 +584,14 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re const awt::Point aOldTextPos( xTextShape->getPosition() ); awt::Point aNewTextPos( aOldTextPos ); + awt::Point aSymbolPosition( aUnrotatedTextPos ); awt::Size aSymbolSize( xSymbol->getSize() ); awt::Size aTextSize( xTextShape->getSize() ); + sal_Int32 nXDiff = aSymbolSize.Width + static_cast< sal_Int32 >( std::max( 100.0, fViewFontSize * 0.22 ) );//minimum 1mm if( !bMultiLineLabel || nLineCountForSymbolsize <= 0 ) nLineCountForSymbolsize = 1; - sal_Int32 nYDiff = aTextSize.Height/nLineCountForSymbolsize; - sal_Int32 nXDiff = aSymbolSize.Width * nYDiff/aSymbolSize.Height; - - // #i109336# Improve auto positioning in chart - nXDiff = nXDiff * 80 / 100; - nYDiff = nYDiff * 80 / 100; - - aSymbolSize.Width = nXDiff * 75/100; - aSymbolSize.Height = nYDiff * 75/100; - - awt::Point aSymbolPosition( aUnrotatedTextPos ); - - // #i109336# Improve auto positioning in chart - aSymbolPosition.Y += ( nYDiff / 4 ); + aSymbolPosition.Y += ((aTextSize.Height/nLineCountForSymbolsize)/4); if(LABEL_ALIGN_LEFT==eAlignment || LABEL_ALIGN_LEFT_TOP==eAlignment @@ -607,10 +613,7 @@ uno::Reference< drawing::XShape > VSeriesPlotter::createDataLabel( const uno::Re aNewTextPos.X += nXDiff/2; } - xSymbol->setSize( aSymbolSize ); xSymbol->setPosition( aSymbolPosition ); - - //set position xTextShape->setPosition( aNewTextPos ); } } @@ -1818,13 +1821,14 @@ bool VSeriesPlotter::shouldSnapRectToUsedArea() return true; } -Sequence< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntries( - LegendExpansion eLegendExpansion +std::vector< ViewLegendEntry > VSeriesPlotter::createLegendEntries( + const awt::Size& rEntryKeyAspectRatio + , ::com::sun::star::chart::ChartLegendExpansion eLegendExpansion , const Reference< beans::XPropertySet >& xTextProperties , const Reference< drawing::XShapes >& xTarget , const Reference< lang::XMultiServiceFactory >& xShapeFactory , const Reference< uno::XComponentContext >& xContext - ) throw (uno::RuntimeException) + ) { std::vector< ViewLegendEntry > aResult; @@ -1851,7 +1855,7 @@ Sequence< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntries( if(!pSeries) continue; - std::vector< ViewLegendEntry > aSeriesEntries( this->createLegendEntriesForSeries( + std::vector< ViewLegendEntry > aSeriesEntries( this->createLegendEntriesForSeries( rEntryKeyAspectRatio, *pSeries, xTextProperties, xTarget, xShapeFactory, xContext ) ); //add series entries to the result now @@ -1865,7 +1869,7 @@ Sequence< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntries( // If the legend is wide and we have a stacked bar-chart the normal order // is the correct one bool bReverse = false; - if( eLegendExpansion != LegendExpansion_WIDE ) + if( eLegendExpansion != ::com::sun::star::chart::ChartLegendExpansion_WIDE ) { StackingDirection eStackingDirection( pSeries->getStackingDirection() ); bReverse = ( eStackingDirection == StackingDirection_Y_STACKING ); @@ -1880,24 +1884,119 @@ Sequence< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntries( } } } + } - //add charttype specific entries if any + return aResult; +} + +::std::vector< VDataSeries* > VSeriesPlotter::getAllSeries() +{ + ::std::vector< VDataSeries* > aAllSeries; + ::std::vector< ::std::vector< VDataSeriesGroup > >::iterator aZSlotIter = m_aZSlots.begin(); + const ::std::vector< ::std::vector< VDataSeriesGroup > >::const_iterator aZSlotEnd = m_aZSlots.end(); + for( ; aZSlotIter != aZSlotEnd; aZSlotIter++ ) + { + ::std::vector< VDataSeriesGroup >::iterator aXSlotIter = aZSlotIter->begin(); + const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = aZSlotIter->end(); + for( ; aXSlotIter != aXSlotEnd; aXSlotIter++ ) { - std::vector< ViewLegendEntry > aChartTypeEntries( this->createLegendEntriesForChartType( - xTextProperties, xTarget, xShapeFactory, xContext ) ); - aResult.insert( aResult.end(), aChartTypeEntries.begin(), aChartTypeEntries.end() ); + ::std::vector< VDataSeries* > aSeriesList = aXSlotIter->m_aSeriesVector; + aAllSeries.insert( aAllSeries.end(), aSeriesList.begin(), aSeriesList.end() ); } } - - return ::chart::ContainerHelper::ContainerToSequence( aResult ); + return aAllSeries; } +namespace +{ +bool lcl_HasVisibleLine( const uno::Reference< beans::XPropertySet >& xProps, bool& rbHasDashedLine ) +{ + bool bHasVisibleLine = false; + rbHasDashedLine = false; + drawing::LineStyle aLineStyle = drawing::LineStyle_NONE; + if( xProps.is() && ( xProps->getPropertyValue( C2U("LineStyle")) >>= aLineStyle ) ) + { + if( aLineStyle != drawing::LineStyle_NONE ) + bHasVisibleLine = true; + if( aLineStyle == drawing::LineStyle_DASH ) + rbHasDashedLine = true; + } + return bHasVisibleLine; +} +bool lcl_HasRegressionCurves( const VDataSeries& rSeries, bool& rbHasDashedLine ) +{ + bool bHasRegressionCurves = false; + Reference< XRegressionCurveContainer > xRegrCont( rSeries.getModel(), uno::UNO_QUERY ); + if( xRegrCont.is()) + { + Sequence< Reference< XRegressionCurve > > aCurves( xRegrCont->getRegressionCurves() ); + sal_Int32 i = 0, nCount = aCurves.getLength(); + for( i=0; i<nCount; ++i ) + { + if( aCurves[i].is() ) + { + bHasRegressionCurves = true; + lcl_HasVisibleLine( uno::Reference< beans::XPropertySet >( aCurves[i], uno::UNO_QUERY ), rbHasDashedLine ); + } + } + } + return bHasRegressionCurves; +} +} LegendSymbolStyle VSeriesPlotter::getLegendSymbolStyle() { - return chart2::LegendSymbolStyle_BOX; + return LegendSymbolStyle_BOX; } +awt::Size VSeriesPlotter::getPreferredLegendKeyAspectRatio() +{ + awt::Size aRet(1000,1000); + if( m_nDimension==3 ) + return aRet; + + bool bSeriesAllowsLines = (getLegendSymbolStyle() == LegendSymbolStyle_LINE); + bool bHasLines = false; + bool bHasDashedLines = false; + ::std::vector< VDataSeries* > aAllSeries( getAllSeries() ); + ::std::vector< VDataSeries* >::const_iterator aSeriesIter = aAllSeries.begin(); + const ::std::vector< VDataSeries* >::const_iterator aSeriesEnd = aAllSeries.end(); + //iterate through all series + for( ; aSeriesIter != aSeriesEnd; aSeriesIter++ ) + { + if( bSeriesAllowsLines ) + { + bool bCurrentDashed = false; + if( lcl_HasVisibleLine( (*aSeriesIter)->getPropertiesOfSeries(), bCurrentDashed ) ) + { + bHasLines = true; + if( bCurrentDashed ) + { + bHasDashedLines = true; + break; + } + } + } + bool bRegressionHasDashedLines=false; + if( lcl_HasRegressionCurves( **aSeriesIter, bRegressionHasDashedLines ) ) + { + bHasLines = true; + if( bRegressionHasDashedLines ) + { + bHasDashedLines = true; + break; + } + } + } + if( bHasLines ) + { + if( bHasDashedLines ) + aRet = awt::Size(1600,-1); + else + aRet = awt::Size(800,-1); + } + return aRet; +} uno::Any VSeriesPlotter::getExplicitSymbol( const VDataSeries& /*rSeries*/, sal_Int32 /*nPointIndex*/ ) { @@ -1905,7 +2004,8 @@ uno::Any VSeriesPlotter::getExplicitSymbol( const VDataSeries& /*rSeries*/, sal_ } Reference< drawing::XShape > VSeriesPlotter::createLegendSymbolForSeries( - const VDataSeries& rSeries + const awt::Size& rEntryKeyAspectRatio + , const VDataSeries& rSeries , const Reference< drawing::XShapes >& xTarget , const Reference< lang::XMultiServiceFactory >& xShapeFactory ) { @@ -1920,17 +2020,13 @@ Reference< drawing::XShape > VSeriesPlotter::createLegendSymbolForSeries( // legend-symbol type switch( eLegendSymbolStyle ) { - case LegendSymbolStyle_HORIZONTAL_LINE: - case LegendSymbolStyle_VERTICAL_LINE: - case LegendSymbolStyle_DIAGONAL_LINE: - case LegendSymbolStyle_LINE_WITH_BOX: - case LegendSymbolStyle_LINE_WITH_SYMBOL: + case LegendSymbolStyle_LINE: ePropType = VLegendSymbolFactory::PROP_TYPE_LINE_SERIES; break; default: break; }; - Reference< drawing::XShape > xShape( VLegendSymbolFactory::createSymbol( + Reference< drawing::XShape > xShape( VLegendSymbolFactory::createSymbol( rEntryKeyAspectRatio, xTarget, eLegendSymbolStyle, xShapeFactory , rSeries.getPropertiesOfSeries(), ePropType, aExplicitSymbol )); @@ -1938,7 +2034,8 @@ Reference< drawing::XShape > VSeriesPlotter::createLegendSymbolForSeries( } Reference< drawing::XShape > VSeriesPlotter::createLegendSymbolForPoint( - const VDataSeries& rSeries + const awt::Size& rEntryKeyAspectRatio + , const VDataSeries& rSeries , sal_Int32 nPointIndex , const Reference< drawing::XShapes >& xTarget , const Reference< lang::XMultiServiceFactory >& xShapeFactory ) @@ -1954,11 +2051,7 @@ Reference< drawing::XShape > VSeriesPlotter::createLegendSymbolForPoint( // legend-symbol type switch( eLegendSymbolStyle ) { - case LegendSymbolStyle_HORIZONTAL_LINE: - case LegendSymbolStyle_VERTICAL_LINE: - case LegendSymbolStyle_DIAGONAL_LINE: - case LegendSymbolStyle_LINE_WITH_BOX: - case LegendSymbolStyle_LINE_WITH_SYMBOL: + case LegendSymbolStyle_LINE: ePropType = VLegendSymbolFactory::PROP_TYPE_LINE_SERIES; break; default: @@ -1989,14 +2082,15 @@ Reference< drawing::XShape > VSeriesPlotter::createLegendSymbolForPoint( } } - Reference< drawing::XShape > xShape( VLegendSymbolFactory::createSymbol( + Reference< drawing::XShape > xShape( VLegendSymbolFactory::createSymbol( rEntryKeyAspectRatio, xTarget, eLegendSymbolStyle, xShapeFactory, xPointSet, ePropType, aExplicitSymbol )); return xShape; } -std::vector< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntriesForSeries( - const VDataSeries& rSeries +std::vector< ViewLegendEntry > VSeriesPlotter::createLegendEntriesForSeries( + const awt::Size& rEntryKeyAspectRatio + , const VDataSeries& rSeries , const Reference< beans::XPropertySet >& xTextProperties , const Reference< drawing::XShapes >& xTarget , const Reference< lang::XMultiServiceFactory >& xShapeFactory @@ -2025,7 +2119,7 @@ std::vector< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntriesForSe uno::Reference< drawing::XShapes > xSymbolGroup( ShapeFactory(xShapeFactory).createGroup2D( xTarget )); // create the symbol - Reference< drawing::XShape > xShape( this->createLegendSymbolForPoint( + Reference< drawing::XShape > xShape( this->createLegendSymbolForPoint( rEntryKeyAspectRatio, rSeries, nIdx, xSymbolGroup, xShapeFactory ) ); // set CID to symbol for selection @@ -2055,7 +2149,7 @@ std::vector< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntriesForSe // create the symbol Reference< drawing::XShape > xShape( this->createLegendSymbolForSeries( - rSeries, xSymbolGroup, xShapeFactory ) ); + rEntryKeyAspectRatio, rSeries, xSymbolGroup, xShapeFactory ) ); // set CID to symbol for selection if( xShape.is()) @@ -2085,11 +2179,10 @@ std::vector< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntriesForSe sal_Int32 i = 0, nCount = aCurves.getLength(); for( i=0; i<nCount; ++i ) { - if( aCurves[i].is() && !RegressionCurveHelper::isMeanValueLine( aCurves[i] ) ) + if( aCurves[i].is() ) { //label - OUString aResStr( SchResId::getResString( STR_STATISTICS_IN_LEGEND )); - replaceParamterInString( aResStr, C2U("%REGRESSIONCURVE"), RegressionCurveHelper::getUINameForRegressionCurve( aCurves[i] )); + OUString aResStr( RegressionCurveHelper::getUINameForRegressionCurve( aCurves[i] ) ); replaceParamterInString( aResStr, C2U("%SERIESNAME"), aLabelText ); aEntry.aLabel = FormattedStringHelper::createFormattedStringSequence( xContext, aResStr, xTextProperties ); @@ -2097,8 +2190,8 @@ std::vector< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntriesForSe uno::Reference< drawing::XShapes > xSymbolGroup( ShapeFactory(xShapeFactory).createGroup2D( xTarget )); // create the symbol - Reference< drawing::XShape > xShape( VLegendSymbolFactory::createSymbol( - xSymbolGroup, chart2::LegendSymbolStyle_DIAGONAL_LINE, xShapeFactory, + Reference< drawing::XShape > xShape( VLegendSymbolFactory::createSymbol( rEntryKeyAspectRatio, + xSymbolGroup, LegendSymbolStyle_LINE, xShapeFactory, Reference< beans::XPropertySet >( aCurves[i], uno::UNO_QUERY ), VLegendSymbolFactory::PROP_TYPE_LINE, uno::Any() )); @@ -2107,7 +2200,7 @@ std::vector< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntriesForSe { aEntry.aSymbol = uno::Reference< drawing::XShape >( xSymbolGroup, uno::UNO_QUERY ); - bool bAverageLine = false;//@todo find out wether this is an average line or a regression curve + bool bAverageLine = RegressionCurveHelper::isMeanValueLine( aCurves[i] ); ObjectType eObjectType = bAverageLine ? OBJECTTYPE_DATA_AVERAGE_LINE : OBJECTTYPE_DATA_CURVE; OUString aChildParticle( ObjectIdentifier::createChildParticleWithIndex( eObjectType, i ) ); aChildParticle = ObjectIdentifier::addChildParticle( aChildParticle, ObjectIdentifier::createChildParticleWithIndex( OBJECTTYPE_LEGEND_ENTRY, 0 ) ); @@ -2127,16 +2220,6 @@ std::vector< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntriesForSe return aResult; } -std::vector< ViewLegendEntry > SAL_CALL VSeriesPlotter::createLegendEntriesForChartType( - const Reference< beans::XPropertySet >& /* xTextProperties */, - const Reference< drawing::XShapes >& /* xTarget */, - const Reference< lang::XMultiServiceFactory >& /* xShapeFactory */, - const Reference< uno::XComponentContext >& /* xContext */ - ) -{ - return std::vector< ViewLegendEntry >(); -} - VSeriesPlotter* VSeriesPlotter::createSeriesPlotter( const uno::Reference<XChartType>& xChartTypeModel , sal_Int32 nDimensionCount |