diff options
Diffstat (limited to 'chart2/source/view/charttypes/VSeriesPlotter.cxx')
-rw-r--r-- | chart2/source/view/charttypes/VSeriesPlotter.cxx | 383 |
1 files changed, 267 insertions, 116 deletions
diff --git a/chart2/source/view/charttypes/VSeriesPlotter.cxx b/chart2/source/view/charttypes/VSeriesPlotter.cxx index af54871ff49d..b9773494d785 100644 --- a/chart2/source/view/charttypes/VSeriesPlotter.cxx +++ b/chart2/source/view/charttypes/VSeriesPlotter.cxx @@ -17,6 +17,7 @@ * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ +#include <cstddef> #include <limits> #include <memory> #include <VSeriesPlotter.hxx> @@ -25,18 +26,23 @@ #include <ShapeFactory.hxx> #include <Diagram.hxx> #include <BaseCoordinateSystem.hxx> +#include <DataSeries.hxx> +#include <DataSeriesProperties.hxx> #include <CommonConverters.hxx> #include <ExplicitCategoriesProvider.hxx> +#include <FormattedString.hxx> #include <ObjectIdentifier.hxx> #include <StatisticsHelper.hxx> #include <PlottingPositionHelper.hxx> #include <LabelPositionHelper.hxx> +#include <ChartType.hxx> #include <ChartTypeHelper.hxx> #include <Clipping.hxx> #include <servicenames_charttypes.hxx> #include <NumberFormatterWrapper.hxx> #include <DataSeriesHelper.hxx> +#include <RegressionCurveModel.hxx> #include <RegressionCurveHelper.hxx> #include <VLegendSymbolFactory.hxx> #include <FormattedStringHelper.hxx> @@ -61,9 +67,9 @@ #include <com/sun/star/chart/TimeUnit.hpp> #include <com/sun/star/chart2/MovingAverageType.hpp> #include <com/sun/star/chart2/XDataPointCustomLabelField.hpp> -#include <com/sun/star/chart2/XRegressionCurveContainer.hpp> #include <com/sun/star/container/XChild.hpp> #include <com/sun/star/chart2/RelativePosition.hpp> +#include <o3tl/safeint.hxx> #include <tools/color.hxx> #include <tools/UnitConversion.hxx> #include <rtl/ustrbuf.hxx> @@ -71,13 +77,13 @@ #include <basegfx/vector/b2dvector.hxx> #include <com/sun/star/drawing/LineStyle.hpp> #include <com/sun/star/util/XCloneable.hpp> -#include <com/sun/star/chart2/XCoordinateSystemContainer.hpp> #include <unotools/localedatawrapper.hxx> #include <comphelper/sequence.hxx> +#include <utility> #include <vcl/svapp.hxx> #include <vcl/settings.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <sal/log.hxx> #include <functional> @@ -90,6 +96,7 @@ namespace chart { using namespace ::com::sun::star; using namespace ::com::sun::star::chart; using namespace ::com::sun::star::chart2; +using namespace ::chart::DataSeriesProperties; using ::com::sun::star::uno::Reference; using ::com::sun::star::uno::Sequence; @@ -137,12 +144,11 @@ sal_Int32 VDataSeriesGroup::getSeriesCount() const return m_aSeriesVector.size(); } -VSeriesPlotter::VSeriesPlotter( const uno::Reference<XChartType>& xChartTypeModel +VSeriesPlotter::VSeriesPlotter( rtl::Reference<ChartType> xChartTypeModel , sal_Int32 nDimensionCount, bool bCategoryXAxis ) : PlotterBase( nDimensionCount ) , m_pMainPosHelper( nullptr ) - , m_xChartTypeModel(xChartTypeModel) - , m_xChartTypeModelProps( uno::Reference< beans::XPropertySet >::query( xChartTypeModel )) + , m_xChartTypeModel(std::move(xChartTypeModel)) , m_bCategoryXAxis(bCategoryXAxis) , m_nTimeResolution(css::chart::TimeUnit::DAY) , m_aNullDate(30,12,1899) @@ -193,7 +199,7 @@ void VSeriesPlotter::addSeries( std::unique_ptr<VDataSeries> pSeries, sal_Int32 pSeries->setXValuesIfNone( m_pExplicitCategoriesProvider->getOriginalCategories() ); } - if(zSlot<0 || zSlot>=static_cast<sal_Int32>(m_aZSlots.size())) + if(zSlot<0 || o3tl::make_unsigned(zSlot)>=m_aZSlots.size()) { //new z slot std::vector< VDataSeriesGroup > aZSlot; @@ -205,7 +211,7 @@ void VSeriesPlotter::addSeries( std::unique_ptr<VDataSeries> pSeries, sal_Int32 //existing zslot std::vector< VDataSeriesGroup >& rXSlots = m_aZSlots[zSlot]; - if(xSlot<0 || xSlot>=static_cast<sal_Int32>(rXSlots.size())) + if(xSlot<0 || o3tl::make_unsigned(xSlot)>=rXSlots.size()) { //append the series to already existing x series rXSlots.emplace_back( std::move(pSeries) ); @@ -513,8 +519,8 @@ rtl::Reference<SvxShapeText> VSeriesPlotter::createDataLabel( const rtl::Referen OUString aRole; if ( m_xChartTypeModel ) aRole = m_xChartTypeModel->getRoleOfSequenceForSeriesLabel(); - const uno::Reference< XDataSeries >& xSeries( rDataSeries.getModel() ); - pTextList[i] = DataSeriesHelper::getDataSeriesLabel( xSeries, aRole ); + const rtl::Reference< DataSeries >& xSeries( rDataSeries.getModel() ); + pTextList[i] = xSeries->getLabelForRole( aRole ); break; } case DataPointCustomLabelFieldType_PERCENTAGE: @@ -571,8 +577,8 @@ rtl::Reference<SvxShapeText> VSeriesPlotter::createDataLabel( const rtl::Referen OUString aRole; if ( m_xChartTypeModel ) aRole = m_xChartTypeModel->getRoleOfSequenceForSeriesLabel(); - const uno::Reference< XDataSeries >& xSeries( rDataSeries.getModel() ); - pTextList[1] = DataSeriesHelper::getDataSeriesLabel( xSeries, aRole ); + const rtl::Reference< DataSeries >& xSeries( rDataSeries.getModel() ); + pTextList[1] = xSeries->getLabelForRole( aRole ); } if( pLabel->ShowNumber ) @@ -592,7 +598,7 @@ rtl::Reference<SvxShapeText> VSeriesPlotter::createDataLabel( const rtl::Referen } } - for( auto const & line : std::as_const(aTextList) ) + for (auto const& line : aTextList) { if( !line.isEmpty() ) { @@ -698,26 +704,20 @@ rtl::Reference<SvxShapeText> VSeriesPlotter::createDataLabel( const rtl::Referen { xTextShape->setPosition(aRelPos); if( !m_xChartTypeModel->getChartType().equalsIgnoreAsciiCase(CHART2_SERVICE_NAME_CHARTTYPE_PIE) && - rDataSeries.getPropertiesOfSeries()->getPropertyValue( "ShowCustomLeaderLines" ).get<sal_Bool>()) + // "ShowCustomLeaderLines" + rDataSeries.getModel()->getFastPropertyValue( PROP_DATASERIES_SHOW_CUSTOM_LEADERLINES ).get<sal_Bool>()) { + const basegfx::B2IRectangle aRect( + BaseGFXHelper::makeRectangle(aRelPos, xTextShape->getSize())); sal_Int32 nX1 = rScreenPosition2D.X; sal_Int32 nY1 = rScreenPosition2D.Y; - sal_Int32 nX2 = nX1; - sal_Int32 nY2 = nY1; - ::basegfx::B2IRectangle aRect(BaseGFXHelper::makeRectangle(aRelPos, xTextShape->getSize())); - if (nX1 < aRelPos.X) - nX2 = aRelPos.X; - else if (nX1 > aRect.getMaxX()) - nX2 = aRect.getMaxX(); - - if (nY1 < aRect.getMinY()) - nY2 = aRect.getMinY(); - else if (nY1 > aRect.getMaxY()) - nY2 = aRect.getMaxY(); + const sal_Int32 nX2 = std::clamp(nX1, aRelPos.X, aRect.getMaxX()); + const sal_Int32 nY2 = std::clamp(nY1, aRect.getMinY(), aRect.getMaxY()); //when the line is very short compared to the page size don't create one ::basegfx::B2DVector aLength(nX1 - nX2, nY1 - nY2); - double fPageDiagonaleLength = sqrt(double(m_aPageReferenceSize.Width)*double(m_aPageReferenceSize.Width) + double(m_aPageReferenceSize.Height)*double(m_aPageReferenceSize.Height)); + double fPageDiagonaleLength + = std::hypot(m_aPageReferenceSize.Width, m_aPageReferenceSize.Height); if ((aLength.getLength() / fPageDiagonaleLength) >= 0.01) { drawing::PointSequenceSequence aPoints{ { {nX1, nY1}, {nX2, nY2} } }; @@ -731,13 +731,11 @@ rtl::Reference<SvxShapeText> VSeriesPlotter::createDataLabel( const rtl::Referen // in case legend symbol has to be displayed, text shape position is // slightly changed. - const awt::Point aUnrotatedTextPos(xTextShape->getPosition()); if( xSymbol.is() ) { - const awt::Point aOldTextPos( xTextShape->getPosition() ); - awt::Point aNewTextPos( aOldTextPos ); + awt::Point aNewTextPos(xTextShape->getPosition()); - awt::Point aSymbolPosition( aUnrotatedTextPos ); + awt::Point aSymbolPosition(aNewTextPos); awt::Size aSymbolSize( xSymbol->getSize() ); awt::Size aTextSize = xTextShape->getSize(); @@ -1041,7 +1039,21 @@ void VSeriesPlotter::createErrorBar( fLocalX-=fLength; aNegative = m_pPosHelper->transformLogicToScene( fLocalX, fLocalY, fZ, true ); } - bCreateNegativeBorder = m_pPosHelper->isLogicVisible( fLocalX, fLocalY, fZ); + if (std::isfinite(aNegative.PositionX) && + std::isfinite(aNegative.PositionY) && + std::isfinite(aNegative.PositionZ)) { + bCreateNegativeBorder = m_pPosHelper->isLogicVisible( fLocalX, fLocalY, fZ); + } else { + // If error bars result in a numerical problem (e.g., an + // error bar on a logarithmic chart that results in a point + // <= 0) then just turn off the error bar. + // + // TODO: This perhaps should display a warning, so the user + // knows why a bar is not appearing. + // TODO: This test could also be added to the positive case, + // though a numerical overflow there is less likely. + bShowNegative = false; + } } else bShowNegative = false; @@ -1088,10 +1100,7 @@ void VSeriesPlotter::addErrorBorder( ,const rtl::Reference<SvxShapeGroupAnyD>& rTarget ,const uno::Reference< beans::XPropertySet >& rErrorBorderProp ) { - std::vector<std::vector<css::drawing::Position3D>> aPoly; - sal_Int32 nSequenceIndex = 0; - AddPointToPoly( aPoly, rPos0, nSequenceIndex ); - AddPointToPoly( aPoly, rPos1, nSequenceIndex ); + std::vector<std::vector<css::drawing::Position3D>> aPoly { { rPos0, rPos1} }; rtl::Reference<SvxShapePolyPolygon> xShape = ShapeFactory::createLine2D( rTarget, aPoly ); PropertyMapper::setMappedProperties( *xShape, rErrorBorderProp, @@ -1293,24 +1302,23 @@ void VSeriesPlotter::createRegressionCurvesShapes( VDataSeries const & rVDataSer { if(m_nDimension!=2) return; - uno::Reference< XRegressionCurveContainer > xContainer( rVDataSeries.getModel(), uno::UNO_QUERY ); + rtl::Reference< DataSeries > xContainer( rVDataSeries.getModel() ); if(!xContainer.is()) return; if (!m_pPosHelper) return; - uno::Sequence< uno::Reference< XRegressionCurve > > aCurveList = xContainer->getRegressionCurves(); + const std::vector< rtl::Reference< ::chart::RegressionCurveModel > > & aCurveList = xContainer->getRegressionCurves2(); - for(sal_Int32 nN=0; nN<aCurveList.getLength(); nN++) + for(std::size_t nN=0; nN<aCurveList.size(); nN++) { - uno::Reference< XRegressionCurveCalculator > xCalculator( aCurveList[nN]->getCalculator() ); + const auto & rCurve = aCurveList[nN]; + uno::Reference< XRegressionCurveCalculator > xCalculator( rCurve->getCalculator() ); if( !xCalculator.is()) continue; - uno::Reference< beans::XPropertySet > xProperties( aCurveList[nN], uno::UNO_QUERY ); - - bool bAverageLine = RegressionCurveHelper::isMeanValueLine( aCurveList[nN] ); + bool bAverageLine = RegressionCurveHelper::isMeanValueLine( rCurve ); sal_Int32 aDegree = 2; sal_Int32 aPeriod = 2; @@ -1320,16 +1328,16 @@ void VSeriesPlotter::createRegressionCurvesShapes( VDataSeries const & rVDataSer bool bForceIntercept = false; double aInterceptValue = 0.0; - if ( xProperties.is() && !bAverageLine ) + if ( !bAverageLine ) { - xProperties->getPropertyValue( "PolynomialDegree") >>= aDegree; - xProperties->getPropertyValue( "MovingAveragePeriod") >>= aPeriod; - xProperties->getPropertyValue( "MovingAverageType") >>= aMovingAverageType; - xProperties->getPropertyValue( "ExtrapolateForward") >>= aExtrapolateForward; - xProperties->getPropertyValue( "ExtrapolateBackward") >>= aExtrapolateBackward; - xProperties->getPropertyValue( "ForceIntercept") >>= bForceIntercept; + rCurve->getPropertyValue( "PolynomialDegree") >>= aDegree; + rCurve->getPropertyValue( "MovingAveragePeriod") >>= aPeriod; + rCurve->getPropertyValue( "MovingAverageType") >>= aMovingAverageType; + rCurve->getPropertyValue( "ExtrapolateForward") >>= aExtrapolateForward; + rCurve->getPropertyValue( "ExtrapolateBackward") >>= aExtrapolateBackward; + rCurve->getPropertyValue( "ForceIntercept") >>= bForceIntercept; if (bForceIntercept) - xProperties->getPropertyValue( "InterceptValue") >>= aInterceptValue; + rCurve->getPropertyValue( "InterceptValue") >>= aInterceptValue; } double fChartMinX = m_pPosHelper->getLogicMinX(); @@ -1421,7 +1429,7 @@ void VSeriesPlotter::createRegressionCurvesShapes( VDataSeries const & rVDataSer if( aRegressionPoly.SequenceX.hasElements() && aRegressionPoly.SequenceX[0].hasElements() ) { VLineProperties aVLineProperties; - aVLineProperties.initFromPropertySet( xProperties ); + aVLineProperties.initFromPropertySet( rCurve ); //create an extra group shape for each curve for selection handling rtl::Reference<SvxShapeGroupAnyD> xRegressionGroupShapes = @@ -1433,7 +1441,7 @@ void VSeriesPlotter::createRegressionCurvesShapes( VDataSeries const & rVDataSer } // curve equation and correlation coefficient - uno::Reference< beans::XPropertySet > xEquationProperties( aCurveList[nN]->getEquationProperties()); + uno::Reference< beans::XPropertySet > xEquationProperties( rCurve->getEquationProperties()); if( xEquationProperties.is()) { createRegressionCurveEquationShapes( @@ -2289,12 +2297,83 @@ OUString VSeriesPlotter::getCategoryName( sal_Int32 nPointIndex ) const return OUString(); } -uno::Sequence< OUString > VSeriesPlotter::getSeriesNames() const +namespace { +// The following it to support rendering order for combo charts. A chart type +// with a lower rendering order is rendered before (i.e., behind) a chart with a +// higher rendering order. The rendering orders are based on rough guesses about +// how much one chart (type) will obscure another chart (type). The intent is to +// minimize obscuring of data, by putting charts that generally cover more +// pixels (e.g., area charts) behind ones that generally cover fewer (e.g., line +// charts). +struct ROrderPair +{ + ROrderPair(OUString n, sal_Int32 r) : chartName(n), renderOrder(r) {} + + OUString chartName; + sal_Int32 renderOrder; +}; + +const ROrderPair pairList[] = { + ROrderPair(CHART2_SERVICE_NAME_CHARTTYPE_AREA, 0), + ROrderPair(CHART2_SERVICE_NAME_CHARTTYPE_BAR, 6), // bar & column are same + ROrderPair(CHART2_SERVICE_NAME_CHARTTYPE_COLUMN, 6), + ROrderPair(CHART2_SERVICE_NAME_CHARTTYPE_LINE, 8), + ROrderPair(CHART2_SERVICE_NAME_CHARTTYPE_SCATTER, 5), + ROrderPair(CHART2_SERVICE_NAME_CHARTTYPE_PIE, 1), + ROrderPair(CHART2_SERVICE_NAME_CHARTTYPE_NET, 3), + ROrderPair(CHART2_SERVICE_NAME_CHARTTYPE_FILLED_NET, 2), + ROrderPair(CHART2_SERVICE_NAME_CHARTTYPE_CANDLESTICK, 7), + ROrderPair(CHART2_SERVICE_NAME_CHARTTYPE_BUBBLE, 4) +}; +} // unnamed + +sal_Int32 VSeriesPlotter::getRenderOrder() const +{ + OUString aChartType = m_xChartTypeModel->getChartType(); + for (const auto& elem : pairList) { + if (aChartType.equalsIgnoreAsciiCase(elem.chartName)) { + return elem.renderOrder; + } + } + SAL_WARN("chart2", "Unsupported chart type in getRenderOrder()"); + return 0; +} + +std::vector<VDataSeries const*> VSeriesPlotter::getAllSeries() const +{ + std::vector<VDataSeries const*> aAllSeries; + for (std::vector<VDataSeriesGroup> const & rXSlot : m_aZSlots) + { + for(VDataSeriesGroup const & rGroup : rXSlot) + { + for (std::unique_ptr<VDataSeries> const & p : rGroup.m_aSeriesVector) + aAllSeries.push_back(p.get()); + } + } + return aAllSeries; +} + + +std::vector<VDataSeries*> VSeriesPlotter::getAllSeries() +{ + std::vector<VDataSeries*> aAllSeries; + for (std::vector<VDataSeriesGroup> const & rXSlot : m_aZSlots) + { + for(VDataSeriesGroup const & rGroup : rXSlot) + { + for (std::unique_ptr<VDataSeries> const & p : rGroup.m_aSeriesVector) + aAllSeries.push_back(p.get()); + } + } + return aAllSeries; +} + +uno::Sequence<OUString> VSeriesPlotter::getSeriesNames() const { std::vector<OUString> aRetVector; OUString aRole; - if( m_xChartTypeModel.is() ) + if (m_xChartTypeModel.is()) aRole = m_xChartTypeModel->getRoleOfSequenceForSeriesLabel(); for (auto const& rGroup : m_aZSlots) @@ -2305,10 +2384,10 @@ uno::Sequence< OUString > VSeriesPlotter::getSeriesNames() const if (!rSeriesGroup.m_aSeriesVector.empty()) { VDataSeries const * pSeries = rSeriesGroup.m_aSeriesVector[0].get(); - uno::Reference< XDataSeries > xSeries( pSeries ? pSeries->getModel() : nullptr ); + rtl::Reference< DataSeries > xSeries( pSeries ? pSeries->getModel() : nullptr ); if( xSeries.is() ) { - OUString aSeriesName( DataSeriesHelper::getDataSeriesLabel( xSeries, aRole ) ); + OUString aSeriesName( xSeries->getLabelForRole( aRole ) ); aRetVector.push_back( aSeriesName ); } } @@ -2317,6 +2396,25 @@ uno::Sequence< OUString > VSeriesPlotter::getSeriesNames() const return comphelper::containerToSequence( aRetVector ); } +uno::Sequence<OUString> VSeriesPlotter::getAllSeriesNames() const +{ + std::vector<OUString> aRetVector; + + OUString aRole; + if (m_xChartTypeModel.is()) + aRole = m_xChartTypeModel->getRoleOfSequenceForSeriesLabel(); + + for (VDataSeries const* pSeries : getAllSeries()) + { + if (pSeries) + { + OUString aSeriesName(pSeries->getModel()->getLabelForRole(aRole)); + aRetVector.push_back(aSeriesName); + } + } + return comphelper::containerToSequence(aRetVector); +} + void VSeriesPlotter::setPageReferenceSize( const css::awt::Size & rPageRefSize ) { m_aPageReferenceSize = rPageRefSize; @@ -2388,7 +2486,8 @@ std::vector< ViewLegendEntry > VSeriesPlotter::createLegendEntries( if (!pSeries) continue; - if (!pSeries->getPropertiesOfSeries()->getPropertyValue("ShowLegendEntry").get<sal_Bool>()) + // "ShowLegendEntry" + if (!pSeries->getModel()->getFastPropertyValue(PROP_DATASERIES_SHOW_LEGEND_ENTRY).get<sal_Bool>()) { continue; } @@ -2434,18 +2533,45 @@ std::vector< ViewLegendEntry > VSeriesPlotter::createLegendEntries( return aResult; } -std::vector<VDataSeries*> VSeriesPlotter::getAllSeries() +std::vector<ViewLegendSymbol> VSeriesPlotter::createSymbols(const awt::Size& rEntryKeyAspectRatio + , const rtl::Reference<SvxShapeGroupAnyD>& xTarget + , const Reference<uno::XComponentContext>& xContext) { - std::vector<VDataSeries*> aAllSeries; - for (std::vector<VDataSeriesGroup> const & rXSlot : m_aZSlots) + std::vector<ViewLegendSymbol> aResult; + + if( xTarget.is() ) { - for(VDataSeriesGroup const & rGroup : rXSlot) + bool bBreak = false; + bool bFirstSeries = true; + + for (std::vector<VDataSeriesGroup> const & rGroupVector : m_aZSlots) { - for (std::unique_ptr<VDataSeries> const & p : rGroup.m_aSeriesVector) - aAllSeries.push_back(p.get()); + for (VDataSeriesGroup const & rGroup : rGroupVector) + { + for (std::unique_ptr<VDataSeries> const & pSeries : rGroup.m_aSeriesVector) + { + if (!pSeries) + continue; + + std::vector<ViewLegendSymbol> aSeriesSymbols = createSymbolsForSeries(rEntryKeyAspectRatio, *pSeries, xTarget, xContext); + + //add series entries to the result now + + // use only the first series if VaryColorsByPoint is set for the first series + if (bFirstSeries && pSeries->isVaryColorsByPoint()) + bBreak = true; + + bFirstSeries = false; + + aResult.insert(aResult.end(), aSeriesSymbols.begin(), aSeriesSymbols.end()); + } + if (bBreak) + return aResult; + } } } - return aAllSeries; + + return aResult; } namespace @@ -2468,19 +2594,11 @@ bool lcl_HasVisibleLine( const uno::Reference< beans::XPropertySet >& xProps, bo bool lcl_HasRegressionCurves( const VDataSeries& rSeries, bool& rbHasDashedLine ) { bool bHasRegressionCurves = false; - Reference< XRegressionCurveContainer > xRegrCont( rSeries.getModel(), uno::UNO_QUERY ); - if( xRegrCont.is()) + rtl::Reference< DataSeries > xRegrCont( rSeries.getModel() ); + for( const rtl::Reference< RegressionCurveModel > & rCurve : xRegrCont->getRegressionCurves2() ) { - 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 ); - } - } + bHasRegressionCurves = true; + lcl_HasVisibleLine( rCurve, rbHasDashedLine ); } return bHasRegressionCurves; } @@ -2646,10 +2764,11 @@ std::vector< ViewLegendEntry > VSeriesPlotter::createLegendEntriesForSeries( CHART2_SERVICE_NAME_CHARTTYPE_PIE); try { - if (bIsPie && m_xChartTypeModelProps.is()) + if (bIsPie) { bool bDonut = false; - if ((m_xChartTypeModelProps->getPropertyValue("UseRings") >>= bDonut) && bDonut) + // "UseRings" + if ((m_xChartTypeModel->getFastPropertyValue(PROP_PIECHARTTYPE_USE_RINGS) >>= bDonut) && bDonut) bIsPie = false; } } @@ -2665,7 +2784,8 @@ std::vector< ViewLegendEntry > VSeriesPlotter::createLegendEntriesForSeries( Sequence<sal_Int32> deletedLegendEntries; try { - rSeries.getPropertiesOfSeries()->getPropertyValue("DeletedLegendEntries") >>= deletedLegendEntries; + // "DeletedLegendEntries" + rSeries.getModel()->getFastPropertyValue(PROP_DATASERIES_DELETED_LEGEND_ENTRIES) >>= deletedLegendEntries; } catch (const uno::Exception&) { @@ -2673,7 +2793,7 @@ std::vector< ViewLegendEntry > VSeriesPlotter::createLegendEntriesForSeries( for( sal_Int32 nIdx=0; nIdx<aCategoryNames.getLength(); ++nIdx ) { bool deletedLegendEntry = false; - for (const auto& deletedLegendEntryIdx : std::as_const(deletedLegendEntries)) + for (const auto& deletedLegendEntryIdx : deletedLegendEntries) { if (nIdx == deletedLegendEntryIdx) { @@ -2706,7 +2826,7 @@ std::vector< ViewLegendEntry > VSeriesPlotter::createLegendEntriesForSeries( aLabelText = aCategoryNames[nIdx]; if( xShape.is() || !aLabelText.isEmpty() ) { - aEntry.aLabel = FormattedStringHelper::createFormattedStringSequence( xContext, aLabelText, xTextProperties ); + aEntry.xLabel = FormattedStringHelper::createFormattedString( aLabelText, xTextProperties ); aResult.push_back(aEntry); } } @@ -2731,8 +2851,8 @@ std::vector< ViewLegendEntry > VSeriesPlotter::createLegendEntriesForSeries( } // label - aLabelText = DataSeriesHelper::getDataSeriesLabel( rSeries.getModel(), m_xChartTypeModel.is() ? m_xChartTypeModel->getRoleOfSequenceForSeriesLabel() : "values-y"); - aEntry.aLabel = FormattedStringHelper::createFormattedStringSequence( xContext, aLabelText, xTextProperties ); + aLabelText = rSeries.getModel()->getLabelForRole( m_xChartTypeModel.is() ? m_xChartTypeModel->getRoleOfSequenceForSeriesLabel() : "values-y"); + aEntry.xLabel = FormattedStringHelper::createFormattedString( aLabelText, xTextProperties ); aResult.push_back(aEntry); } @@ -2742,44 +2862,41 @@ std::vector< ViewLegendEntry > VSeriesPlotter::createLegendEntriesForSeries( if (!ChartTypeHelper::isSupportingStatisticProperties( m_xChartTypeModel, m_nDimension )) return aResult; - Reference< XRegressionCurveContainer > xRegrCont( rSeries.getModel(), uno::UNO_QUERY ); + rtl::Reference< DataSeries > xRegrCont = rSeries.getModel(); if( xRegrCont.is()) { - Sequence< Reference< XRegressionCurve > > aCurves( xRegrCont->getRegressionCurves()); - sal_Int32 i = 0, nCount = aCurves.getLength(); + const std::vector< rtl::Reference< RegressionCurveModel > > & aCurves = xRegrCont->getRegressionCurves2(); + sal_Int32 i = 0, nCount = aCurves.size(); for( i=0; i<nCount; ++i ) { - if( aCurves[i].is() ) + //label + OUString aResStr( RegressionCurveHelper::getUINameForRegressionCurve( aCurves[i] ) ); + replaceParamterInString( aResStr, u"%SERIESNAME", aLabelText ); + aEntry.xLabel = FormattedStringHelper::createFormattedString( aResStr, xTextProperties ); + + // symbol + rtl::Reference<SvxShapeGroup> xSymbolGroup(ShapeFactory::createGroup2D( xTarget )); + + // create the symbol + rtl::Reference<SvxShapeGroup> xShape = VLegendSymbolFactory::createSymbol( rEntryKeyAspectRatio, + xSymbolGroup, LegendSymbolStyle::Line, + aCurves[i], + VLegendSymbolFactory::PropertyType::Line, uno::Any() ); + + // set CID to symbol for selection + if( xShape.is()) { - //label - OUString aResStr( RegressionCurveHelper::getUINameForRegressionCurve( aCurves[i] ) ); - replaceParamterInString( aResStr, "%SERIESNAME", aLabelText ); - aEntry.aLabel = FormattedStringHelper::createFormattedStringSequence( xContext, aResStr, xTextProperties ); - - // symbol - rtl::Reference<SvxShapeGroup> xSymbolGroup(ShapeFactory::createGroup2D( xTarget )); - - // create the symbol - rtl::Reference<SvxShapeGroup> xShape = VLegendSymbolFactory::createSymbol( rEntryKeyAspectRatio, - xSymbolGroup, LegendSymbolStyle::Line, - Reference< beans::XPropertySet >( aCurves[i], uno::UNO_QUERY ), - VLegendSymbolFactory::PropertyType::Line, uno::Any() ); - - // set CID to symbol for selection - if( xShape.is()) - { - aEntry.xSymbol = xSymbolGroup; - - 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 ) ); - OUString aCID = ObjectIdentifier::createClassifiedIdentifierForParticles( rSeries.getSeriesParticle(), aChildParticle ); - ShapeFactory::setShapeName( xShape, aCID ); - } + aEntry.xSymbol = xSymbolGroup; - aResult.push_back(aEntry); + 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 ) ); + OUString aCID = ObjectIdentifier::createClassifiedIdentifierForParticles( rSeries.getSeriesParticle(), aChildParticle ); + ShapeFactory::setShapeName( xShape, aCID ); } + + aResult.push_back(aEntry); } } } @@ -2790,8 +2907,42 @@ std::vector< ViewLegendEntry > VSeriesPlotter::createLegendEntriesForSeries( return aResult; } +std::vector<ViewLegendSymbol> VSeriesPlotter::createSymbolsForSeries( + const awt::Size& rEntryKeyAspectRatio + , const VDataSeries& rSeries + , const rtl::Reference<SvxShapeGroupAnyD>& xTarget + , const Reference<uno::XComponentContext>& xContext) +{ + std::vector<ViewLegendSymbol> aResult; + + if (!(xTarget.is() && xContext.is())) + return aResult; + + try + { + ViewLegendSymbol aEntry; + // symbol + rtl::Reference<SvxShapeGroup> xSymbolGroup(ShapeFactory::createGroup2D(xTarget)); + + // create the symbol + rtl::Reference<SvxShapeGroup> xShape = createLegendSymbolForSeries(rEntryKeyAspectRatio, rSeries, xSymbolGroup ); + + // set CID to symbol for selection + if (xShape.is()) + { + aEntry.xSymbol = xSymbolGroup; + aResult.push_back(aEntry); + } + } + catch (const uno::Exception &) + { + DBG_UNHANDLED_EXCEPTION("chart2" ); + } + return aResult; +} + VSeriesPlotter* VSeriesPlotter::createSeriesPlotter( - const uno::Reference<XChartType>& xChartTypeModel + const rtl::Reference<ChartType>& xChartTypeModel , sal_Int32 nDimensionCount , bool bExcludingPositioning ) { |