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

Quelle  Tickmarks.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 "Tickmarks.hxx"
#include "Tickmarks_Equidistant.hxx"
#include "Tickmarks_Dates.hxx"
#include <ViewDefines.hxx>
#include "VAxisProperties.hxx"
#include <osl/diagnose.h>
#include <com/sun/star/chart2/AxisType.hpp>
#include <utility>

using namespace ::com::sun::star;
using ::basegfx::B2DVector;

namespace chart {

TickInfo::TickInfo( uno::Reference<chart2::XScaling> xInverse )
: fScaledTickValue( 0.0 )
, xInverseScaling(std::move( xInverse ))
, aTickScreenPosition(0.0,0.0)
, nFactorForLimitedTextWidth(1)
, bPaintIt( true )
{
}

double TickInfo::getUnscaledTickValue() const
{
    if( xInverseScaling.is() )
        return xInverseScaling->doScaling( fScaledTickValue );
    else
        return fScaledTickValue;
}

sal_Int32 TickInfo::getScreenDistanceBetweenTicks( const TickInfo& rOherTickInfo const
{
    //return the positive distance between the two first tickmarks in screen values

    B2DVector aDistance = rOherTickInfo.aTickScreenPosition - aTickScreenPosition;
    sal_Int32 nRet = static_cast<sal_Int32>(aDistance.getLength());
    if(nRet<0)
        nRet *= -1;
    return nRet;
}

PureTickIter::PureTickIter( TickInfoArrayType& rTickInfoVector )
            : m_rTickVector(rTickInfoVector)
            , m_aTickIter(m_rTickVector.begin())
{
}
PureTickIter::~PureTickIter()
{
}
TickInfo* PureTickIter::firstInfo()
{
    m_aTickIter = m_rTickVector.begin();
    if(m_aTickIter!=m_rTickVector.end())
        return &*m_aTickIter;
    return nullptr;
}
TickInfo* PureTickIter::nextInfo()
{
    if(m_aTickIter!=m_rTickVector.end())
    {
        ++m_aTickIter;
        if(m_aTickIter!=m_rTickVector.end())
            return &*m_aTickIter;
    }
    return nullptr;
}

TickFactory::TickFactory(
          ExplicitScaleData aScale, ExplicitIncrementData aIncrement )
            : m_rScale(std::move( aScale ))
            , m_rIncrement(std::move( aIncrement ))
{
    //@todo: make sure that the scale is valid for the scaling

    if( m_rScale.Scaling.is() )
    {
        m_xInverseScaling = m_rScale.Scaling->getInverseScaling();
        OSL_ENSURE( m_xInverseScaling.is(), "each Scaling needs to return an inverse Scaling" );
    }

    m_fScaledVisibleMin = m_rScale.Minimum;
    if( m_xInverseScaling.is() )
        m_fScaledVisibleMin = m_rScale.Scaling->doScaling(m_fScaledVisibleMin);

    m_fScaledVisibleMax = m_rScale.Maximum;
    if( m_xInverseScaling.is() )
        m_fScaledVisibleMax = m_rScale.Scaling->doScaling(m_fScaledVisibleMax);
}

TickFactory::~TickFactory()
{
}

bool TickFactory::isDateAxis() const
{
    return m_rScale.AxisType == chart2::AxisType::DATE;
}

void TickFactory::getAllTicks( TickInfoArraysType& rAllTickInfos ) const
{
    if( isDateAxis() )
        DateTickFactory( m_rScale, m_rIncrement ).getAllTicks( rAllTickInfos );
    else
        EquidistantTickFactory( m_rScale, m_rIncrement ).getAllTicks( rAllTickInfos );
}

void TickFactory::getAllTicksShifted( TickInfoArraysType& rAllTickInfos ) const
{
    if( isDateAxis() )
        DateTickFactory( m_rScale, m_rIncrement ).getAllTicksShifted( rAllTickInfos );
    else
        EquidistantTickFactory( m_rScale, m_rIncrement ).getAllTicksShifted( rAllTickInfos );
}

// ___TickFactory_2D___
TickFactory2D::TickFactory2D(
          const ExplicitScaleData& rScale, const ExplicitIncrementData& rIncrement
          //, double fStretch_SceneToScreen, double fOffset_SceneToScreen )
          , const B2DVector& rStartScreenPos, const B2DVector& rEndScreenPos
          , const B2DVector& rAxisLineToLabelLineShift )
          : TickFactory( rScale, rIncrement )
          , m_aAxisStartScreenPosition2D(rStartScreenPos)
          , m_aAxisEndScreenPosition2D(rEndScreenPos)
          , m_aAxisLineToLabelLineShift(rAxisLineToLabelLineShift)
          , m_fStretch_LogicToScreen(1.0)
          , m_fOffset_LogicToScreen(0.0)
{
    double fWidthY = m_fScaledVisibleMax - m_fScaledVisibleMin;
    if (m_rScale.Orientation == chart2::AxisOrientation_MATHEMATICAL)
    {
        m_fStretch_LogicToScreen = 1.0/fWidthY;
        m_fOffset_LogicToScreen = -m_fScaledVisibleMin;
    }
    else
    {
        B2DVector aSwap(m_aAxisStartScreenPosition2D);
        m_aAxisStartScreenPosition2D = m_aAxisEndScreenPosition2D;
        m_aAxisEndScreenPosition2D = aSwap;

        m_fStretch_LogicToScreen = -1.0/fWidthY;
        m_fOffset_LogicToScreen = -m_fScaledVisibleMax;
    }
}

TickFactory2D::~TickFactory2D()
{
}

bool TickFactory2D::isHorizontalAxis() const
{
    // check trivial cases:
    if ( m_aAxisStartScreenPosition2D.getY() == m_aAxisEndScreenPosition2D.getY() )
        return true;
    if ( m_aAxisStartScreenPosition2D.getX() == m_aAxisEndScreenPosition2D.getX() )
        return false;

    // for skew axes compare angle with horizontal vector
    double fInclination = std::abs(B2DVector(m_aAxisEndScreenPosition2D-m_aAxisStartScreenPosition2D).angle(B2DVector(1.0, 0.0)));
    return fInclination < M_PI_4 || fInclination > (M_PI-M_PI_4);
}
bool TickFactory2D::isVerticalAxis() const
{
    // check trivial cases:
    if ( m_aAxisStartScreenPosition2D.getX() == m_aAxisEndScreenPosition2D.getX() )
        return true;
    if ( m_aAxisStartScreenPosition2D.getY() == m_aAxisEndScreenPosition2D.getY() )
        return false;

    // for skew axes compare angle with vertical vector
    double fInclination = std::abs(B2DVector(m_aAxisEndScreenPosition2D-m_aAxisStartScreenPosition2D).angle(B2DVector(0.0, -1.0)));
    return fInclination < M_PI_4 || fInclination > (M_PI-M_PI_4);
}
//static
sal_Int32 TickFactory2D::getTickScreenDistance( TickIter& rIter )
{
    //return the positive distance between the two first tickmarks in screen values
    //if there are less than two tickmarks -1 is returned

    const TickInfo* pFirstTickInfo = rIter.firstInfo();
    const TickInfo* pSecondTickInfo = rIter.nextInfo();
    if(!pSecondTickInfo  || !pFirstTickInfo)
        return -1;

    return pFirstTickInfo->getScreenDistanceBetweenTicks( *pSecondTickInfo );
}

B2DVector TickFactory2D::getTickScreenPosition2D( double fScaledLogicTickValue ) const
{
    B2DVector aRet(m_aAxisStartScreenPosition2D);
    aRet += (m_aAxisEndScreenPosition2D-m_aAxisStartScreenPosition2D)
                *((fScaledLogicTickValue+m_fOffset_LogicToScreen)*m_fStretch_LogicToScreen);
    return aRet;
}

void TickFactory2D::addPointSequenceForTickLine( drawing::PointSequenceSequence&&nbsp;rPoints
                                , sal_Int32 nSequenceIndex
                                , double fScaledLogicTickValue, double fInnerDirectionSign
                                , const TickmarkProperties& rTickmarkProperties
                                , bool bPlaceAtLabels ) const
{
    if( fInnerDirectionSign==0.0 )
        fInnerDirectionSign = 1.0;

    B2DVector aTickScreenPosition = getTickScreenPosition2D(fScaledLogicTickValue);
    if( bPlaceAtLabels )
        aTickScreenPosition += m_aAxisLineToLabelLineShift;

    B2DVector aMainDirection = m_aAxisEndScreenPosition2D-m_aAxisStartScreenPosition2D;
    aMainDirection.normalize();
    B2DVector aOrthoDirection(-aMainDirection.getY(),aMainDirection.getX());
    aOrthoDirection *= fInnerDirectionSign;
    aOrthoDirection.normalize();

    B2DVector aStart = aTickScreenPosition + aOrthoDirection*rTickmarkProperties.RelativePos;
    B2DVector aEnd = aStart - aOrthoDirection*rTickmarkProperties.Length;

    rPoints.getArray()[nSequenceIndex]
        = { { static_cast<sal_Int32>(aStart.getX()), static_cast<sal_Int32>(aStart.getY()) },
            { static_cast<sal_Int32>(aEnd.getX()), static_cast<sal_Int32>(aEnd.getY()) } };
}

B2DVector TickFactory2D::getDistanceAxisTickToText( const AxisProperties& rAxisProperties, bool bIncludeFarAwayDistanceIfSo, bool bIncludeSpaceBetweenTickAndText ) const
{
    bool bFarAwayLabels = false;
    if( rAxisProperties.m_eLabelPos == css::chart::ChartAxisLabelPosition_OUTSIDE_START
        || rAxisProperties.m_eLabelPos == css::chart::ChartAxisLabelPosition_OUTSIDE_END )
        bFarAwayLabels = true;

    double fInnerDirectionSign = rAxisProperties.maLabelAlignment.mfInnerTickDirection;
    if( fInnerDirectionSign==0.0 )
        fInnerDirectionSign = 1.0;

    B2DVector aMainDirection = m_aAxisEndScreenPosition2D-m_aAxisStartScreenPosition2D;
    aMainDirection.normalize();
    B2DVector aOrthoDirection(-aMainDirection.getY(),aMainDirection.getX());
    aOrthoDirection *= fInnerDirectionSign;
    aOrthoDirection.normalize();

    B2DVector aStart(0,0), aEnd(0,0);
    if( bFarAwayLabels )
    {
        TickmarkProperties aProps( AxisProperties::getBiggestTickmarkProperties() );
        aStart = aOrthoDirection*aProps.RelativePos;
        aEnd = aStart - aOrthoDirection*aProps.Length;
    }
    else
    {
        for( sal_Int32 nN=rAxisProperties.m_aTickmarkPropertiesList.size();nN--;)
        {
            const TickmarkProperties& rProps = rAxisProperties.m_aTickmarkPropertiesList[nN];
            B2DVector aNewStart = aOrthoDirection*rProps.RelativePos;
            B2DVector aNewEnd = aNewStart - aOrthoDirection*rProps.Length;
            if(aNewStart.getLength()>aStart.getLength())
                aStart=aNewStart;
            if(aNewEnd.getLength()>aEnd.getLength())
                aEnd=aNewEnd;
        }
    }

    B2DVector aLabelDirection(aStart);
    if (rAxisProperties.maLabelAlignment.mfInnerTickDirection != rAxisProperties.maLabelAlignment.mfLabelDirection)
        aLabelDirection = aEnd;

    B2DVector aOrthoLabelDirection(aOrthoDirection);
    if (rAxisProperties.maLabelAlignment.mfInnerTickDirection != rAxisProperties.maLabelAlignment.mfLabelDirection)
        aOrthoLabelDirection*=-1.0;
    aOrthoLabelDirection.normalize();
    if( bIncludeSpaceBetweenTickAndText )
        aLabelDirection += aOrthoLabelDirection*AXIS2D_TICKLABELSPACING;
    if( bFarAwayLabels && bIncludeFarAwayDistanceIfSo )
        aLabelDirection += m_aAxisLineToLabelLineShift;
    return aLabelDirection;
}

void TickFactory2D::createPointSequenceForAxisMainLine( drawing::PointSequenceSequence& rPoints ) const
{
    rPoints.getArray()[0] = { { static_cast<sal_Int32>(m_aAxisStartScreenPosition2D.getX()),
                                static_cast<sal_Int32>(m_aAxisStartScreenPosition2D.getY()) },
                              { static_cast<sal_Int32>(m_aAxisEndScreenPosition2D.getX()),
                                static_cast<sal_Int32>(m_aAxisEndScreenPosition2D.getY()) } };
}

void TickFactory2D::updateScreenValues( TickInfoArraysType& rAllTickInfos ) const
{
    //get the transformed screen values for all tickmarks in rAllTickInfos
    for (auto & tickInfos : rAllTickInfos)
    {
        for (auto & tickInfo : tickInfos)
        {
            tickInfo.aTickScreenPosition =
                getTickScreenPosition2D(tickInfo.fScaledTickValue);
        }
    }
}

//namespace chart

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

Messung V0.5
C=97 H=96 G=96

¤ Dauer der Verarbeitung: 0.12 Sekunden  (vorverarbeitet)  ¤

*© 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.