chart2/source/view/axes/VAxisProperties.cxx |   13 ++++-
 chart2/source/view/axes/VAxisProperties.hxx |    3 +
 chart2/source/view/axes/VCartesianAxis.cxx  |   68 +++++++++++++++++----------
 chart2/source/view/axes/VCartesianAxis.hxx  |    2 
 chart2/source/view/inc/DataTableView.hxx    |   11 ++--
 chart2/source/view/main/DataTableView.cxx   |   69 +++++++++++++++++++---------
 6 files changed, 114 insertions(+), 52 deletions(-)

New commits:
commit 3323e9b64de186e7e0610c130121779e19b4b54b
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Sat Aug 13 14:14:00 2022 +0200
Commit:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
CommitDate: Sat Aug 13 14:14:00 2022 +0200

    chart2: support data table rendering when the X axis is swapped
    
    In case when the X axis is swapped, so the Y axis is rendered in
    the place of X axis, we need to render the data table below the
    Y-axis labels. This is best done to put the data table into the
    Y-axis instead, so we get the correct size and position of the
    data table, and then just allow rendering of the axis labels and
    (re)position the table below Y-axis.
    
    Change-Id: I74aa79402a5638133b0d1ed83bbd8aad6f6c9d1d

diff --git a/chart2/source/view/axes/VAxisProperties.cxx 
b/chart2/source/view/axes/VAxisProperties.cxx
index f39420c9ce02..da038d27471c 100644
--- a/chart2/source/view/axes/VAxisProperties.cxx
+++ b/chart2/source/view/axes/VAxisProperties.cxx
@@ -257,7 +257,7 @@ void AxisProperties::init( bool bCartesian )
 
     if( bCartesian )
     {
-        if (m_nDimensionIndex == 0)
+        if ((!m_bSwapXAndY && m_nDimensionIndex == 0) || (m_bSwapXAndY && 
m_nDimensionIndex == 1))
         {
             m_bDisplayDataTable = m_xDataTableModel.is();
         }
@@ -332,6 +332,17 @@ void AxisProperties::init( bool bCartesian )
     {
         TOOLS_WARN_EXCEPTION("chart2", "" );
     }
+
+    if (m_bDisplayDataTable)
+    {
+        m_bDataTableAlignAxisValuesWithColumns = (m_nDimensionIndex == 0);
+
+        if (m_nDimensionIndex == 0)
+        {
+            m_bDisplayLabels = false;
+        }
+
+    }
 }
 
 AxisLabelProperties::AxisLabelProperties()
diff --git a/chart2/source/view/axes/VAxisProperties.hxx 
b/chart2/source/view/axes/VAxisProperties.hxx
index 6b6b7c361ea2..0cc23602b541 100644
--- a/chart2/source/view/axes/VAxisProperties.hxx
+++ b/chart2/source/view/axes/VAxisProperties.hxx
@@ -111,7 +111,10 @@ struct AxisProperties final
 
     AxisLabelAlignment maLabelAlignment;
 
+    // Data table
     bool m_bDisplayDataTable;
+    bool m_bDataTableAlignAxisValuesWithColumns;
+
     bool m_bDisplayLabels;
 
     // Compatibility option: starting from LibreOffice 5.1 the rotated
diff --git a/chart2/source/view/axes/VCartesianAxis.cxx 
b/chart2/source/view/axes/VCartesianAxis.cxx
index 293d1f0479a8..82e24403d678 100644
--- a/chart2/source/view/axes/VCartesianAxis.cxx
+++ b/chart2/source/view/axes/VCartesianAxis.cxx
@@ -1664,35 +1664,43 @@ void VCartesianAxis::doStaggeringOfLabels( const 
AxisLabelProperties& rAxisLabel
     }
 }
 
