Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/LibreOffice/chart2/source/tools/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 39 kB image not shown  

Quelle  AxisHelper.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <AxisHelper.hxx>
#include <DiagramHelper.hxx>
#include <Diagram.hxx>
#include <ChartTypeHelper.hxx>
#include <ChartType.hxx>
#include <Axis.hxx>
#include <AxisIndexDefines.hxx>
#include <DataSource.hxx>
#include <LinePropertiesHelper.hxx>
#include <servicenames_coosystems.hxx>
#include <DataSeries.hxx>
#include <DataSeriesHelper.hxx>
#include <Scaling.hxx>
#include <ChartModel.hxx>
#include <DataSourceHelper.hxx>
#include <ReferenceSizeProvider.hxx>
#include <ExplicitCategoriesProvider.hxx>
#include <unonames.hxx>
#include <BaseCoordinateSystem.hxx>
#include <GridProperties.hxx>

#include <o3tl/safeint.hxx>
#include <unotools/saveopt.hxx>

#include <com/sun/star/chart/ChartAxisPosition.hpp>
#include <com/sun/star/chart2/AxisType.hpp>

#include <sal/log.hxx>

#include <com/sun/star/lang/XServiceName.hpp>
#include <com/sun/star/uno/XComponentContext.hpp>
#include <comphelper/diagnose_ex.hxx>

#include <cstddef>
#include <map>

