summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorSzymon Kłos <szymon.klos@collabora.com>2018-02-12 20:39:14 +0100
committerAndras Timar <andras.timar@collabora.com>2018-02-12 20:39:14 +0100
commit55e7f7f8d76db06505a04ff7b8505455aff50c5e (patch)
treeadfbf0e03a9a4dd962bc21163dad9ffc92c65db1 /oox
parent24d674338b4651222620d5823f1d8fe026566679 (diff)
tdf#114821 import/export/place complex data labels in charts
Change-Id: Ia44abcebb4febcabb1704aef85e396730ac2cd6f
Diffstat (limited to 'oox')
-rw-r--r--oox/inc/drawingml/textfield.hxx2
-rw-r--r--oox/source/drawingml/chart/seriesconverter.cxx112
-rw-r--r--oox/source/export/chartexport.cxx107
-rw-r--r--oox/source/token/properties.txt1
4 files changed, 208 insertions, 14 deletions
diff --git a/oox/inc/drawingml/textfield.hxx b/oox/inc/drawingml/textfield.hxx
index 9f5bf9cf27af..7cc15a04fce4 100644
--- a/oox/inc/drawingml/textfield.hxx
+++ b/oox/inc/drawingml/textfield.hxx
@@ -38,7 +38,9 @@ public:
const TextParagraphProperties& getTextParagraphProperties() const { return maTextParagraphProperties; }
void setType( const OUString& sType ) { msType = sType; }
+ const OUString& getType() const { return msType; }
void setUuid( const OUString & sUuid ) { msUuid = sUuid; }
+ const OUString& getUuid() const { return msUuid; }
virtual sal_Int32 insertAt(
const ::oox::core::XmlFilterBase& rFilterBase,
diff --git a/oox/source/drawingml/chart/seriesconverter.cxx b/oox/source/drawingml/chart/seriesconverter.cxx
index d0ed206cd0b1..666620b09845 100644
--- a/oox/source/drawingml/chart/seriesconverter.cxx
+++ b/oox/source/drawingml/chart/seriesconverter.cxx
@@ -22,11 +22,16 @@
#include <com/sun/star/chart/DataLabelPlacement.hpp>
#include <com/sun/star/chart/ErrorBarStyle.hpp>
#include <com/sun/star/chart2/DataPointLabel.hpp>
+#include <com/sun/star/chart2/XDataPointCustomLabelField.hpp>
+#include <com/sun/star/chart2/DataPointCustomLabelField.hpp>
+#include <com/sun/star/chart2/DataPointCustomLabelFieldType.hpp>
#include <com/sun/star/chart2/XDataSeries.hpp>
#include <com/sun/star/chart2/XRegressionCurve.hpp>
#include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
#include <com/sun/star/chart2/data/XDataSink.hpp>
#include <com/sun/star/chart2/data/LabeledDataSequence.hpp>
+#include <com/sun/star/chart2/XFormattedString2.hpp>
+#include <com/sun/star/chart2/FormattedString.hpp>
#include <osl/diagnose.h>
#include <basegfx/numeric/ftools.hxx>
#include "drawingml/chart/datasourceconverter.hxx"
@@ -41,6 +46,10 @@
#include <oox/token/properties.hxx>
#include <oox/token/tokens.hxx>
#include <oox/drawingml/lineproperties.hxx>
+#include <drawingml/textparagraph.hxx>
+#include <drawingml/textrun.hxx>
+#include <drawingml/textfield.hxx>
+#include <drawingml/textbody.hxx>
namespace oox {
namespace drawingml {
@@ -54,13 +63,30 @@ using namespace ::com::sun::star::uno;
namespace {
-/** nested-up sgn function - employs some gratuity around 0 - values
- smaller than 0.33 are clamped to 0
+/** Function to get vertical position of label from chart height factor.
+ Value can be negative, prefer top placement.
*/
-int lclSgn( double nVal )
+int lclGetPositionY( double nVal )
{
- const int intVal=nVal*3;
- return intVal == 0 ? 0 : (intVal < 0 ? -1 : 1);
+ if( nVal <= 0.1 )
+ return -1;
+ else if( nVal <= 0.6 )
+ return 0;
+ else
+ return 1;
+}
+
+/** Function to get horizontal position of label from chart width factor.
+ Value can be negative, prefer center placement.
+*/
+int lclGetPositionX( double nVal )
+{
+ if( nVal <= -0.2 )
+ return -1;
+ else if( nVal <= 0.2 )
+ return 0;
+ else
+ return 1;
}
Reference< XLabeledDataSequence > lclCreateLabeledDataSequence(
@@ -193,6 +219,20 @@ void importBorderProperties( PropertySet& rPropSet, Shape& rShape, const Graphic
rPropSet.setProperty(PROP_LabelBorderColor, uno::makeAny(nColor));
}
+DataPointCustomLabelFieldType lcl_ConvertFieldNameToFieldEnum( const OUString& rField )
+{
+ if (rField == "VALUE")
+ return DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_VALUE;
+ else if (rField == "SERIESNAME")
+ return DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_SERIESNAME;
+ else if (rField == "CATEGORYNAME")
+ return DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_CATEGORYNAME;
+ else if (rField == "CELLREF")
+ return DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_CELLREF;
+ else
+ return DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_TEXT;
+}
+
} // namespace
DataLabelConverter::DataLabelConverter( const ConverterRoot& rParent, DataLabelModel& rModel ) :
@@ -228,17 +268,69 @@ void DataLabelConverter::convertFromModel( const Reference< XDataSeries >& rxDat
csscd::LEFT, csscd::CENTER, csscd::RIGHT,
csscd::BOTTOM_LEFT, csscd::BOTTOM, csscd::BOTTOM_RIGHT
};
- const double nMax=std::max(
- fabs(mrModel.mxLayout->mfX),
- fabs(mrModel.mxLayout->mfY));
- const int simplifiedX=lclSgn(mrModel.mxLayout->mfX/nMax);
- const int simplifiedY=lclSgn(mrModel.mxLayout->mfY/nMax);
+ const int simplifiedX = lclGetPositionX(mrModel.mxLayout->mfX);
+ const int simplifiedY = lclGetPositionY(mrModel.mxLayout->mfY);
aPropSet.setProperty( PROP_LabelPlacement,
aPositionsLookupTable[ simplifiedX+1 + 3*(simplifiedY+1) ] );
}
if (mrModel.mxShapeProp)
importBorderProperties(aPropSet, *mrModel.mxShapeProp, getFilter().getGraphicHelper());
+
+ if( mrModel.mxText && mrModel.mxText->mxTextBody && mrModel.mxText->mxTextBody->getParagraphs().size() )
+ {
+ css::uno::Reference< XComponentContext > xContext = getComponentContext();
+ uno::Sequence< css::uno::Reference< XDataPointCustomLabelField > > aSequence;
+
+ auto& rParagraphs = mrModel.mxText->mxTextBody->getParagraphs();
+
+ int nSequenceSize = 0;
+ for( auto& pParagraph : rParagraphs )
+ nSequenceSize += pParagraph->getRuns().size();
+
+ int nParagraphs = rParagraphs.size();
+ if( nParagraphs > 1 )
+ nSequenceSize += nParagraphs - 1;
+
+ aSequence.realloc( nSequenceSize );
+
+ int nPos = 0;
+ for( auto& pParagraph : rParagraphs )
+ {
+ for( auto& pRun : pParagraph->getRuns() )
+ {
+ css::uno::Reference< XDataPointCustomLabelField > xCustomLabel = DataPointCustomLabelField::create( xContext );
+
+ // Store properties
+ oox::PropertySet aPropertySet( xCustomLabel );
+ pRun->getTextCharacterProperties().pushToPropSet( aPropertySet, getFilter() );
+
+ TextField* pField = nullptr;
+ if( ( pField = dynamic_cast< TextField* >( pRun.get() ) ) )
+ {
+ xCustomLabel->setString( pField->getText() );
+ xCustomLabel->setFieldType( lcl_ConvertFieldNameToFieldEnum( pField->getType() ) );
+ xCustomLabel->setGuid( pField->getUuid() );
+ }
+ else if( pRun.get() )
+ {
+ xCustomLabel->setString( pRun->getText() );
+ xCustomLabel->setFieldType( DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_TEXT );
+ }
+ aSequence[ nPos++ ] = xCustomLabel;
+ }
+
+ if( nParagraphs > 1 && nPos < nSequenceSize )
+ {
+ css::uno::Reference< XDataPointCustomLabelField > xCustomLabel = DataPointCustomLabelField::create( xContext );
+ xCustomLabel->setFieldType( DataPointCustomLabelFieldType::DataPointCustomLabelFieldType_NEWLINE );
+ xCustomLabel->setString("\n");
+ aSequence[ nPos++ ] = xCustomLabel;
+ }
+ }
+
+ aPropSet.setProperty( PROP_CustomLabelFields, makeAny( aSequence ) );
+ }
}
catch( Exception& )
{
diff --git a/oox/source/export/chartexport.cxx b/oox/source/export/chartexport.cxx
index 18b9a02bcd0d..142761afb89d 100644
--- a/oox/source/export/chartexport.cxx
+++ b/oox/source/export/chartexport.cxx
@@ -57,6 +57,8 @@
#include <com/sun/star/chart2/XDataSeriesContainer.hpp>
#include <com/sun/star/chart2/DataPointGeometry3D.hpp>
#include <com/sun/star/chart2/DataPointLabel.hpp>
+#include <com/sun/star/chart2/DataPointCustomLabelField.hpp>
+#include <com/sun/star/chart2/DataPointCustomLabelFieldType.hpp>
#include <com/sun/star/chart2/Symbol.hpp>
#include <com/sun/star/chart2/data/XDataSource.hpp>
#include <com/sun/star/chart2/data/XDataSink.hpp>
@@ -2955,17 +2957,111 @@ const char* toOOXMLPlacement( sal_Int32 nPlacement )
return "outEnd";
}
-void writeLabelProperties(
- const FSHelperPtr& pFS, const uno::Reference<beans::XPropertySet>& xPropSet, const LabelPlacementParam& rLabelParam )
+OUString getFieldTypeString( const chart2::DataPointCustomLabelFieldType aType )
+{
+ switch (aType)
+ {
+ case chart2::DataPointCustomLabelFieldType_CATEGORYNAME:
+ return OUString("CATEGORYNAME");
+
+ case chart2::DataPointCustomLabelFieldType_SERIESNAME:
+ return OUString("SERIESNAME");
+
+ case chart2::DataPointCustomLabelFieldType_VALUE:
+ return OUString("VALUE");
+
+ case chart2::DataPointCustomLabelFieldType_CELLREF:
+ return OUString("CELLREF");
+
+ default:
+ break;
+ }
+ return OUString();
+}
+
+void writeRunProperties( ChartExport* pChartExport, Reference<XPropertySet>& xPropertySet )
+{
+ bool bDummy = false;
+ sal_Int32 nDummy;
+ pChartExport->WriteRunProperties(xPropertySet, false, XML_rPr, true, bDummy, nDummy);
+}
+
+void writeCustomLabel( const FSHelperPtr& pFS, ChartExport* pChartExport,
+ const Sequence<Reference<chart2::XDataPointCustomLabelField>>& rCustomLabelFields )
+{
+ pFS->startElement(FSNS(XML_c, XML_tx), FSEND);
+ pFS->startElement(FSNS(XML_c, XML_rich), FSEND);
+
+ // TODO: body properties?
+ pFS->singleElement(FSNS(XML_a, XML_bodyPr), FSEND);
+
+ OUString sFieldType;
+ bool bNewParagraph;
+ pFS->startElement(FSNS(XML_a, XML_p), FSEND);
+
+ for (auto& rField : rCustomLabelFields)
+ {
+ Reference<XPropertySet> xPropertySet(rField, UNO_QUERY);
+ chart2::DataPointCustomLabelFieldType aType = rField->getFieldType();
+ sFieldType.clear();
+ bNewParagraph = false;
+
+ if (aType == chart2::DataPointCustomLabelFieldType_NEWLINE)
+ bNewParagraph = true;
+ else if (aType != chart2::DataPointCustomLabelFieldType_TEXT)
+ sFieldType = getFieldTypeString(aType);
+
+ if (bNewParagraph)
+ {
+ pFS->endElement(FSNS(XML_a, XML_p));
+ pFS->startElement(FSNS(XML_a, XML_p), FSEND);
+ continue;
+ }
+
+ if (sFieldType.isEmpty())
+ {
+ // Normal text run
+ pFS->startElement(FSNS(XML_a, XML_r), FSEND);
+ writeRunProperties(pChartExport, xPropertySet);
+
+ pFS->startElement(FSNS(XML_a, XML_t), FSEND);
+ pFS->writeEscaped(rField->getString());
+ pFS->endElement(FSNS(XML_a, XML_t));
+
+ pFS->endElement(FSNS(XML_a, XML_r));
+ }
+ else
+ {
+ // Field
+ pFS->startElement(FSNS(XML_a, XML_fld), XML_id, USS(rField->getGuid()), XML_type, USS(sFieldType), FSEND);
+ writeRunProperties(pChartExport, xPropertySet);
+
+ pFS->startElement(FSNS(XML_a, XML_t), FSEND);
+ pFS->writeEscaped(rField->getString());
+ pFS->endElement(FSNS(XML_a, XML_t));
+
+ pFS->endElement(FSNS(XML_a, XML_fld));
+ }
+ }
+
+ pFS->endElement(FSNS(XML_a, XML_p));
+ pFS->endElement(FSNS(XML_c, XML_rich));
+ pFS->endElement(FSNS(XML_c, XML_tx));
+}
+
+void writeLabelProperties( const FSHelperPtr& pFS, ChartExport* pChartExport,
+ const uno::Reference<beans::XPropertySet>& xPropSet, const LabelPlacementParam& rLabelParam )
{
if (!xPropSet.is())
return;
chart2::DataPointLabel aLabel;
+ Sequence<Reference<chart2::XDataPointCustomLabelField>> aCustomLabelFields;
sal_Int32 nLabelBorderWidth = 0;
sal_Int32 nLabelBorderColor = 0x00FFFFFF;
xPropSet->getPropertyValue("Label") >>= aLabel;
+ xPropSet->getPropertyValue("CustomLabelFields") >>= aCustomLabelFields;
xPropSet->getPropertyValue("LabelBorderWidth") >>= nLabelBorderWidth;
xPropSet->getPropertyValue("LabelBorderColor") >>= nLabelBorderColor;
@@ -2986,6 +3082,9 @@ void writeLabelProperties(
pFS->endElement(FSNS(XML_c, XML_spPr));
}
+ if (aCustomLabelFields.getLength() > 0)
+ writeCustomLabel(pFS, pChartExport, aCustomLabelFields);
+
if (rLabelParam.mbExport)
{
sal_Int32 nLabelPlacement = rLabelParam.meDefault;
@@ -3081,12 +3180,12 @@ void ChartExport::exportDataLabels(
// Individual label property that overwrites the baseline.
pFS->startElement(FSNS(XML_c, XML_dLbl), FSEND);
pFS->singleElement(FSNS(XML_c, XML_idx), XML_val, I32S(nIdx), FSEND);
- writeLabelProperties(pFS, xLabelPropSet, aParam);
+ writeLabelProperties(pFS, this, xLabelPropSet, aParam);
pFS->endElement(FSNS(XML_c, XML_dLbl));
}
// Baseline label properties for all labels.
- writeLabelProperties(pFS, xPropSet, aParam);
+ writeLabelProperties(pFS, this, xPropSet, aParam);
pFS->singleElement(FSNS(XML_c, XML_showLeaderLines),
XML_val, "0",
diff --git a/oox/source/token/properties.txt b/oox/source/token/properties.txt
index f4ca60265708..c8715881b80e 100644
--- a/oox/source/token/properties.txt
+++ b/oox/source/token/properties.txt
@@ -278,6 +278,7 @@ LabelBorderWidth
LabelPlacement
LabelPosition
LabelSeparator
+CustomLabelFields
LayoutInfo
LeftBorder
LeftBorderDistance