-void VCartesianAxis::createLabels()
+void VCartesianAxis::createDataTableShape(std::unique_ptr<TickFactory2D> 
const& rpTickFactory2D)
 {
-    if( !prepareShapeCreation() )
+    // Check if we can create the data table shape
+    // Data table view and m_bDisplayDataTable must be true
+    if (!m_pDataTableView || !m_aAxisProperties.m_bDisplayDataTable)
         return;
 
-    std::unique_ptr<TickFactory2D> apTickFactory2D(createTickFactory2D()); // 
throws on failure
+    m_pDataTableView->initializeShapes(m_xDataTableTarget);
+    basegfx::B2DVector aStart = rpTickFactory2D->getXaxisStartPos();
+    basegfx::B2DVector aEnd = rpTickFactory2D->getXaxisEndPos();
 
-    if (m_pDataTableView && m_aAxisProperties.m_bDisplayDataTable)
-    {
-        m_pDataTableView->initializeShapes(m_xDataTableTarget);
-        basegfx::B2DVector aStart = apTickFactory2D->getXaxisStartPos();
-        basegfx::B2DVector aEnd = apTickFactory2D->getXaxisEndPos();
+    rpTickFactory2D->updateScreenValues(m_aAllTickInfos);
 
-        apTickFactory2D->updateScreenValues(m_aAllTickInfos);
+    sal_Int32 nDistance = -1;
 
-        sal_Int32 nDistance = -1;
+    std::unique_ptr<TickIter> apTickIter(createLabelTickIterator(0));
+    if (apTickIter)
+    {
+        nDistance = TickFactory2D::getTickScreenDistance(*apTickIter);
+        if (getTextLevelCount() > 1)
+            nDistance *= 2;
+    }
 
-        std::unique_ptr<TickIter> apTickIter(createLabelTickIterator(0));
-        if (apTickIter)
-        {
-            nDistance = TickFactory2D::getTickScreenDistance(*apTickIter);
-            if (getTextLevelCount() > 1)
-                nDistance *= 2;
-        }
+    if (nDistance > 0)
+    {
+        m_pDataTableView->createShapes(aStart, aEnd, nDistance);
+    }
+}
 
-        if (nDistance > 0)
-            m_pDataTableView->createShapes(aStart, aEnd, nDistance);
+void VCartesianAxis::createLabels()
+{
+    if( !prepareShapeCreation() )
         return;
-    }
+
+    std::unique_ptr<TickFactory2D> apTickFactory2D(createTickFactory2D()); // 
throws on failure
+
+    createDataTableShape(apTickFactory2D);
 
     //create labels
     if (!m_aAxisProperties.m_bDisplayLabels)
@@ -1744,6 +1752,14 @@ void VCartesianAxis::createLabels()
         }
     }
     doStaggeringOfLabels( m_aAxisLabelProperties, pTickFactory2D );
+
+    if (m_pDataTableView)
+    {
+        sal_Int32 x = m_xTextTarget->getPosition().X;
+        sal_Int32 y = m_xTextTarget->getPosition().Y;
+        sal_Int32 height = m_xTextTarget->getSize().Height;
+        m_pDataTableView->changePosition(x, y + height);
+    }
 }
 
 void VCartesianAxis::createMaximumLabels()
@@ -1998,12 +2014,12 @@ void 
VCartesianAxis::createDataTableView(std::vector<std::unique_ptr<VSeriesPlot
                                          rtl::Reference<::chart::ChartModel> 
const& xChartDoc,
                                          
css::uno::Reference<css::uno::XComponentContext> const& rComponentContext)
 {
-    if (m_aAxisProperties.m_bDisplayDataTable)
-    {
-        m_pDataTableView.reset(new DataTableView(xChartDoc, 
m_aAxisProperties.m_xDataTableModel, rComponentContext));
-        m_pDataTableView->initializeValues(rSeriesPlotterList);
-        m_xNumberFormatsSupplier = xNumberFormatsSupplier;
-    }
+    if (!m_aAxisProperties.m_bDisplayDataTable)
+        return;
+
+    m_pDataTableView.reset(new DataTableView(xChartDoc, 
m_aAxisProperties.m_xDataTableModel, rComponentContext, 
m_aAxisProperties.m_bDataTableAlignAxisValuesWithColumns));
+    m_pDataTableView->initializeValues(rSeriesPlotterList);
+    m_xNumberFormatsSupplier = xNumberFormatsSupplier;
 }
 
 
diff --git a/chart2/source/view/axes/VCartesianAxis.hxx 
b/chart2/source/view/axes/VCartesianAxis.hxx
index 132887510eff..210f36dd4802 100644
--- a/chart2/source/view/axes/VCartesianAxis.hxx
+++ b/chart2/source/view/axes/VCartesianAxis.hxx
@@ -156,6 +156,8 @@ private: //methods
 
     ::basegfx::B2DVector getScreenPosition( double fLogicX, double fLogicY, 
double fLogicZ ) const;
     ScreenPosAndLogicPos getScreenPosAndLogicPos( double fLogicX, double 
fLogicY, double fLogicZ ) const;
+
+    void createDataTableShape(std::unique_ptr<TickFactory2D> const& 
rTickFactory2D);
 };
 
 } //namespace chart
diff --git a/chart2/source/view/inc/DataTableView.hxx 
b/chart2/source/view/inc/DataTableView.hxx
index 3d00a9644ba3..ba0a5f8d051d 100644
--- a/chart2/source/view/inc/DataTableView.hxx
+++ b/chart2/source/view/inc/DataTableView.hxx
@@ -12,8 +12,7 @@
 #include <svx/unoshape.hxx>
 #include <svx/unodraw/SvxTableShape.hxx>
 #include <com/sun/star/awt/Rectangle.hpp>
-#include <com/sun/star/text/XTextRange.hpp>
-#include <com/sun/star/text/XText.hpp>
+#include <com/sun/star/table/XTable.hpp>
 #include <com/sun/star/uno/XComponentContext.hpp>
 #include <DataTable.hxx>
 #include "VLineProperties.hxx"
@@ -32,12 +31,14 @@ private:
     rtl::Reference<SvxTableShape> m_xTableShape;
     rtl::Reference<DataTable> m_xDataTableModel;
     css::uno::Reference<css::uno::XComponentContext> m_xComponentContext;
+    css::uno::Reference<css::table::XTable> m_xTable;
     VLineProperties m_aLineProperties;
     std::vector<VSeriesPlotter*> m_pSeriesPlotterList;
 
     std::vector<OUString> m_aDataSeriesNames;
     std::vector<OUString> m_aXValues;
     std::vector<std::vector<OUString>> m_pDataSeriesValues;
+    bool m_bAlignAxisValuesWithColumns;
 
     void
     
setCellCharAndParagraphProperties(css::uno::Reference<css::beans::XPropertySet>&
 xPropertySet);
@@ -48,11 +49,13 @@ private:
 public:
     DataTableView(rtl::Reference<::chart::ChartModel> const& xChartDoc,
                   rtl::Reference<DataTable> const& rDataTableModel,
-                  css::uno::Reference<css::uno::XComponentContext> const& 
rComponentContext);
+                  css::uno::Reference<css::uno::XComponentContext> const& 
rComponentContext,
+                  bool bAlignAxisValuesWithColumns);
     void initializeShapes(const rtl::Reference<SvxShapeGroupAnyD>& xTarget);
     void initializeValues(std::vector<std::unique_ptr<VSeriesPlotter>>& 
rSeriesPlotterList);
     void createShapes(basegfx::B2DVector const& rStart, basegfx::B2DVector 
const& rEnd,
-                      sal_Int32 nColumnWidth);
+                      sal_Int32 nAxisStepWidth);
+    void changePosition(sal_Int32 x, sal_Int32 y);
 };
 
 } //namespace chart
diff --git a/chart2/source/view/main/DataTableView.cxx 
b/chart2/source/view/main/DataTableView.cxx
index 59cc133763a2..3eff83ef5edb 100644
--- a/chart2/source/view/main/DataTableView.cxx
+++ b/chart2/source/view/main/DataTableView.cxx
@@ -16,11 +16,12 @@
 
 #include <svx/svdotable.hxx>
 
-#include <com/sun/star/table/XTable.hpp>
 #include <com/sun/star/table/BorderLine.hpp>
 #include <com/sun/star/table/BorderLine2.hpp>
 #include <com/sun/star/table/TableBorder.hpp>
 #include <com/sun/star/table/BorderLineStyle.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+#include <com/sun/star/text/XText.hpp>
 #include <com/sun/star/style/ParagraphAdjust.hpp>
 #include <com/sun/star/drawing/TextHorizontalAdjust.hpp>
 #include <com/sun/star/drawing/TextVerticalAdjust.hpp>
@@ -85,10 +86,12 @@ getFirstParagraphProperties(uno::Reference<text::XText> 
const& xText)
 DataTableView::DataTableView(
     rtl::Reference<::chart::ChartModel> const& xChartModel,
     rtl::Reference<DataTable> const& rDataTableModel,
-    css::uno::Reference<css::uno::XComponentContext> const& rComponentContext)
+    css::uno::Reference<css::uno::XComponentContext> const& rComponentContext,
+    bool bAlignAxisValuesWithColumns)
     : m_xChartModel(xChartModel)
     , m_xDataTableModel(rDataTableModel)
     , m_xComponentContext(rComponentContext)
+    , m_bAlignAxisValuesWithColumns(bAlignAxisValuesWithColumns)
 {
     uno::Reference<beans::XPropertySet> xPropertySet(m_xDataTableModel);
     m_aLineProperties.initFromPropertySet(xPropertySet);
@@ -224,7 +227,7 @@ void 
DataTableView::setCellProperties(css::uno::Reference<beans::XPropertySet>&
 }
 
 void DataTableView::createShapes(basegfx::B2DVector const& rStart, 
basegfx::B2DVector const& rEnd,
-                                 sal_Int32 nColumnWidth)
+                                 sal_Int32 nAxisStepWidth)
 {
     if (!m_xTarget.is())
         return;
@@ -234,22 +237,23 @@ void DataTableView::createShapes(basegfx::B2DVector 
const& rStart, basegfx::B2DV
     auto sCID = 
ObjectIdentifier::createClassifiedIdentifierForParticle(sParticle);
     m_xTableShape = ShapeFactory::createTable(m_xTarget, sCID);
 
-    uno::Reference<table::XTable> xTable;
+    auto rDelta = rEnd - rStart;
+    sal_Int32 nTableSize = basegfx::fround(rDelta.getX());
+    m_xTableShape->setSize({ nTableSize, 0 });
+
     try
     {
-        auto rDelta = rEnd - rStart;
-        m_xTableShape->setSize({ basegfx::fround(rDelta.getX()), 0 });
-        m_xTableShape->getPropertyValue("Model") >>= xTable;
+        m_xTableShape->getPropertyValue("Model") >>= m_xTable;
     }
     catch (const uno::Exception&)
     {
         return;
     }
 
-    if (!xTable.is())
+    if (!m_xTable.is())
         return;
 
-    uno::Reference<util::XBroadcaster> xBroadcaster(xTable, uno::UNO_QUERY);
+    uno::Reference<util::XBroadcaster> xBroadcaster(m_xTable, uno::UNO_QUERY);
 
     if (!xBroadcaster.is())
         return;
@@ -271,15 +275,24 @@ void DataTableView::createShapes(basegfx::B2DVector 
const& rStart, basegfx::B2DV
     m_xDataTableModel->getPropertyValue("Keys") >>= bKeys;
 
     sal_Int32 nColumnCount = m_aXValues.size();
-    uno::Reference<table::XTableColumns> xTableColumns = xTable->getColumns();
+    uno::Reference<table::XTableColumns> xTableColumns = 
m_xTable->getColumns();
     xTableColumns->insertByIndex(0, nColumnCount);
 
     sal_Int32 nRowCount = m_aDataSeriesNames.size();
-    uno::Reference<table::XTableRows> xTableRows = xTable->getRows();
+    uno::Reference<table::XTableRows> xTableRows = m_xTable->getRows();
     xTableRows->insertByIndex(0, nRowCount);
 
+    double nColumnWidth = 0.0;
+
+    // If we don't align, we have to calculate the column width ourselves
+    if (m_bAlignAxisValuesWithColumns)
+        nColumnWidth = nAxisStepWidth;
+    else
+        nColumnWidth = double(nTableSize) / nColumnCount;
+
+    // Setup empty top-left cell
     {
-        uno::Reference<table::XCell> xCell = xTable->getCellByPosition(0, 0);
+        uno::Reference<table::XCell> xCell = m_xTable->getCellByPosition(0, 0);
         uno::Reference<beans::XPropertySet> xPropertySet(xCell, 
uno::UNO_QUERY);
         if (xPropertySet.is())
         {
@@ -295,7 +308,7 @@ void DataTableView::createShapes(basegfx::B2DVector const& 
rStart, basegfx::B2DV
     nColumn = 1;
     for (auto const& rString : m_aXValues)
     {
-        uno::Reference<table::XCell> xCell = 
xTable->getCellByPosition(nColumn, 0);
+        uno::Reference<table::XCell> xCell = 
m_xTable->getCellByPosition(nColumn, 0);
         uno::Reference<beans::XPropertySet> xPropertySet(xCell, 
uno::UNO_QUERY);
         uno::Reference<text::XTextRange> xCellTextRange(xCell, uno::UNO_QUERY);
         if (xCellTextRange.is())
@@ -341,7 +354,7 @@ void DataTableView::createShapes(basegfx::B2DVector const& 
rStart, basegfx::B2DV
     nRow = 1;
     for (auto const& rSeriesName : m_aDataSeriesNames)
     {
-        uno::Reference<table::XCell> xCell = xTable->getCellByPosition(0, 
nRow);
+        uno::Reference<table::XCell> xCell = m_xTable->getCellByPosition(0, 
nRow);
         uno::Reference<beans::XPropertySet> xCellPropertySet(xCell, 
uno::UNO_QUERY);
         uno::Reference<text::XTextRange> xCellTextRange(xCell, uno::UNO_QUERY);
         if (xCellTextRange.is())
@@ -373,7 +386,7 @@ void DataTableView::createShapes(basegfx::B2DVector const& 
rStart, basegfx::B2DV
         nColumn = 1;
         for (auto const& rValue : rSeries)
         {
-            uno::Reference<table::XCell> xCell = 
xTable->getCellByPosition(nColumn, nRow);
+            uno::Reference<table::XCell> xCell = 
m_xTable->getCellByPosition(nColumn, nRow);
             uno::Reference<beans::XPropertySet> xCellPropertySet(xCell, 
uno::UNO_QUERY);
             uno::Reference<text::XTextRange> xCellTextRange(xCell, 
uno::UNO_QUERY);
             if (xCellTextRange.is())
@@ -415,13 +428,13 @@ void DataTableView::createShapes(basegfx::B2DVector 
const& rStart, basegfx::B2DV
     pTableObject->DistributeRows(0, nRowCount - 1, true, true);
 
     xBroadcaster->lockBroadcasts();
-    uno::Reference<beans::XPropertySet> 
xPropertySet(xTableColumns->getByIndex(0), uno::UNO_QUERY);
-    sal_Int32 nWidth = 0;
-    xPropertySet->getPropertyValue("Width") >>= nWidth;
 
-    sal_Int32 nTableX = basegfx::fround(rStart.getX() - nWidth);
-    sal_Int32 nTableY = basegfx::fround(rStart.getY());
-    m_xTableShape->setPosition({ nTableX, nTableY });
+    changePosition(basegfx::fround(rStart.getX()), 
basegfx::fround(rStart.getY()));
+
+    sal_Int32 nTableX = m_xTableShape->getPosition().X;
+    sal_Int32 nTableY = m_xTableShape->getPosition().Y;
+
+    uno::Reference<beans::XPropertySet> 
xPropertySet(xTableColumns->getByIndex(0), uno::UNO_QUERY);
 
     for (sal_Int32 i = 1; i < xTableColumns->getCount(); ++i)
     {
@@ -448,6 +461,20 @@ void DataTableView::createShapes(basegfx::B2DVector const& 
rStart, basegfx::B2DV
     xBroadcaster->unlockBroadcasts();
 }
 
+void DataTableView::changePosition(sal_Int32 x, sal_Int32 y)
+{
+    if (!m_xTable.is())
+        return;
+
+    uno::Reference<table::XTableColumns> xTableColumns = 
m_xTable->getColumns();
+    uno::Reference<beans::XPropertySet> 
xPropertySet(xTableColumns->getByIndex(0), uno::UNO_QUERY);
+
+    sal_Int32 nWidth = 0;
+    xPropertySet->getPropertyValue("Width") >>= nWidth;
+
+    m_xTarget->setPosition({ x - nWidth, y });
+}
+
 void DataTableView::initializeShapes(const rtl::Reference<SvxShapeGroupAnyD>& 
xTarget)
 {
     m_xTarget = xTarget;

Reply via email to