namespace chart
{
using namespace ::com::sun::star;
using namespace ::com::sun::star::chart2;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::Sequence;

Reference< chart2::XScaling > AxisHelper::createLinearScaling()
{
    return new LinearScaling( 1.0, 0.0 );
}

Reference< chart2::XScaling > AxisHelper::createLogarithmicScaling( double fBase )
{
    return new LogarithmicScaling( fBase );
}

ScaleData AxisHelper::createDefaultScale()
{
    ScaleData aScaleData;
    aScaleData.AxisType = chart2::AxisType::REALNUMBER;
    aScaleData.AutoDateAxis = true;
    aScaleData.ShiftedCategoryPosition = false;
    aScaleData.IncrementData.SubIncrements = { SubIncrement() };
    return aScaleData;
}

void AxisHelper::removeExplicitScaling( ScaleData& rScaleData )
{
    rScaleData.Minimum = rScaleData.Maximum = rScaleData.Origin = uno::Any();
    rScaleData.Scaling = nullptr;
    ScaleData aDefaultScale( createDefaultScale() );
    rScaleData.IncrementData = aDefaultScale.IncrementData;
    rScaleData.TimeIncrement = aDefaultScale.TimeIncrement;
}

bool AxisHelper::isLogarithmic( const Reference< XScaling >& xScaling )
{
    Reference< lang::XServiceName > xServiceName( xScaling, uno::UNO_QUERY );
    return xServiceName.is()
        && xServiceName->getServiceName() == "com.sun.star.chart2.LogarithmicScaling";
}

chart2::ScaleData AxisHelper::getDateCheckedScale( const rtl::Reference< Axis >& xAxis, ChartModel& rModel )
{
    ScaleData aScale = xAxis->getScaleData();
    rtl::Reference< BaseCoordinateSystem > xCooSys( rModel.getFirstCoordinateSystem() );
    if( aScale.AutoDateAxis && aScale.AxisType == AxisType::CATEGORY )
    {
        sal_Int32 nDimensionIndex=0; sal_Int32 nAxisIndex=0;
        AxisHelper::getIndicesForAxis(xAxis, xCooSys, nDimensionIndex, nAxisIndex );
        auto xChartType = AxisHelper::getChartTypeByIndex(xCooSys, 0);
        bool bChartTypeAllowsDateAxis = xChartType.is() ? xChartType->isSupportingDateAxis(nDimensionIndex) : true;
        if( bChartTypeAllowsDateAxis )
            aScale.AxisType = AxisType::DATE;
    }
    if( aScale.AxisType == AxisType::DATE )
    {
        ExplicitCategoriesProvider aExplicitCategoriesProvider( xCooSys, rModel );
        if( !aExplicitCategoriesProvider.isDateAxis() )
            aScale.AxisType = AxisType::CATEGORY;
    }
    return aScale;
}

void AxisHelper::checkDateAxis( chart2::ScaleData& rScale, ExplicitCategoriesProvider* pExplicitCategoriesProvider, bool bChartTypeAllowsDateAxis )
{
    if( rScale.AutoDateAxis && rScale.AxisType == AxisType::CATEGORY && bChartTypeAllowsDateAxis )
    {
        rScale.AxisType = AxisType::DATE;
        removeExplicitScaling( rScale );
    }
    if( rScale.AxisType == AxisType::DATE && (!pExplicitCategoriesProvider || !pExplicitCategoriesProvider->isDateAxis()) )
    {
        rScale.AxisType = AxisType::CATEGORY;
        removeExplicitScaling( rScale );
    }
}

sal_Int32 AxisHelper::getExplicitNumberFormatKeyForAxis(
                  const rtl::Reference< Axis >& xAxis
                , const rtl::Reference< BaseCoordinateSystem > & xCorrespondingCoordinateSystem
                , const rtl::Reference<ChartModel>& xChartDoc
                , bool bSearchForParallelAxisIfNothingIsFound )
{
    sal_Int32 nNumberFormatKey(0);
    sal_Int32 nAxisIndex = 0;
    sal_Int32 nDimensionIndex = 1;
    AxisHelper::getIndicesForAxis( xAxis, xCorrespondingCoordinateSystem, nDimensionIndex, nAxisIndex );

    if (!xAxis.is())
        return 0;

    bool bLinkToSource = true;
    xAxis->getPropertyValue(CHART_UNONAME_LINK_TO_SRC_NUMFMT) >>= bLinkToSource;
    xAxis->getPropertyValue(CHART_UNONAME_NUMFMT) >>= nNumberFormatKey;

    if (bLinkToSource)
    {
        bool bFormatSet = false;
        //check whether we have a percent scale -> use percent format
        if (xChartDoc)
        {
            ScaleData aData = AxisHelper::getDateCheckedScale( xAxis, *xChartDoc );
            if( aData.AxisType==AxisType::PERCENT )
            {
                sal_Int32 nPercentFormat = DiagramHelper::getPercentNumberFormat( xChartDoc );
                if( nPercentFormat != -1 )
                {
                    nNumberFormatKey = nPercentFormat;
                    bFormatSet = true;
                }
            }
            else if( aData.AxisType==AxisType::DATE )
            {
                if( aData.Categories.is() )
                {
                    Reference< data::XDataSequence > xSeq( aData.Categories->getValues());
                    if( xSeq.is() && !( xChartDoc.is() && xChartDoc->hasInternalDataProvider()) )
                        nNumberFormatKey = xSeq->getNumberFormatKeyByIndex( -1 );
                    else
                        nNumberFormatKey = DiagramHelper::getDateNumberFormat( xChartDoc );
                    bFormatSet = true;
                }
            }
            else if( xChartDoc.is() && xChartDoc->hasInternalDataProvider() && nDimensionIndex == 0 ) //maybe date axis
            {
                rtl::Reference< Diagram > xDiagram( xChartDoc->getFirstChartDiagram() );
                if( xDiagram->isSupportingDateAxis() )
                {
                    nNumberFormatKey = DiagramHelper::getDateNumberFormat( xChartDoc );
                }
                else
                {
                    rtl::Reference< DataSource > xSource = DataSourceHelper::getUsedData( *xChartDoc );
                    if( xSource.is() )
                    {
                        std::vector< uno::Reference< chart2::data::XLabeledDataSequence > > aXValues(
                            DataSeriesHelper::getAllDataSequencesByRole( xSource->getDataSequences(), u"values-x"_ustr ) );
                        if( aXValues.empty() )
                        {
                            uno::Reference< chart2::data::XLabeledDataSequence > xCategories( xDiagram->getCategories() );
                            if( xCategories.is() )
                            {
                                Reference< data::XDataSequence > xSeq( xCategories->getValues());
                                if( xSeq.is() )
                                {
                                    bool bHasValidDoubles = false;
                                    double fTest=0.0;
                                    Sequence< uno::Any > aCats( xSeq->getData() );
                                    sal_Int32 nCount = aCats.getLength();
                                    for( sal_Int32 i = 0; i < nCount; ++i )
                                    {
                                        if( (aCats[i]>>=fTest) && !std::isnan(fTest) )
                                        {
                                            bHasValidDoubles=true;
                                            break;
                                        }
                                    }
                                    if( bHasValidDoubles )
                                        nNumberFormatKey = DiagramHelper::getDateNumberFormat( xChartDoc );
                                }
                            }
                        }
                    }
                }
                bFormatSet = true;
            }
        }

        if( !bFormatSet )
        {
            std::map< sal_Int32, sal_Int32 > aKeyMap;
            bool bNumberFormatKeyFoundViaAttachedData = false;

            try
            {
                OUString aRoleToMatch;
                if( nDimensionIndex == 0 )
                    aRoleToMatch = "values-x";
                const std::vector< rtl::Reference< ChartType > > & aChartTypes( xCorrespondingCoordinateSystem->getChartTypes2());
                for( rtl::Reference< ChartType > const & chartType : aChartTypes )
                {
                    if( nDimensionIndex != 0 )
                        aRoleToMatch = ChartTypeHelper::getRoleOfSequenceForYAxisNumberFormatDetection( chartType );
                    for( rtl::Reference< DataSeries > const & xDataSeries : chartType->getDataSeries2() )
                    {
                        if( nDimensionIndex == 1 )
                        {
                            //only take those series into account that are attached to this axis
                            sal_Int32 nAttachedAxisIndex = xDataSeries->getAttachedAxisIndex();
                            if( nAttachedAxisIndex != nAxisIndex )
                                continue;
                        }

                        Reference< data::XLabeledDataSequence > xLabeledSeq(
                            DataSeriesHelper::getDataSequenceByRole( xDataSeries, aRoleToMatch ) );

                        if( !xLabeledSeq.is() && nDimensionIndex==0 )
                        {
                            ScaleData aData = xAxis->getScaleData();
                            xLabeledSeq = aData.Categories;
                        }

                        if( xLabeledSeq.is() )
                        {
                            Reference< data::XDataSequence > xSeq( xLabeledSeq->getValues());
                            if( xSeq.is() )
                            {
                                sal_Int32 nKey = xSeq->getNumberFormatKeyByIndex( -1 );
                                // increase frequency
                                aKeyMap[ nKey ] ++;
                            }
                        }
                    }
                }
            }
            catchconst uno::Exception & )
            {
                DBG_UNHANDLED_EXCEPTION("chart2");
            }

            if( ! aKeyMap.empty())
            {
                sal_Int32 nMaxFreq = 0;
                // find most frequent key
                for (auto const& elem : aKeyMap)
                {
                    SAL_INFO(
                        "chart2.tools",
                        "NumberFormatKey " << elem.first << " appears "
                            << elem.second << " times");
                    // all values must at least be 1
                    if( elem.second > nMaxFreq )
                    {
                        nNumberFormatKey = elem.first;
                        bNumberFormatKeyFoundViaAttachedData = true;
                        nMaxFreq = elem.second;
                    }
                }
            }

            if( bSearchForParallelAxisIfNothingIsFound )
            {
                //no format is set to this axis and no data is set to this axis
                //--> try to obtain the format from the parallel y-axis
                if( !bNumberFormatKeyFoundViaAttachedData && nDimensionIndex == 1 )
                {
                    sal_Int32 nParallelAxisIndex = (nAxisIndex==1) ?0 :1;
                    rtl::Reference< Axis > xParallelAxis = AxisHelper::getAxis( 1, nParallelAxisIndex, xCorrespondingCoordinateSystem );
                    nNumberFormatKey = AxisHelper::getExplicitNumberFormatKeyForAxis(xParallelAxis, xCorrespondingCoordinateSystem, xChartDoc, false);
                }
            }
        }
    }

    return nNumberFormatKey;
}

rtl::Reference< Axis > AxisHelper::createAxis(
          sal_Int32 nDimensionIndex
        , sal_Int32 nAxisIndex // 0==main or 1==secondary axis
        , const rtl::Reference< BaseCoordinateSystem >& xCooSys
        , const Reference< uno::XComponentContext > & xContext
        , ReferenceSizeProvider * pRefSizeProvider )
{
    if( !xContext.is() || !xCooSys.is() )
        return nullptr;
    if( nDimensionIndex >= xCooSys->getDimension() )
        return nullptr;

    rtl::Reference< Axis > xAxis = new Axis();

    xCooSys->setAxisByDimension( nDimensionIndex, xAxis, nAxisIndex );

    if( nAxisIndex>0 )//when inserting secondary axes copy some things from the main axis
    {
        css::chart::ChartAxisPosition eNewAxisPos( css::chart::ChartAxisPosition_END );

        rtl::Reference< Axis > xMainAxis = xCooSys->getAxisByDimension2( nDimensionIndex, 0 );
        if( xMainAxis.is() )
        {
            ScaleData aScale = xAxis->getScaleData();
            ScaleData aMainScale = xMainAxis->getScaleData();

            aScale.AxisType = aMainScale.AxisType;
            aScale.AutoDateAxis = aMainScale.AutoDateAxis;
            aScale.Categories = aMainScale.Categories;
            aScale.Orientation = aMainScale.Orientation;
            aScale.ShiftedCategoryPosition = aMainScale.ShiftedCategoryPosition;

            xAxis->setScaleData( aScale );

            //ensure that the second axis is not placed on the main axis
            css::chart::ChartAxisPosition eMainAxisPos( css::chart::ChartAxisPosition_ZERO );
            xMainAxis->getPropertyValue(u"CrossoverPosition"_ustr) >>= eMainAxisPos;
            if( eMainAxisPos == css::chart::ChartAxisPosition_END )
                eNewAxisPos = css::chart::ChartAxisPosition_START;
        }

        xAxis->setPropertyValue(u"CrossoverPosition"_ustr, uno::Any(eNewAxisPos) );
    }

    try
    {
        // set correct initial AutoScale
        if( pRefSizeProvider )
            pRefSizeProvider->setValuesAtPropertySet( xAxis );
    }
    catchconst uno::Exception& )
    {
        TOOLS_WARN_EXCEPTION("chart2""" );
    }
    return xAxis;
}

rtl::Reference< Axis > AxisHelper::createAxis( sal_Int32 nDimensionIndex, bool bMainAxis
                , const rtl::Reference< Diagram >& xDiagram
                , const Reference< uno::XComponentContext >& xContext
                , ReferenceSizeProvider * pRefSizeProvider )
{
    OSL_ENSURE( xContext.is(), "need a context to create an axis" );
    if( !xContext.is() )
        return nullptr;

    sal_Int32 nAxisIndex = bMainAxis ? MAIN_AXIS_INDEX : SECONDARY_AXIS_INDEX;
    rtl::Reference< BaseCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemByIndex( xDiagram, 0 );

    // create axis
    return AxisHelper::createAxis(
        nDimensionIndex, nAxisIndex, xCooSys, xContext, pRefSizeProvider );
}

void AxisHelper::showAxis( sal_Int32 nDimensionIndex, bool bMainAxis
                , const rtl::Reference< Diagram >& xDiagram
                , const Reference< uno::XComponentContext >& xContext
                , ReferenceSizeProvider * pRefSizeProvider )
{
    if( !xDiagram.is() )
        return;

    bool bNewAxisCreated = false;
    rtl::Reference< Axis > xAxis = AxisHelper::getAxis( nDimensionIndex, bMainAxis, xDiagram );
    if( !xAxis.is() && xContext.is() )
    {
        // create axis
        bNewAxisCreated = true;
        xAxis = AxisHelper::createAxis( nDimensionIndex, bMainAxis, xDiagram, xContext, pRefSizeProvider );
    }

    OSL_ASSERT( xAxis.is());
    if( !bNewAxisCreated ) //default is true already if created
        AxisHelper::makeAxisVisible( xAxis );
}

void AxisHelper::showGrid( sal_Int32 nDimensionIndex, sal_Int32 nCooSysIndex, bool bMainGrid
                , const rtl::Reference< Diagram >& xDiagram )
{
    if( !xDiagram.is() )
        return;

    rtl::Reference< BaseCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemByIndex( xDiagram, nCooSysIndex );
    if(!xCooSys.is())
        return;

    rtl::Reference< Axis > xAxis = AxisHelper::getAxis( nDimensionIndex, MAIN_AXIS_INDEX, xCooSys );
    if(!xAxis.is())
    {
        //hhhh todo create axis without axis visibility
        return;
    }

    if( bMainGrid )
        AxisHelper::makeGridVisible( xAxis->getGridProperties2() );
    else
    {
        std::vector< rtl::Reference< GridProperties > > aSubGrids( xAxis->getSubGridProperties2() );
        forauto const & i : aSubGrids )
            AxisHelper::makeGridVisible( i );
    }
}

void AxisHelper::makeAxisVisible( const rtl::Reference< Axis >& xAxis )
{
    if( xAxis.is() )
    {
        xAxis->setPropertyValue( u"Show"_ustr, uno::Any( true ) );
        LinePropertiesHelper::SetLineVisible( xAxis );
        xAxis->setPropertyValue( u"DisplayLabels"_ustr, uno::Any( true ) );
    }
}

void AxisHelper::makeGridVisible( const rtl::Reference< GridProperties >& xGridProperties )
{
    if( xGridProperties.is() )
    {
        xGridProperties->setPropertyValue( u"Show"_ustr, uno::Any( true ) );
        LinePropertiesHelper::SetLineVisible( xGridProperties );
    }
}

void AxisHelper::hideAxis( sal_Int32 nDimensionIndex, bool bMainAxis
                , const rtl::Reference< Diagram >& xDiagram )
{
    AxisHelper::makeAxisInvisible( AxisHelper::getAxis( nDimensionIndex, bMainAxis, xDiagram ) );
}

void AxisHelper::makeAxisInvisible( const rtl::Reference< Axis >& xAxis )
{
    if( xAxis.is() )
    {
        xAxis->setPropertyValue( u"Show"_ustr, uno::Any( false ) );
    }
}

void AxisHelper::hideAxisIfNoDataIsAttached( const rtl::Reference< Axis >& xAxis, const rtl::Reference< Diagram >& xDiagram )
{
    //axis is hidden if no data is attached anymore but data is available
    bool bOtherSeriesAttachedToThisAxis = false;
    std::vector< rtl::Reference< DataSeries > > aSeriesVector = xDiagram->getDataSeries();
    for (auto const& series : aSeriesVector)
    {
        rtl::Reference< Axis > xCurrentAxis = xDiagram->getAttachedAxis(series);
        if( xCurrentAxis==xAxis )
        {
            bOtherSeriesAttachedToThisAxis = true;
            break;
        }
    }
    if(!bOtherSeriesAttachedToThisAxis && !aSeriesVector.empty() )
        AxisHelper::makeAxisInvisible( xAxis );
}

void AxisHelper::hideGrid( sal_Int32 nDimensionIndex, sal_Int32 nCooSysIndex, bool bMainGrid
                , const rtl::Reference< Diagram >& xDiagram )
{
    if( !xDiagram.is() )
        return;

    rtl::Reference< BaseCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemByIndex( xDiagram, nCooSysIndex );
    if(!xCooSys.is())
        return;

    rtl::Reference< Axis > xAxis = AxisHelper::getAxis( nDimensionIndex, MAIN_AXIS_INDEX, xCooSys );
    if(!xAxis.is())
        return;

    if( bMainGrid )
        AxisHelper::makeGridInvisible( xAxis->getGridProperties2() );
    else
    {
        std::vector< rtl::Reference< ::chart::GridProperties > > aSubGrids( xAxis->getSubGridProperties2() );
        forauto const & i : aSubGrids)
            AxisHelper::makeGridInvisible( i );
    }
}

void AxisHelper::makeGridInvisible( const rtl::Reference< ::chart::GridProperties >& ;xGridProperties )
{
    if( xGridProperties.is() )
    {
        xGridProperties->setPropertyValue( u"Show"_ustr, uno::Any( false ) );
    }
}

bool AxisHelper::isGridShown( sal_Int32 nDimensionIndex, sal_Int32 nCooSysIndex, bool bMainGrid
                , const rtl::Reference< Diagram >& xDiagram )
{
    bool bRet = false;

    rtl::Reference< BaseCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemByIndex( xDiagram, nCooSysIndex );
    if(!xCooSys.is())
        return bRet;

    rtl::Reference< Axis > xAxis = AxisHelper::getAxis( nDimensionIndex, MAIN_AXIS_INDEX, xCooSys );
    if(!xAxis.is())
        return bRet;

    if( bMainGrid )
        bRet = AxisHelper::isGridVisible( xAxis->getGridProperties2() );
    else
    {
        std::vector< rtl::Reference< ::chart::GridProperties > > aSubGrids( xAxis->getSubGridProperties2() );
        if( !aSubGrids.empty() )
            bRet = AxisHelper::isGridVisible( aSubGrids[0] );
    }

    return bRet;
}

rtl::Reference< ::chart::BaseCoordinateSystem > AxisHelper::getCoordinateSystemByIndex(
    const rtl::Reference< Diagram >& xDiagram, sal_Int32 nIndex )
{
    if(!xDiagram.is())
        return nullptr;
    auto aCooSysList = xDiagram->getBaseCoordinateSystems();
    if(0<=nIndex && o3tl::make_unsigned(nIndex) < aCooSysList.size())
        return aCooSysList[nIndex];
    return nullptr;
}

rtl::Reference< Axis > AxisHelper::getAxis( sal_Int32 nDimensionIndex, bool bMainAxis
            , const rtl::Reference< Diagram >& xDiagram )
{
    rtl::Reference< Axis > xRet;
    try
    {
        rtl::Reference< BaseCoordinateSystem > xCooSys = AxisHelper::getCoordinateSystemByIndex( xDiagram, 0 );
        xRet = AxisHelper::getAxis( nDimensionIndex, bMainAxis ? 0 : 1, xCooSys );
    }
    catchconst uno::Exception & )
    {
    }
    return xRet;
}

rtl::Reference< Axis > AxisHelper::getAxis( sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex
            , const rtl::Reference< BaseCoordinateSystem >& xCooSys )
{
    rtl::Reference< Axis > xRet;
    if(!xCooSys.is())
        return xRet;

    if(nDimensionIndex >= xCooSys->getDimension())
        return xRet;

    if(nAxisIndex > xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex))
        return xRet;

    assert(nAxisIndex >= 0);
    assert(nDimensionIndex >= 0);
    xRet = xCooSys->getAxisByDimension2( nDimensionIndex, nAxisIndex );
    return xRet;
}

rtl::Reference< Axis > AxisHelper::getCrossingMainAxis( const rtl::Reference< Axis >& xAxis
            , const rtl::Reference< BaseCoordinateSystem >& xCooSys )
{
    sal_Int32 nDimensionIndex = 0;
    sal_Int32 nAxisIndex = 0;
    AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex );
    if( nDimensionIndex==2 )
    {
        nDimensionIndex=1;
        bool bSwapXY = false;
        if( (xCooSys->getPropertyValue( u"SwapXAndYAxis"_ustr ) >>= bSwapXY) && bSwapXY )
            nDimensionIndex=0;
    }
    else if( nDimensionIndex==1 )
        nDimensionIndex=0;
    else
        nDimensionIndex=1;
    return AxisHelper::getAxis( nDimensionIndex, 0, xCooSys );
}

rtl::Reference< Axis > AxisHelper::getParallelAxis( const rtl::Reference< Axis >& xAxis
            , const rtl::Reference< Diagram >& xDiagram )
{
    try
    {
        sal_Int32 nCooSysIndex=-1;
        sal_Int32 nDimensionIndex=-1;
        sal_Int32 nAxisIndex=-1;
        if( getIndicesForAxis( xAxis, xDiagram, nCooSysIndex, nDimensionIndex, nAxisIndex ) )
        {
            sal_Int32 nParallelAxisIndex = (nAxisIndex==1) ?0 :1;
            return getAxis( nDimensionIndex, nParallelAxisIndex, getCoordinateSystemByIndex( xDiagram, nCooSysIndex ) );
        }
    }
    catchconst uno::RuntimeException& )
    {
    }
    return nullptr;
}

bool AxisHelper::isAxisShown( sal_Int32 nDimensionIndex, bool bMainAxis
            , const rtl::Reference< Diagram >& xDiagram )
{
    return AxisHelper::isAxisVisible( AxisHelper::getAxis( nDimensionIndex, bMainAxis, xDiagram ) );
}

bool AxisHelper::isAxisVisible( const rtl::Reference< Axis >& xAxis )
{
    bool bRet = false;

    if( xAxis.is() )
    {
        xAxis->getPropertyValue( u"Show"_ustr ) >>= bRet;
        bRet = bRet && ( LinePropertiesHelper::IsLineVisible( xAxis )
            || areAxisLabelsVisible( xAxis ) );
    }

    return bRet;
}

bool AxisHelper::areAxisLabelsVisible( const rtl::Reference< Axis >& xAxis )
{
    bool bRet = false;
    if( xAxis.is() )
    {
        xAxis->getPropertyValue( u"DisplayLabels"_ustr ) >>= bRet;
    }
    return bRet;
}

bool AxisHelper::isGridVisible( const rtl::Reference< ::chart::GridProperties >& xGridproperties )
{
    bool bRet = false;

    if( xGridproperties.is() )
    {
        xGridproperties->getPropertyValue( u"Show"_ustr ) >>= bRet;
        bRet = bRet && LinePropertiesHelper::IsLineVisible( xGridproperties );
    }

    return bRet;
}

rtl::Reference< GridProperties > AxisHelper::getGridProperties(
            const rtl::Reference< BaseCoordinateSystem >& xCooSys
        , sal_Int32 nDimensionIndex, sal_Int32 nAxisIndex, sal_Int32 nSubGridIndex )
{
    rtl::Reference< GridProperties > xRet;

    rtl::Reference< Axis > xAxis( AxisHelper::getAxis( nDimensionIndex, nAxisIndex, xCooSys ) );
    if( xAxis.is() )
    {
        if( nSubGridIndex<0 )
            xRet = xAxis->getGridProperties2();
        else
        {
            std::vector< rtl::Reference< GridProperties > > aSubGrids( xAxis->getSubGridProperties2() );
            if (nSubGridIndex < static_cast<sal_Int32>(aSubGrids.size()))
                xRet = aSubGrids[nSubGridIndex];
        }
    }

    return xRet;
}

sal_Int32 AxisHelper::getDimensionIndexOfAxis(
              const rtl::Reference< Axis >& xAxis
            , const rtl::Reference< Diagram >& xDiagram )
{
    sal_Int32 nDimensionIndex = -1;
    sal_Int32 nCooSysIndex = -1;
    sal_Int32 nAxisIndex = -1;
    AxisHelper::getIndicesForAxis( xAxis, xDiagram, nCooSysIndex , nDimensionIndex, nAxisIndex );
    return nDimensionIndex;
}

bool AxisHelper::getIndicesForAxis(
              const rtl::Reference< Axis >& xAxis
            , const rtl::Reference< BaseCoordinateSystem >& xCooSys
            , sal_Int32& rOutDimensionIndex, sal_Int32& rOutAxisIndex )
{
    //returns true if indices are found

    rOutDimensionIndex = -1;
    rOutAxisIndex = -1;

    if( !xCooSys || !xAxis )
        return false;

    rtl::Reference< Axis > xCurrentAxis;
    sal_Int32 nDimensionCount( xCooSys->getDimension() );
    for( sal_Int32 nDimensionIndex = 0; nDimensionIndex < nDimensionCount; nDimensionIndex++ )
    {
        sal_Int32 nMaxAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
        for( sal_Int32 nAxisIndex = 0; nAxisIndex <= nMaxAxisIndex; nAxisIndex++ )
        {
             xCurrentAxis = xCooSys->getAxisByDimension2(nDimensionIndex,nAxisIndex);
             if( xCurrentAxis == xAxis )
             {
                 rOutDimensionIndex = nDimensionIndex;
                 rOutAxisIndex = nAxisIndex;
                 return true;
             }
        }
    }
    return false;
}

bool AxisHelper::getIndicesForAxis( const rtl::Reference< Axis >& xAxis, const rtl::Reference< Diagram >& xDiagram
            , sal_Int32& rOutCooSysIndex, sal_Int32& rOutDimensionIndex, sal_Int32& rOutAxisIndex )
{
    //returns true if indices are found

    rOutCooSysIndex = -1;
    rOutDimensionIndex = -1;
    rOutAxisIndex = -1;

    const std::vector< rtl::Reference< BaseCoordinateSystem > > aCooSysList = xDiagram->getBaseCoordinateSystems();
    for( std::size_t nC=0; nC < aCooSysList.size(); ++nC )
    {
        if( AxisHelper::getIndicesForAxis( xAxis, aCooSysList[nC], rOutDimensionIndex, rOutAxisIndex ) )
        {
            rOutCooSysIndex = nC;
            return true;
        }
    }

    return false;
}

std::vector< rtl::Reference< Axis > > AxisHelper::getAllAxesOfCoordinateSystem(
      const rtl::Reference< BaseCoordinateSystem >& xCooSys
    , bool bOnlyVisible /* = false */ )
{
    std::vector< rtl::Reference< Axis > > aAxisVector;

    if(xCooSys.is())
    {
        sal_Int32 nMaxDimensionIndex = xCooSys->getDimension() -1;
        if( nMaxDimensionIndex>=0 )
        {
            sal_Int32 nDimensionIndex = 0;
            for(; nDimensionIndex<=nMaxDimensionIndex; ++nDimensionIndex)
            {
                const sal_Int32 nMaximumAxisIndex = xCooSys->getMaximumAxisIndexByDimension(nDimensionIndex);
                for(sal_Int32 nAxisIndex=0; nAxisIndex<=nMaximumAxisIndex; ++nAxisIndex)
                {
                    try
                    {
                        rtl::Reference< Axis > xAxis = xCooSys->getAxisByDimension2( nDimensionIndex, nAxisIndex );
                        if( xAxis.is() )
                        {
                            bool bAddAxis = true;
                            if( bOnlyVisible )
                            {
                                if( !(xAxis->getPropertyValue( u"Show"_ustr) >>= bAddAxis) )
                                    bAddAxis = false;
                            }
                            if( bAddAxis )
                                aAxisVector.push_back( xAxis );
                        }
                    }
                    catchconst uno::Exception & )
                    {
                        DBG_UNHANDLED_EXCEPTION("chart2");
                    }
                }
            }
        }
    }

    return aAxisVector;
}

std::vector< rtl::Reference< Axis > > AxisHelper::getAllAxesOfDiagram(
      const rtl::Reference< Diagram >& xDiagram
    , bool bOnlyVisible )
{
    std::vector< rtl::Reference< Axis > > aAxisVector;

    for( rtl::Reference< BaseCoordinateSystem > const & coords : xDiagram->getBaseCoordinateSystems() )
    {
        std::vector< rtl::Reference< Axis > > aAxesPerCooSys = AxisHelper::getAllAxesOfCoordinateSystem( coords, bOnlyVisible );
        aAxisVector.insert( aAxisVector.end(), aAxesPerCooSys.begin(), aAxesPerCooSys.end() );
    }

    return aAxisVector;
}

std::vector< rtl::Reference< GridProperties > > AxisHelper::getAllGrids( const rtl::Reference< Diagram >& xDiagram )
{
    const std::vector< rtl::Reference< Axis > > aAllAxes = AxisHelper::getAllAxesOfDiagram( xDiagram );
    std::vector< rtl::Reference< GridProperties > > aGridVector;

    for( rtl::Reference< Axis > const & xAxis : aAllAxes )
    {
        rtl::Reference< GridProperties > xGridProperties( xAxis->getGridProperties2() );
        if( xGridProperties.is() )
            aGridVector.push_back( xGridProperties );

        std::vector< rtl::Reference< GridProperties > > aSubGrids( xAxis->getSubGridProperties2() );
        for( rtl::Reference< GridProperties > const & xSubGrid : aSubGrids )
        {
            if( xSubGrid.is() )
                aGridVector.push_back( xSubGrid );
        }
    }

    return aGridVector;
}

