diff --git a/chart2/qa/extras/chart2import2.cxx b/chart2/qa/extras/chart2import2.cxx index 7fba95030162..1e83d03d7c56 100644 --- a/chart2/qa/extras/chart2import2.cxx +++ b/chart2/qa/extras/chart2import2.cxx @@ -883,6 +883,32 @@ CPPUNIT_TEST_FIXTURE(Chart2ImportTest2, testChartDataTableWithMultipleLegendEntr CPPUNIT_ASSERT(xDataTableShape.is()); } +CPPUNIT_TEST_FIXTURE(Chart2ImportTest2, testTdf159450AxisTitleWithDataTable) +{ + // The chart has a vertical axis title and a data table below the plot area. + // The axis title must stay centered on the plot area, not on the whole + // diagram including the data table below it (which used to shift it down). + loadFromFile(u"xlsx/tdf159450.xlsx"); + auto xDrawPage + = getChartDocFromSheet(0).queryThrow()->getDrawPage(); + auto xShapes = xDrawPage->getByIndex(0).queryThrow(); + + // The chart has a data table, drawn below the plot area. + CPPUNIT_ASSERT(getShapeByName(xShapes, u"CID/D=0:DataTable="_ustr).is()); + Reference xPlotArea = getShapeByName(xShapes, u"PlotAreaExcludingAxes"_ustr); + CPPUNIT_ASSERT(xPlotArea.is()); + Reference xAxisTitle + = getShapeByName(xShapes, u"CID/D=0:CS=0:Axis=1,0:Title="_ustr); + CPPUNIT_ASSERT(xAxisTitle.is()); + + // The vertical axis title is centered on the plot area. Before the fix it was + // centered on the plot area plus the data table below it, so its center sat + // about half the data table height lower. + sal_Int32 nTitleCenterY = xAxisTitle->getPosition().Y + xAxisTitle->getSize().Height / 2; + sal_Int32 nPlotCenterY = xPlotArea->getPosition().Y + xPlotArea->getSize().Height / 2; + CPPUNIT_ASSERT_DOUBLES_EQUAL(nPlotCenterY, nTitleCenterY, 20); +} + namespace { void lcl_assertAngles(const Reference& rAxis, const double& rExpectedLabelAngle, diff --git a/chart2/qa/extras/data/xlsx/tdf159450.xlsx b/chart2/qa/extras/data/xlsx/tdf159450.xlsx new file mode 100644 index 000000000000..011bc9778d47 Binary files /dev/null and b/chart2/qa/extras/data/xlsx/tdf159450.xlsx differ diff --git a/chart2/source/view/main/ChartView.cxx b/chart2/source/view/main/ChartView.cxx index 28e4333da5b9..9f6739f2ed11 100644 --- a/chart2/source/view/main/ChartView.cxx +++ b/chart2/source/view/main/ChartView.cxx @@ -993,7 +993,8 @@ bool getAvailablePosAndSizeForDiagram( enum class TitleAlignment { ALIGN_LEFT, ALIGN_TOP, ALIGN_RIGHT, ALIGN_BOTTOM, ALIGN_Z }; void changePositionOfAxisTitle( VTitle* pVTitle, TitleAlignment eAlignment - , awt::Rectangle const & rDiagramPlusAxesRect, const awt::Size & rPageSize ) + , awt::Rectangle const & rDiagramPlusAxesRect, sal_Int32 nDiagramVerticalCenter + , const awt::Size & rPageSize ) { if(!pVTitle) return; @@ -1013,12 +1014,14 @@ void changePositionOfAxisTitle( VTitle* pVTitle, TitleAlignment eAlignment , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height + aTitleSize.Height/2 + nYDistance ); break; case TitleAlignment::ALIGN_LEFT: + // Center on the plot area (the axis), not on the plot area plus axes, + // so a data table drawn below the plot area does not shift the title down. aNewPosition = awt::Point( rDiagramPlusAxesRect.X - aTitleSize.Width/2 - nXDistance - , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height/2 ); + , nDiagramVerticalCenter ); break; case TitleAlignment::ALIGN_RIGHT: aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width + aTitleSize.Width/2 + nXDistance - , rDiagramPlusAxesRect.Y + rDiagramPlusAxesRect.Height/2 ); + , nDiagramVerticalCenter ); break; case TitleAlignment::ALIGN_Z: aNewPosition = awt::Point( rDiagramPlusAxesRect.X + rDiagramPlusAxesRect.Width + aTitleSize.Width/2 + nXDistance @@ -1986,16 +1989,20 @@ void ChartView::createShapes2D( const awt::Size& rPageSize ) //correct axis title position awt::Rectangle aDiagramPlusAxesRect( aUsedOuterRect ); + // The vertical (left/right) axis titles are centered on the plot area, + // which excludes a data table drawn below it. + sal_Int32 nDiagramVerticalCenter = m_aResultingDiagramRectangleExcludingAxes.Y + + m_aResultingDiagramRectangleExcludingAxes.Height / 2; if (aParam.mbAutoPosTitleX) - changePositionOfAxisTitle(aParam.mpVTitleX.get(), TitleAlignment::ALIGN_BOTTOM, aDiagramPlusAxesRect, rPageSize); + changePositionOfAxisTitle(aParam.mpVTitleX.get(), TitleAlignment::ALIGN_BOTTOM, aDiagramPlusAxesRect, nDiagramVerticalCenter, rPageSize); if (aParam.mbAutoPosTitleY) - changePositionOfAxisTitle(aParam.mpVTitleY.get(), TitleAlignment::ALIGN_LEFT, aDiagramPlusAxesRect, rPageSize); + changePositionOfAxisTitle(aParam.mpVTitleY.get(), TitleAlignment::ALIGN_LEFT, aDiagramPlusAxesRect, nDiagramVerticalCenter, rPageSize); if (aParam.mbAutoPosTitleZ) - changePositionOfAxisTitle(aParam.mpVTitleZ.get(), TitleAlignment::ALIGN_Z, aDiagramPlusAxesRect, rPageSize); + changePositionOfAxisTitle(aParam.mpVTitleZ.get(), TitleAlignment::ALIGN_Z, aDiagramPlusAxesRect, nDiagramVerticalCenter, rPageSize); if (aParam.mbAutoPosSecondTitleX) - changePositionOfAxisTitle(aParam.mpVTitleSecondX.get(), bIsVertical? TitleAlignment::ALIGN_RIGHT : TitleAlignment::ALIGN_TOP, aDiagramPlusAxesRect, rPageSize); + changePositionOfAxisTitle(aParam.mpVTitleSecondX.get(), bIsVertical? TitleAlignment::ALIGN_RIGHT : TitleAlignment::ALIGN_TOP, aDiagramPlusAxesRect, nDiagramVerticalCenter, rPageSize); if (aParam.mbAutoPosSecondTitleY) - changePositionOfAxisTitle(aParam.mpVTitleSecondY.get(), bIsVertical? TitleAlignment::ALIGN_TOP : TitleAlignment::ALIGN_RIGHT, aDiagramPlusAxesRect, rPageSize); + changePositionOfAxisTitle(aParam.mpVTitleSecondY.get(), bIsVertical? TitleAlignment::ALIGN_TOP : TitleAlignment::ALIGN_RIGHT, aDiagramPlusAxesRect, nDiagramVerticalCenter, rPageSize); } //cleanup: remove all empty group shapes to avoid grey border lines: