diff options
author | Release Engineers <releng@openoffice.org> | 2009-07-02 19:17:43 +0000 |
---|---|---|
committer | Release Engineers <releng@openoffice.org> | 2009-07-02 19:17:43 +0000 |
commit | 44569a657c4282757443ae06efc6441e571a0409 (patch) | |
tree | bf446449db3c764a11e9a327f03f9468fc31e9f5 /chart2/source/view/charttypes/BubbleChart.cxx | |
parent | be14833d0fe6be523299e09a72ae61d93a04bc04 (diff) |
CWS-TOOLING: integrate CWS bubblechart
2009-06-17 08:41:14 +0200 hde r273051 : i101635: added new charttype bubble
2009-06-17 08:39:37 +0200 hde r273050 : i101635: created new testcase tCreateNewBubbleChart
2009-06-17 08:38:07 +0200 hde r273049 : i101635: created new testcase tCreateNewBubbleChart
2009-06-15 15:22:32 +0200 hde r272991 : 101635
2009-06-11 12:44:01 +0200 iha r272864 : rebase to dev300m50
2009-06-10 23:27:54 +0200 iha r272841 : CWS-TOOLING: rebase CWS bubblechart to trunk@272827 (milestone: DEV300:m50)
2009-06-04 18:07:35 +0200 iha r272649 : #i64689# Bubble Chart
2009-06-04 17:26:44 +0200 iha r272647 : #i64689# Bubble Chart
2009-06-04 11:24:25 +0200 iha r272618 : #i64689# add more spacing between bubbles and data labels
2009-05-26 18:05:23 +0200 ufi r272314 : i101637
2009-04-22 14:37:50 +0200 iha r271115 : #i64689# bubble chart
2009-04-21 17:52:23 +0200 iha r271052 : #i64689# bubble chart
2009-04-21 17:50:48 +0200 iha r271051 : #i76728# type icon for xy chart
2009-04-21 17:25:52 +0200 iha r271049 : #i76728# type icon for xy chart
2009-04-09 11:18:09 +0200 iha r270685 : #i100977# autoscaling works not correct if missing values should be treated as zero
2009-04-08 16:39:43 +0200 iha r270656 : #i64689# bubble chart - missing value treatment
2009-04-08 15:13:25 +0200 iha r270655 : #i64689# bubble chart - remove unused code
2009-04-08 15:12:19 +0200 iha r270653 : #i64689# bubble chart - determine sereis length correctly on export
2009-04-08 14:22:43 +0200 iha r270650 : #i64689# bubble chart - remove unused code
2009-04-08 14:12:09 +0200 iha r270646 : #i64689# bubble chart - export domains even if no main sequence was found
2009-04-08 14:11:07 +0200 iha r270645 : #i64689# bubble chart - don't replace missing size values with 1.0
2009-04-07 16:20:22 +0200 iha r270602 : #i64689# bubble chart - do not offer percent values for data label display for xy and bubble chart
2009-04-07 16:17:42 +0200 iha r270601 : remove superfluous code
2009-04-06 16:39:32 +0200 iha r270569 : #i64689# bubble chart -correct automatic numberformat detection for axis, data table and data label + transport data label numberformat during copy paste in addition to axis numberformat
2009-04-02 17:33:33 +0200 iha r270427 : use input string for formatting in data table during edit
2009-04-02 16:00:29 +0200 iha r270413 : #i64689# bubble chart - when creating a new series within the data table give it the same number format as the former series, thus the new bubble size values can be edited with the same format immidiately
2009-04-02 11:25:33 +0200 iha r270385 : #i64689# bubble chart -correct automatic numberformat detection for axis, data table and data label + transport data label numberformat during copy paste in addition to axis numberformat
2009-04-01 11:32:03 +0200 iha r270312 : #i64689# bubble chart - add further parameter for view creation
2009-03-31 17:52:08 +0200 iha r270291 : #i64689# bubble chart - scale bubble size with diagram size
2009-03-31 13:38:13 +0200 iha r270278 : #i64689# bubble chart - wrong size for small values < 1
2009-03-27 19:11:07 +0100 iha r270169 : #i64689# bubble chart
2009-03-27 19:07:11 +0100 iha r270168 : #i64689# bubble chart - remove unused code
2009-03-27 18:33:57 +0100 iha r270167 : #i64689# bubble chart - create no shape for invalid sizes
2009-03-27 15:18:21 +0100 iha r270157 : #i76728# type icon for xy chart
2009-03-27 14:34:38 +0100 iha r270156 : #i64689# bubble chart - correct scaling
2009-03-27 14:27:27 +0100 iha r270155 : #i64689# bubble chart - images
2009-03-27 14:25:45 +0100 iha r270154 : #i64689# bubble chart - images
2009-03-27 11:38:57 +0100 iha r270142 : #i64689# bubble chart - values-size is the main series
2009-03-27 11:30:20 +0100 iha r270140 : #i64689# correct order of sequences after load thus switching charttypes afterwards produces expected results now
2009-03-26 10:22:55 +0100 iha r270056 : #i64689# bubble chart
2009-03-24 17:45:15 +0100 iha r269984 : #i64689# bubble chart - user properties from points (not only from the series)
2009-03-24 15:10:57 +0100 dr r269954 : #i64989# export bubble charts to xls
2009-03-24 14:55:29 +0100 dr r269952 : #i64989# import bubble charts from xls
2009-03-24 14:54:46 +0100 dr r269950 : #i64989# import bubble charts from ooxml
2009-03-23 18:59:08 +0100 iha r269895 : further cleanups possible with new member m_aGlobalSeriesImportInfo
2009-03-23 16:54:04 +0100 iha r269886 : #i64689# bubble chart - a single sequence must be interpreted as sizes because of ODF specification
2009-03-23 16:50:43 +0100 iha r269885 : #i64689# save&load bubble chart
2009-03-20 19:30:29 +0100 iha r269826 : CWS-TOOLING: rebase CWS bubblechart to trunk@269781 (milestone: DEV300:m44)
2009-03-19 11:30:33 +0100 iha r269732 : #i64689# rename SchXMLCategoriesDomainContext to SchXMLCategoriesContext avoid confusion with domains
2009-03-18 17:11:13 +0100 iha r269693 : #i64689# add charttype bubble
2009-03-18 17:09:22 +0100 iha r269692 : #i64689# remove unused code
2009-03-13 12:18:26 +0100 iha r269467 : #i64689# corrected lineends
2009-03-12 11:25:14 +0100 iha r269376 : #i64689# bubble chart (part 1)
Diffstat (limited to 'chart2/source/view/charttypes/BubbleChart.cxx')
-rw-r--r-- | chart2/source/view/charttypes/BubbleChart.cxx | 420 |
1 files changed, 420 insertions, 0 deletions
diff --git a/chart2/source/view/charttypes/BubbleChart.cxx b/chart2/source/view/charttypes/BubbleChart.cxx new file mode 100644 index 000000000000..b63603ef403a --- /dev/null +++ b/chart2/source/view/charttypes/BubbleChart.cxx @@ -0,0 +1,420 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: ,v $ + * $Revision: $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_chart2.hxx" + +#include "BubbleChart.hxx" +#include "PlottingPositionHelper.hxx" +#include "ShapeFactory.hxx" +#include "CommonConverters.hxx" +#include "macros.hxx" +#include "ViewDefines.hxx" +#include "ObjectIdentifier.hxx" +#include "Splines.hxx" +#include "LabelPositionHelper.hxx" +#include "Clipping.hxx" +#include "Stripe.hxx" + +#include <com/sun/star/chart2/Symbol.hpp> +#include <com/sun/star/chart/DataLabelPlacement.hpp> +#include <tools/debug.hxx> +#include <svx/unoprnms.hxx> +#include <rtl/math.hxx> +#include <com/sun/star/drawing/DoubleSequence.hpp> +#include <com/sun/star/drawing/NormalsKind.hpp> +#include <com/sun/star/lang/XServiceName.hpp> + +//............................................................................. +namespace chart +{ +//............................................................................. +using namespace ::com::sun::star; +using namespace ::rtl::math; +using namespace ::com::sun::star::chart2; + +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- + +BubbleChart::BubbleChart( const uno::Reference<XChartType>& xChartTypeModel + , sal_Int32 nDimensionCount ) + : VSeriesPlotter( xChartTypeModel, nDimensionCount, false ) + , m_bShowNegativeValues(false) + , m_bBubbleSizeAsArea(true) + , m_fBubbleSizeScaling(1.0) + , m_fMaxLogicBubbleSize( 0.0 ) + , m_fBubbleSizeFactorToScreen( 1.0 ) +{ + if( !m_pMainPosHelper ) + m_pMainPosHelper = new PlottingPositionHelper(); + PlotterBase::m_pPosHelper = m_pMainPosHelper; + VSeriesPlotter::m_pMainPosHelper = m_pMainPosHelper; +} + +BubbleChart::~BubbleChart() +{ + delete m_pMainPosHelper; +} + +void BubbleChart::calculateMaximumLogicBubbleSize() +{ + double fMaxSize = 0.0; + + sal_Int32 nStartIndex = 0; + sal_Int32 nEndIndex = VSeriesPlotter::getPointCount(); + for( sal_Int32 nIndex = nStartIndex; nIndex < nEndIndex; nIndex++ ) + { + ::std::vector< ::std::vector< VDataSeriesGroup > >::iterator aZSlotIter = m_aZSlots.begin(); + const ::std::vector< ::std::vector< VDataSeriesGroup > >::const_iterator aZSlotEnd = m_aZSlots.end(); + for( ; aZSlotIter != aZSlotEnd; aZSlotIter++ ) + { + ::std::vector< VDataSeriesGroup >::iterator aXSlotIter = aZSlotIter->begin(); + const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = aZSlotIter->end(); + for( ; aXSlotIter != aXSlotEnd; aXSlotIter++ ) + { + ::std::vector< VDataSeries* >* pSeriesList = &(aXSlotIter->m_aSeriesVector); + ::std::vector< VDataSeries* >::const_iterator aSeriesIter = pSeriesList->begin(); + const ::std::vector< VDataSeries* >::const_iterator aSeriesEnd = pSeriesList->end(); + for( ; aSeriesIter != aSeriesEnd; aSeriesIter++ ) + { + VDataSeries* pSeries( *aSeriesIter ); + if(!pSeries) + continue; + + double fSize = pSeries->getBubble_Size( nIndex ); + if( m_bShowNegativeValues ) + fSize = abs(fSize); + if( fSize > fMaxSize ) + fMaxSize = fSize; + } + } + } + } + + m_fMaxLogicBubbleSize = fMaxSize; +} + +void BubbleChart::calculateBubbleSizeScalingFactor() +{ + double fLogicZ=0.5; + drawing::Position3D aSceneMinPos( m_pMainPosHelper->transformLogicToScene( m_pMainPosHelper->getLogicMinX(),m_pMainPosHelper->getLogicMinY(),fLogicZ, false ) ); + drawing::Position3D aSceneMaxPos( m_pMainPosHelper->transformLogicToScene( m_pMainPosHelper->getLogicMaxX(),m_pMainPosHelper->getLogicMaxY(),fLogicZ, false ) ); + + awt::Point aScreenMinPos( LabelPositionHelper(m_pMainPosHelper,m_nDimension,m_xLogicTarget,m_pShapeFactory).transformSceneToScreenPosition( aSceneMinPos ) ); + awt::Point aScreenMaxPos( LabelPositionHelper(m_pMainPosHelper,m_nDimension,m_xLogicTarget,m_pShapeFactory).transformSceneToScreenPosition( aSceneMaxPos ) ); + + sal_Int32 nWidth = abs( aScreenMaxPos.X - aScreenMinPos.X ); + sal_Int32 nHeight = abs( aScreenMaxPos.Y - aScreenMinPos.Y ); + + sal_Int32 nMinExtend = std::min( nWidth, nHeight ); + m_fBubbleSizeFactorToScreen = nMinExtend * 0.25;//max bubble size is 25 percent of diagram size +} + +drawing::Direction3D BubbleChart::transformToScreenBubbleSize( double fLogicSize ) +{ + drawing::Direction3D aRet(0,0,0); + + if( ::rtl::math::isNan(fLogicSize) || ::rtl::math::isInf(fLogicSize) ) + return aRet; + + if( m_bShowNegativeValues ) + fLogicSize = abs(fLogicSize); + + double fMaxSize = m_fMaxLogicBubbleSize; + + double fMaxRadius = fMaxSize; + double fRaduis = fLogicSize; + if( m_bBubbleSizeAsArea ) + { + fMaxRadius = sqrt( fMaxSize / F_PI ); + fRaduis = sqrt( fLogicSize / F_PI ); + } + + aRet.DirectionX = m_fBubbleSizeScaling * m_fBubbleSizeFactorToScreen * fRaduis / fMaxRadius; + aRet.DirectionY = aRet.DirectionX; + + return aRet; +} + +bool BubbleChart::isExpandIfValuesCloseToBorder( sal_Int32 /*nDimensionIndex*/ ) +{ + return true; +} + +bool BubbleChart::isSeperateStackingForDifferentSigns( sal_Int32 /*nDimensionIndex*/ ) +{ + return false; +} + +//----------------------------------------------------------------- + +LegendSymbolStyle BubbleChart::getLegendSymbolStyle() +{ + return chart2::LegendSymbolStyle_CIRCLE; +} + +drawing::Direction3D BubbleChart::getPreferredDiagramAspectRatio() const +{ + return drawing::Direction3D(-1,-1,-1); +} + +void BubbleChart::addSeries( VDataSeries* pSeries, sal_Int32 zSlot, sal_Int32 xSlot, sal_Int32 ySlot ) +{ + VSeriesPlotter::addSeries( pSeries, zSlot, xSlot, ySlot ); +} + +//better performance for big data +struct FormerPoint +{ + FormerPoint( double fX, double fY, double fZ ) + : m_fX(fX), m_fY(fY), m_fZ(fZ) + {} + FormerPoint() + { + ::rtl::math::setNan( &m_fX ); + ::rtl::math::setNan( &m_fY ); + ::rtl::math::setNan( &m_fZ ); + } + + double m_fX; + double m_fY; + double m_fZ; +}; + +void BubbleChart::createShapes() +{ + if( m_aZSlots.begin() == m_aZSlots.end() ) //no series + return; + + DBG_ASSERT(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is(),"BubbleChart is not proper initialized"); + if(!(m_pShapeFactory&&m_xLogicTarget.is()&&m_xFinalTarget.is())) + return; + + //therefore create an own group for the texts and the error bars to move them to front + //(because the text group is created after the series group the texts are displayed on top) + uno::Reference< drawing::XShapes > xSeriesTarget( + createGroupShape( m_xLogicTarget,rtl::OUString() )); + uno::Reference< drawing::XShapes > xTextTarget( + m_pShapeFactory->createGroup2D( m_xFinalTarget,rtl::OUString() )); + + //update/create information for current group + double fLogicZ = 0.5;//as defined + + sal_Int32 nStartIndex = 0; // inclusive ;..todo get somehow from x scale + sal_Int32 nEndIndex = VSeriesPlotter::getPointCount(); + if(nEndIndex<=0) + nEndIndex=1; + + //better performance for big data + std::map< VDataSeries*, FormerPoint > aSeriesFormerPointMap; + m_bPointsWereSkipped = false; + sal_Int32 nSkippedPoints = 0; + sal_Int32 nCreatedPoints = 0; + // + + calculateMaximumLogicBubbleSize(); + calculateBubbleSizeScalingFactor(); + if( m_fMaxLogicBubbleSize <= 0 || m_fBubbleSizeFactorToScreen <= 0 ) + return; + +//============================================================================= + //iterate through all x values per indices + for( sal_Int32 nIndex = nStartIndex; nIndex < nEndIndex; nIndex++ ) + { + ::std::vector< ::std::vector< VDataSeriesGroup > >::iterator aZSlotIter = m_aZSlots.begin(); + const ::std::vector< ::std::vector< VDataSeriesGroup > >::const_iterator aZSlotEnd = m_aZSlots.end(); + + aZSlotIter = m_aZSlots.begin(); + for( sal_Int32 nZ=1; aZSlotIter != aZSlotEnd; aZSlotIter++, nZ++ ) + { + ::std::vector< VDataSeriesGroup >::iterator aXSlotIter = aZSlotIter->begin(); + const ::std::vector< VDataSeriesGroup >::const_iterator aXSlotEnd = aZSlotIter->end(); + + aXSlotIter = aZSlotIter->begin(); + for( sal_Int32 nX=0; aXSlotIter != aXSlotEnd; aXSlotIter++, nX++ ) + { + ::std::vector< VDataSeries* >* pSeriesList = &(aXSlotIter->m_aSeriesVector); + ::std::vector< VDataSeries* >::const_iterator aSeriesIter = pSeriesList->begin(); + const ::std::vector< VDataSeries* >::const_iterator aSeriesEnd = pSeriesList->end(); + + //============================================================================= + //iterate through all series + for( sal_Int32 nSeriesIndex = 0; aSeriesIter != aSeriesEnd; aSeriesIter++, nSeriesIndex++ ) + { + VDataSeries* pSeries( *aSeriesIter ); + if(!pSeries) + continue; + + uno::Reference< drawing::XShapes > xSeriesGroupShape_Shapes = getSeriesGroupShape(*aSeriesIter, xSeriesTarget); + + sal_Int32 nAttachedAxisIndex = pSeries->getAttachedAxisIndex(); + PlottingPositionHelper* pPosHelper = &(this->getPlottingPositionHelper( nAttachedAxisIndex )); + if(!pPosHelper) + pPosHelper = m_pMainPosHelper; + PlotterBase::m_pPosHelper = pPosHelper; + + if(m_nDimension==3) + fLogicZ = nZ+0.5; + + //collect data point information (logic coordinates, style ): + double fLogicX = pSeries->getXValue(nIndex); + double fLogicY = pSeries->getYValue(nIndex); + double fBubbleSize = pSeries->getBubble_Size( nIndex ); + + if( !m_bShowNegativeValues && fBubbleSize<0.0 ) + continue; + + if( ::rtl::math::approxEqual( fBubbleSize, 0.0 ) || ::rtl::math::isNan(fBubbleSize) ) + continue; + + if( ::rtl::math::isNan(fLogicX) || ::rtl::math::isInf(fLogicX) + || ::rtl::math::isNan(fLogicY) || ::rtl::math::isInf(fLogicY) ) + continue; + + bool bIsVisible = pPosHelper->isLogicVisible( fLogicX, fLogicY, fLogicZ ); + + drawing::Position3D aUnscaledLogicPosition( fLogicX, fLogicY, fLogicZ ); + drawing::Position3D aScaledLogicPosition(aUnscaledLogicPosition); + pPosHelper->doLogicScaling( aScaledLogicPosition ); + + //transformation 3) -> 4) + drawing::Position3D aScenePosition( pPosHelper->transformLogicToScene( fLogicX,fLogicY,fLogicZ, false ) ); + + //better performance for big data + FormerPoint aFormerPoint( aSeriesFormerPointMap[pSeries] ); + pPosHelper->setCoordinateSystemResolution( m_aCoordinateSystemResolution ); + if( !pSeries->isAttributedDataPoint(nIndex) + && + pPosHelper->isSameForGivenResolution( aFormerPoint.m_fX, aFormerPoint.m_fY, aFormerPoint.m_fZ + , aScaledLogicPosition.PositionX, aScaledLogicPosition.PositionY, aScaledLogicPosition.PositionZ ) ) + { + nSkippedPoints++; + m_bPointsWereSkipped = true; + continue; + } + aSeriesFormerPointMap[pSeries] = FormerPoint(aScaledLogicPosition.PositionX, aScaledLogicPosition.PositionY, aScaledLogicPosition.PositionZ); + + //create a single datapoint if point is visible + if( !bIsVisible ) + continue; + + //create a group shape for this point and add to the series shape: + rtl::OUString aPointCID = ObjectIdentifier::createPointCID( + pSeries->getPointCID_Stub(), nIndex ); + uno::Reference< drawing::XShapes > xPointGroupShape_Shapes( + createGroupShape(xSeriesGroupShape_Shapes,aPointCID) ); + uno::Reference<drawing::XShape> xPointGroupShape_Shape = + uno::Reference<drawing::XShape>( xPointGroupShape_Shapes, uno::UNO_QUERY ); + + { + nCreatedPoints++; + + //create data point + drawing::Direction3D aSymbolSize = transformToScreenBubbleSize( fBubbleSize ); + if(m_nDimension!=3) + { + uno::Reference<drawing::XShape> xShape; + xShape = m_pShapeFactory->createCircle2D( xPointGroupShape_Shapes + , aScenePosition, aSymbolSize ); + + this->setMappedProperties( xShape + , pSeries->getPropertiesOfPoint( nIndex ) + , PropertyMapper::getPropertyNameMapForFilledSeriesProperties() ); + + m_pShapeFactory->setShapeName( xShape, C2U("MarkHandles") ); + } + + //create data point label + if( (**aSeriesIter).getDataPointLabelIfLabel(nIndex) ) + { + LabelAlignment eAlignment = LABEL_ALIGN_TOP; + drawing::Position3D aScenePosition3D( aScenePosition.PositionX + , aScenePosition.PositionY + , aScenePosition.PositionZ+this->getTransformedDepth() ); + + sal_Int32 nLabelPlacement = pSeries->getLabelPlacement( nIndex, m_xChartTypeModel, m_nDimension, pPosHelper->isSwapXAndY() ); + + switch(nLabelPlacement) + { + case ::com::sun::star::chart::DataLabelPlacement::TOP: + aScenePosition3D.PositionY -= (aSymbolSize.DirectionY/2+1); + eAlignment = LABEL_ALIGN_TOP; + break; + case ::com::sun::star::chart::DataLabelPlacement::BOTTOM: + aScenePosition3D.PositionY += (aSymbolSize.DirectionY/2+1); + eAlignment = LABEL_ALIGN_BOTTOM; + break; + case ::com::sun::star::chart::DataLabelPlacement::LEFT: + aScenePosition3D.PositionX -= (aSymbolSize.DirectionX/2+1); + eAlignment = LABEL_ALIGN_LEFT; + break; + case ::com::sun::star::chart::DataLabelPlacement::RIGHT: + aScenePosition3D.PositionX += (aSymbolSize.DirectionX/2+1); + eAlignment = LABEL_ALIGN_RIGHT; + break; + case ::com::sun::star::chart::DataLabelPlacement::CENTER: + eAlignment = LABEL_ALIGN_CENTER; + break; + default: + DBG_ERROR("this label alignment is not implemented yet"); + aScenePosition3D.PositionY -= (aSymbolSize.DirectionY/2+1); + eAlignment = LABEL_ALIGN_TOP; + break; + } + + + awt::Point aScreenPosition2D( LabelPositionHelper(pPosHelper,m_nDimension,m_xLogicTarget,m_pShapeFactory) + .transformSceneToScreenPosition( aScenePosition3D ) ); + sal_Int32 nOffset = 0; + if(LABEL_ALIGN_CENTER!=eAlignment) + nOffset = 100;//add some spacing //@todo maybe get more intelligent values + this->createDataLabel( xTextTarget, **aSeriesIter, nIndex + , fBubbleSize, fBubbleSize, aScreenPosition2D, eAlignment, nOffset ); + } + } + + //remove PointGroupShape if empty + if(!xPointGroupShape_Shapes->getCount()) + xSeriesGroupShape_Shapes->remove(xPointGroupShape_Shape); + + }//next series in x slot (next y slot) + }//next x slot + }//next z slot + }//next category +//============================================================================= +//============================================================================= +//============================================================================= + OSL_TRACE( "\nPPPPPPPPP<<<<<<<<<<<< area chart :: createShapes():: skipped points: %d created points: %d", nSkippedPoints, nCreatedPoints ); +} + +//............................................................................. +} //namespace chart +//............................................................................. |