void AxisHelper::getAxisOrGridPossibilities( Sequence< sal_Bool >& rPossibilityList
        , const rtl::Reference< Diagram>& xDiagram, bool bAxis )
{
    rPossibilityList.realloc(6);
    sal_Bool* pPossibilityList = rPossibilityList.getArray();

    sal_Int32 nDimensionCount = -1;
    if (xDiagram)
        nDimensionCount = xDiagram->getDimension();

    //set possibilities:
    sal_Int32 nIndex=0;
    rtl::Reference< ChartType > xChartType;
    if (xDiagram)
        xChartType = xDiagram->getChartTypeByIndex( 0 );
    for(nIndex=0;nIndex<3;nIndex++)
        pPossibilityList[nIndex] = xChartType.is() ? xChartType->isSupportingMainAxis(nDimensionCount, nIndex) : true;
    for(nIndex=3;nIndex<6;nIndex++)
        if( bAxis )
            pPossibilityList[nIndex] = xChartType.is() ? xChartType->isSupportingSecondaryAxis(nDimensionCount) : true;
        else
            pPossibilityList[nIndex] = rPossibilityList[nIndex-3];
}

bool AxisHelper::isSecondaryYAxisNeeded( const rtl::Reference< BaseCoordinateSystem >&&nbsp;xCooSys )
{
    if( !xCooSys.is() )
        return false;

    const std::vector< rtl::Reference< ChartType > > & aChartTypes( xCooSys->getChartTypes2() );
    for( rtl::Reference< ChartType > const & chartType : aChartTypes )
    {
        const std::vector< rtl::Reference< DataSeries > > & aSeriesList = chartType->getDataSeries2();
        for( sal_Int32 nS = aSeriesList.size(); nS-- ; )
        {
            sal_Int32 nAttachedAxisIndex = 0;
            if( ( aSeriesList[nS]->getPropertyValue( u"AttachedAxisIndex"_ustr ) >>= nAttachedAxisIndex ) &&
                    nAttachedAxisIndex>0 )
                return true;
        }
    }
    return false;
}

bool AxisHelper::shouldAxisBeDisplayed( const rtl::Reference< Axis >& xAxis
                                       , const rtl::Reference< BaseCoordinateSystem >& xCooSys )
{
    bool bRet = false;

    if( xAxis.is() && xCooSys.is() )
    {
        sal_Int32 nDimensionIndex=-1;
        sal_Int32 nAxisIndex=-1;
        if( AxisHelper::getIndicesForAxis( xAxis, xCooSys, nDimensionIndex, nAxisIndex ) )
        {
            sal_Int32 nDimensionCount = xCooSys->getDimension();
            rtl::Reference< ChartType > xChartType( AxisHelper::getChartTypeByIndex( xCooSys, 0 ) );

            bool bMainAxis = (nAxisIndex==MAIN_AXIS_INDEX);
            if( bMainAxis )
                bRet = xChartType.is() ? xChartType->isSupportingMainAxis(nDimensionCount, nDimensionIndex) : true;
            else
                bRet = xChartType.is() ? xChartType->isSupportingSecondaryAxis(nDimensionCount) : true;
        }
    }

    return bRet;
}

void AxisHelper::getAxisOrGridExistence( Sequence< sal_Bool >& rExistenceList
        , const rtl::Reference< Diagram>& xDiagram, bool bAxis )
{
    rExistenceList.realloc(6);
    sal_Bool* pExistenceList = rExistenceList.getArray();

    if(bAxis)
    {
        sal_Int32 nN;
        for(nN=0;nN<3;nN++)
            pExistenceList[nN] = AxisHelper::isAxisShown( nN, true, xDiagram );
        for(nN=3;nN<6;nN++)
            pExistenceList[nN] = AxisHelper::isAxisShown( nN%3, false, xDiagram );
    }
    else
    {
        sal_Int32 nN;

        for(nN=0;nN<3;nN++)
            pExistenceList[nN] = AxisHelper::isGridShown( nN, 0, true, xDiagram );
        for(nN=3;nN<6;nN++)
            pExistenceList[nN] = AxisHelper::isGridShown( nN%3, 0, false, xDiagram );
    }
}

bool AxisHelper::changeVisibilityOfAxes( const rtl::Reference< Diagram >& xDiagram
                        , const Sequence< sal_Bool >& rOldExistenceList
                        , const Sequence< sal_Bool >& rNewExistenceList
                        , const Reference< uno::XComponentContext >& xContext
                        , ReferenceSizeProvider * pRefSizeProvider )
{
    bool bChanged = false;
    for(sal_Int32 nN=0;nN<6;nN++)
    {
        if(rOldExistenceList[nN]!=rNewExistenceList[nN])
        {
            bChanged = true;
            if(rNewExistenceList[nN])
            {
                AxisHelper::showAxis( nN%3, nN<3, xDiagram, xContext, pRefSizeProvider );
            }
            else
                AxisHelper::hideAxis( nN%3, nN<3, xDiagram );
        }
    }
    return bChanged;
}

bool AxisHelper::changeVisibilityOfGrids( const rtl::Reference< Diagram >& xDiagram
                        , const Sequence< sal_Bool >& rOldExistenceList
                        , const Sequence< sal_Bool >& rNewExistenceList )
{
    bool bChanged = false;
    for(sal_Int32 nN=0;nN<6;nN++)
    {
        if(rOldExistenceList[nN]!=rNewExistenceList[nN])
        {
            bChanged = true;
            if(rNewExistenceList[nN])
                AxisHelper::showGrid( nN%3, 0, nN<3, xDiagram );
            else
                AxisHelper::hideGrid( nN%3, 0, nN<3, xDiagram );
        }
    }
    return bChanged;
}

rtl::Reference< BaseCoordinateSystem > AxisHelper::getCoordinateSystemOfAxis(
              const rtl::Reference< Axis >& xAxis
            , const rtl::Reference< Diagram >& xDiagram )
{
    if (!xDiagram)
        return nullptr;

    rtl::Reference< BaseCoordinateSystem > xRet;
    for( rtl::Reference< BaseCoordinateSystem > const & xCooSys : xDiagram->getBaseCoordinateSystems() )
    {
        std::vector< rtl::Reference< Axis > > aAllAxis = AxisHelper::getAllAxesOfCoordinateSystem( xCooSys );

        auto aFound = std::find( aAllAxis.begin(), aAllAxis.end(), xAxis );
        if( aFound != aAllAxis.end())
        {
            xRet = xCooSys;
            break;
        }
    }
    return xRet;
}

rtl::Reference< ChartType > AxisHelper::getChartTypeByIndex( const rtl::Reference< BaseCoordinateSystem >& xCooSys, sal_Int32 nIndex )
{
    rtl::Reference< ChartType > xChartType;

    if( xCooSys.is() )
    {
        const std::vector< rtl::Reference< ChartType > > aChartTypeList( xCooSys->getChartTypes2() );
        if( nIndex >= 0 && o3tl::make_unsigned(nIndex) < aChartTypeList.size() )
            xChartType = aChartTypeList[nIndex];
    }

    return xChartType;
}

void AxisHelper::setRTLAxisLayout( const rtl::Reference< BaseCoordinateSystem >& xCooSys )
{
    if( !xCooSys.is() )
        return;

    bool bCartesian = xCooSys->getViewServiceName() == CHART2_COOSYSTEM_CARTESIAN_VIEW_SERVICE_NAME;
    if( !bCartesian )
        return;

    bool bVertical = false;
    xCooSys->getPropertyValue( u"SwapXAndYAxis"_ustr ) >>= bVertical;

    sal_Int32 nHorizontalAxisDimension = bVertical ? 1 : 0;
    sal_Int32 nVerticalAxisDimension = bVertical ? 0 : 1;

    try
    {
        //reverse direction for horizontal main axis
        rtl::Reference< Axis > xHorizontalMainAxis = AxisHelper::getAxis( nHorizontalAxisDimension, MAIN_AXIS_INDEX, xCooSys );
        if( xHorizontalMainAxis.is() )
        {
            chart2::ScaleData aScale = xHorizontalMainAxis->getScaleData();
            aScale.Orientation = chart2::AxisOrientation_REVERSE;
            xHorizontalMainAxis->setScaleData(aScale);
        }

        //mathematical direction for vertical main axis
        rtl::Reference< Axis > xVerticalMainAxis = AxisHelper::getAxis( nVerticalAxisDimension, MAIN_AXIS_INDEX, xCooSys );
        if( xVerticalMainAxis.is() )
        {
            chart2::ScaleData aScale = xVerticalMainAxis->getScaleData();
            aScale.Orientation = chart2::AxisOrientation_MATHEMATICAL;
            xVerticalMainAxis->setScaleData(aScale);
        }
    }
    catchconst uno::Exception & )
    {
        DBG_UNHANDLED_EXCEPTION("chart2" );
    }

    try
    {
        //reverse direction for horizontal secondary axis
        rtl::Reference< Axis > xHorizontalSecondaryAxis = AxisHelper::getAxis( nHorizontalAxisDimension, SECONDARY_AXIS_INDEX, xCooSys );
        if( xHorizontalSecondaryAxis.is() )
        {
            chart2::ScaleData aScale = xHorizontalSecondaryAxis->getScaleData();
            aScale.Orientation = chart2::AxisOrientation_REVERSE;
            xHorizontalSecondaryAxis->setScaleData(aScale);
        }

        //mathematical direction for vertical secondary axis
        rtl::Reference< Axis > xVerticalSecondaryAxis = AxisHelper::getAxis( nVerticalAxisDimension, SECONDARY_AXIS_INDEX, xCooSys );
        if( xVerticalSecondaryAxis.is() )
        {
            chart2::ScaleData aScale = xVerticalSecondaryAxis->getScaleData();
            aScale.Orientation = chart2::AxisOrientation_MATHEMATICAL;
            xVerticalSecondaryAxis->setScaleData(aScale);
        }
    }
    catchconst uno::Exception & )
    {
        DBG_UNHANDLED_EXCEPTION("chart2");
    }
}

rtl::Reference< ChartType > AxisHelper::getFirstChartTypeWithSeriesAttachedToAxisIndex( const rtl::Reference< Diagram >& xDiagram, const sal_Int32 nAttachedAxisIndex )
{
    rtl::Reference< ChartType > xChartType;
    std::vector< rtl::Reference< DataSeries > > aSeriesVector = xDiagram->getDataSeries();
    for (auto const& series : aSeriesVector)
    {
        sal_Int32 nCurrentIndex = series->getAttachedAxisIndex();
        if( nAttachedAxisIndex == nCurrentIndex )
        {
            xChartType = xDiagram->getChartTypeOfSeries(series);
            if(xChartType.is())
                break;
        }
    }
    return xChartType;
}

bool AxisHelper::isAxisPositioningEnabled()
{
    const SvtSaveOptions::ODFSaneDefaultVersion nCurrentVersion(GetODFSaneDefaultVersion());
    return nCurrentVersion >= SvtSaveOptions::ODFSVER_012;
}

//namespace chart

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=76 H=97 G=86

¤ Dauer der Verarbeitung: 0.13 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.