[PATCH] fdo#61135 stepped lines graph: handle ods files
Eric Seynaeve (via Code Review)
gerrit at gerrit.libreoffice.org
Thu Feb 28 14:45:44 PST 2013
Hi,
I have submitted a patch for review:
https://gerrit.libreoffice.org/2476
To pull it, you can do:
git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/76/2476/1
fdo#61135 stepped lines graph: handle ods files
The boilerplate code for drawing the 4 types of stepped is in place (as
described in ODF1.3,
https://tools.oasis-open.org/issues/browse/OFFICE-3662).
We can also read the current attribute used in Gnumeric and keep this
during saves from LO.
Change-Id: I0f04a779de4b65326ed7ce6de56191f11b51c596
---
M chart2/source/controller/chartapiwrapper/WrappedSplineProperties.cxx
M chart2/source/view/charttypes/AreaChart.cxx
M chart2/source/view/charttypes/AreaChart.hxx
M offapi/com/sun/star/chart2/CurveStyle.idl
M xmloff/inc/xmloff/xmltoken.hxx
M xmloff/source/chart/PropertyMap.hxx
M xmloff/source/core/xmltoken.cxx
M xmloff/source/transform/StyleOASISTContext.cxx
8 files changed, 316 insertions(+), 22 deletions(-)
diff --git a/chart2/source/controller/chartapiwrapper/WrappedSplineProperties.cxx b/chart2/source/controller/chartapiwrapper/WrappedSplineProperties.cxx
index d68bdc5..d3db08d 100644
--- a/chart2/source/controller/chartapiwrapper/WrappedSplineProperties.cxx
+++ b/chart2/source/controller/chartapiwrapper/WrappedSplineProperties.cxx
@@ -231,12 +231,41 @@
rInnerValue >>= aInnerValue;
sal_Int32 nOuterValue;
- if( chart2::CurveStyle_CUBIC_SPLINES == aInnerValue )
- nOuterValue = 1;
- else if( chart2::CurveStyle_B_SPLINES == aInnerValue )
- nOuterValue = 2;
- else
- nOuterValue = 0;
+ switch (aInnerValue)
+ {
+ case chart2::CurveStyle_CUBIC_SPLINES:
+ nOuterValue = 1;
+ break;
+ case chart2::CurveStyle_B_SPLINES:
+ nOuterValue = 2;
+ break;
+ case chart2::CurveStyle_STEP_START:
+ nOuterValue = 3;
+ break;
+ case chart2::CurveStyle_STEP_END:
+ nOuterValue = 4;
+ break;
+ case chart2::CurveStyle_STEP_CENTER_X:
+ nOuterValue = 5;
+ break;
+ case chart2::CurveStyle_STEP_CENTER_Y:
+ nOuterValue = 6;
+ break;
+ case chart2::CurveStyle_GNM_STEP_START:
+ nOuterValue = 7;
+ break;
+ case chart2::CurveStyle_GNM_STEP_END:
+ nOuterValue = 8;
+ break;
+ case chart2::CurveStyle_GNM_STEP_CENTER_X:
+ nOuterValue = 9;
+ break;
+ case chart2::CurveStyle_GNM_STEP_CENTER_Y:
+ nOuterValue = 10;
+ break;
+ default:
+ nOuterValue = 0;
+ }
return uno::makeAny(nOuterValue);
}
@@ -247,12 +276,42 @@
chart2::CurveStyle aInnerValue;
- if(1==nOuterValue)
- aInnerValue = chart2::CurveStyle_CUBIC_SPLINES;
- else if(2==nOuterValue)
- aInnerValue = chart2::CurveStyle_B_SPLINES;
- else
- aInnerValue = chart2::CurveStyle_LINES;
+ switch (nOuterValue)
+ {
+ case 1:
+ aInnerValue = chart2::CurveStyle_CUBIC_SPLINES;
+ break;
+ case 2:
+ aInnerValue = chart2::CurveStyle_B_SPLINES;
+ break;
+ case 3:
+ aInnerValue = chart2::CurveStyle_STEP_START;
+ break;
+ case 4:
+ aInnerValue = chart2::CurveStyle_STEP_END;
+ break;
+ case 5:
+ aInnerValue = chart2::CurveStyle_STEP_CENTER_X;
+ break;
+ case 6:
+ aInnerValue = chart2::CurveStyle_STEP_CENTER_Y;
+ break;
+ case 7:
+ aInnerValue = chart2::CurveStyle_GNM_STEP_START;
+ break;
+ case 8:
+ aInnerValue = chart2::CurveStyle_GNM_STEP_END;
+ break;
+ case 9:
+ aInnerValue = chart2::CurveStyle_GNM_STEP_CENTER_X;
+ break;
+ case 10:
+ aInnerValue = chart2::CurveStyle_GNM_STEP_CENTER_Y;
+ break;
+ default:
+ // TODO: add an error is nOuterValue != 0 and we're in debugging mode
+ aInnerValue = chart2::CurveStyle_LINES;
+ }
return uno::makeAny(aInnerValue);
}
diff --git a/chart2/source/view/charttypes/AreaChart.cxx b/chart2/source/view/charttypes/AreaChart.cxx
index a9e207c..a1bacc3 100644
--- a/chart2/source/view/charttypes/AreaChart.cxx
+++ b/chart2/source/view/charttypes/AreaChart.cxx
@@ -287,6 +287,140 @@
rPolyPoly=aTmp;
}
+bool AreaChart::create_stepped_line( drawing::PolyPolygonShape3D aStartPoly, chart2::CurveStyle eCurveStyle, PlottingPositionHelper* pPosHelper, drawing::PolyPolygonShape3D &aPoly )
+{
+ drawing::PolyPolygonShape3D aSteppedPoly;
+
+ aSteppedPoly.SequenceX.realloc(0);
+ aSteppedPoly.SequenceY.realloc(0);
+ aSteppedPoly.SequenceZ.realloc(0);
+
+ sal_uInt32 nOuterCount = aStartPoly.SequenceX.getLength();
+ if ( !nOuterCount )
+ return false;
+
+ aSteppedPoly.SequenceX.realloc(nOuterCount);
+ aSteppedPoly.SequenceY.realloc(nOuterCount);
+ aSteppedPoly.SequenceZ.realloc(nOuterCount);
+ for( sal_uInt32 nOuter = 0; nOuter < nOuterCount; ++nOuter )
+ {
+ if( aStartPoly.SequenceX[nOuter].getLength() <= 1 )
+ continue; //we need at least two points
+
+ sal_uInt32 nMaxIndexPoints = aStartPoly.SequenceX[nOuter].getLength()-1; // is >1
+ sal_uInt32 nNewIndexPoints = 0;
+ if ( CurveStyle_STEP_START==eCurveStyle || CurveStyle_STEP_END==eCurveStyle ||
+ CurveStyle_GNM_STEP_START==eCurveStyle || CurveStyle_GNM_STEP_END==eCurveStyle)
+ nNewIndexPoints = nMaxIndexPoints * 2 + 1;
+ else
+ nNewIndexPoints = nMaxIndexPoints * 3 + 1;
+
+ const double* pOldX = aStartPoly.SequenceX[nOuter].getConstArray();
+ const double* pOldY = aStartPoly.SequenceY[nOuter].getConstArray();
+ const double* pOldZ = aStartPoly.SequenceZ[nOuter].getConstArray();
+
+ aSteppedPoly.SequenceX[nOuter].realloc( nNewIndexPoints );
+ aSteppedPoly.SequenceY[nOuter].realloc( nNewIndexPoints );
+ aSteppedPoly.SequenceZ[nOuter].realloc( nNewIndexPoints );
+
+ double* pNewX = aSteppedPoly.SequenceX[nOuter].getArray();
+ double* pNewY = aSteppedPoly.SequenceY[nOuter].getArray();
+ double* pNewZ = aSteppedPoly.SequenceZ[nOuter].getArray();
+
+ pNewX[0] = pOldX[0];
+ pNewY[0] = pOldY[0];
+ pNewZ[0] = pOldZ[0];
+ for( sal_uInt32 oi = 0; oi < nMaxIndexPoints; oi++ )
+ {
+ switch ( eCurveStyle )
+ {
+ case CurveStyle_STEP_START:
+ case CurveStyle_GNM_STEP_START:
+ /** O
+ |
+ |
+ |
+ O-----+
+ */
+ // create the intermediate point
+ pNewX[1+oi*2] = pOldX[oi+1];
+ pNewY[1+oi*2] = pOldY[oi];
+ pNewZ[1+oi*2] = pOldZ[oi];
+ // and now the normal one
+ pNewX[1+oi*2+1] = pOldX[oi+1];
+ pNewY[1+oi*2+1] = pOldY[oi+1];
+ pNewZ[1+oi*2+1] = pOldZ[oi+1];
+ break;
+ case CurveStyle_STEP_END:
+ case CurveStyle_GNM_STEP_END:
+ /** +------O
+ |
+ |
+ |
+ O
+ */
+ // create the intermediate point
+ pNewX[1+oi*2] = pOldX[oi];
+ pNewY[1+oi*2] = pOldY[oi+1];
+ pNewZ[1+oi*2] = pOldZ[oi];
+ // and now the normal one
+ pNewX[1+oi*2+1] = pOldX[oi+1];
+ pNewY[1+oi*2+1] = pOldY[oi+1];
+ pNewZ[1+oi*2+1] = pOldZ[oi+1];
+ break;
+ case CurveStyle_STEP_CENTER_X:
+ case CurveStyle_GNM_STEP_CENTER_X:
+ /** +--O
+ |
+ |
+ |
+ O--+
+ */
+ // create the first intermediate point
+ pNewX[1+oi*3] = (pOldX[oi]+pOldX[oi+1])/2;
+ pNewY[1+oi*3] = pOldY[oi];
+ pNewZ[1+oi*3] = pOldZ[oi];
+ // create the second intermediate point
+ pNewX[1+oi*3+1] = (pOldX[oi]+pOldX[oi+1])/2;
+ pNewY[1+oi*3+1] = pOldY[oi+1];
+ pNewZ[1+oi*3+1] = pOldZ[oi];
+ // and now the normal one
+ pNewX[1+oi*3+2] = pOldX[oi+1];
+ pNewY[1+oi*3+2] = pOldY[oi+1];
+ pNewZ[1+oi*3+2] = pOldZ[oi+1];
+ break;
+ case CurveStyle_STEP_CENTER_Y:
+ case CurveStyle_GNM_STEP_CENTER_Y:
+ /** O
+ |
+ +-----+
+ |
+ O
+ */
+ // create the first intermediate point
+ pNewX[1+oi*3] = pOldX[oi];
+ pNewY[1+oi*3] = (pOldY[oi]+pOldY[oi+1])/2;
+ pNewZ[1+oi*3] = pOldZ[oi];
+ // create the second intermediate point
+ pNewX[1+oi*3+1] = pOldX[oi+1];
+ pNewY[1+oi*3+1] = (pOldY[oi]+pOldY[oi+1])/2;
+ pNewZ[1+oi*3+1] = pOldZ[oi];
+ // and now the normal one
+ pNewX[1+oi*3+2] = pOldX[oi+1];
+ pNewY[1+oi*3+2] = pOldY[oi+1];
+ pNewZ[1+oi*3+2] = pOldZ[oi+1];
+ break;
+ default:
+ // this should never be executed
+ OSL_FAIL("Unknown curvestyle in AreaChart::create_stepped_line");
+ }
+ }
+ }
+ Clipping::clipPolygonAtRectangle( aSteppedPoly, pPosHelper->getScaledLogicClipDoubleRect(), aPoly );
+
+ return true;
+}
+
bool AreaChart::impl_createLine( VDataSeries* pSeries
, drawing::PolyPolygonShape3D* pSeriesPoly
, PlottingPositionHelper* pPosHelper )
@@ -309,8 +443,23 @@
lcl_removeDuplicatePoints( aSplinePoly, *pPosHelper );
Clipping::clipPolygonAtRectangle( aSplinePoly, pPosHelper->getScaledLogicClipDoubleRect(), aPoly );
}
- else
+ else if (CurveStyle_STEP_START==m_eCurveStyle ||
+ CurveStyle_STEP_END==m_eCurveStyle ||
+ CurveStyle_STEP_CENTER_Y==m_eCurveStyle ||
+ CurveStyle_STEP_CENTER_X==m_eCurveStyle ||
+ CurveStyle_GNM_STEP_START==m_eCurveStyle ||
+ CurveStyle_GNM_STEP_END==m_eCurveStyle ||
+ CurveStyle_GNM_STEP_CENTER_Y==m_eCurveStyle ||
+ CurveStyle_GNM_STEP_CENTER_X==m_eCurveStyle)
{
+ if (!create_stepped_line(*pSeriesPoly, m_eCurveStyle, pPosHelper, aPoly))
+ {
+ return false;
+ }
+ }
+ else
+ { // default to creating a straight line
+ // TODO: in debugging mode, print a warning when the linetype is not CurveStyle_LINES
bool bIsClipped = false;
if( m_bConnectLastToFirstPoint && !ShapeFactory::isPolygonEmptyOrSinglePoint(*pSeriesPoly) )
{
diff --git a/chart2/source/view/charttypes/AreaChart.hxx b/chart2/source/view/charttypes/AreaChart.hxx
index cc8b9ae..cb6ea9f 100644
--- a/chart2/source/view/charttypes/AreaChart.hxx
+++ b/chart2/source/view/charttypes/AreaChart.hxx
@@ -80,6 +80,10 @@
bool impl_createLine( VDataSeries* pSeries
, ::com::sun::star::drawing::PolyPolygonShape3D* pSeriesPoly
, PlottingPositionHelper* pPosHelper );
+ bool create_stepped_line( ::com::sun::star::drawing::PolyPolygonShape3D aStartPoly
+ , ::com::sun::star::chart2::CurveStyle eCurveStyle
+ , PlottingPositionHelper* pPosHelper
+ , ::com::sun::star::drawing::PolyPolygonShape3D &aPoly );
private: //member
PlottingPositionHelper* m_pMainPosHelper;
diff --git a/offapi/com/sun/star/chart2/CurveStyle.idl b/offapi/com/sun/star/chart2/CurveStyle.idl
index 3164186..5a6fdac 100644
--- a/offapi/com/sun/star/chart2/CurveStyle.idl
+++ b/offapi/com/sun/star/chart2/CurveStyle.idl
@@ -46,6 +46,55 @@
*/
B_SPLINES,
+ /** Data points are connected via a 2-segmented stepped line.
+ The line starts horizontally.
+ O
+ |
+ |
+ |
+ O-----+
+ */
+ STEP_START,
+
+ /** Data points are connected via a 2-segmented stepped line.
+ The line ends horizontally.
+ +------O
+ |
+ |
+ |
+ O
+ */
+ STEP_END,
+
+ /** Data points are connected via a 3-segmented stepped line.
+ The lines is horizontal till the center of the X values.
+ +--O
+ |
+ |
+ |
+ O--+
+ */
+ STEP_CENTER_X,
+
+ /** Data points are connected via a 3-segmented stepped line.
+ The lines is horizontal at the center of the Y values.
+ O
+ |
+ +-----+
+ |
+ O
+ */
+ STEP_CENTER_Y,
+
+ /** These have the same meaning as above,
+ but are linked to the older Gnumeric attributes before
+ ODF1.3 was approved.
+ */
+ GNM_STEP_START,
+ GNM_STEP_END,
+ GNM_STEP_CENTER_X,
+ GNM_STEP_CENTER_Y,
+
/**
*/
NURBS
diff --git a/xmloff/inc/xmloff/xmltoken.hxx b/xmloff/inc/xmloff/xmltoken.hxx
index e7e886e..96025e4 100644
--- a/xmloff/inc/xmloff/xmltoken.hxx
+++ b/xmloff/inc/xmloff/xmltoken.hxx
@@ -2555,6 +2555,14 @@
XML_INTERPOLATION,
XML_CUBIC_SPLINE,
XML_B_SPLINE,
+ XML_STEP_START,
+ XML_STEP_END,
+ XML_STEP_CENTER_X,
+ XML_STEP_CENTER_Y,
+ XML_GNM_STEP_START,
+ XML_GNM_STEP_END,
+ XML_GNM_STEP_CENTER_X,
+ XML_GNM_STEP_CENTER_Y,
XML_N_DB_OASIS,
XML_SHOW_FILTER_BUTTON,
diff --git a/xmloff/source/chart/PropertyMap.hxx b/xmloff/source/chart/PropertyMap.hxx
index e8298a6..d455a4a 100644
--- a/xmloff/source/chart/PropertyMap.hxx
+++ b/xmloff/source/chart/PropertyMap.hxx
@@ -290,10 +290,18 @@
{
// this is neither an enum nor a constants group, but just a
// documented long property
- { ::xmloff::token::XML_NONE, 0 },
- { ::xmloff::token::XML_CUBIC_SPLINE, 1 },
- { ::xmloff::token::XML_B_SPLINE, 2 },
- { ::xmloff::token::XML_TOKEN_INVALID,0 }
+ { ::xmloff::token::XML_NONE, 0 },
+ { ::xmloff::token::XML_CUBIC_SPLINE, 1 },
+ { ::xmloff::token::XML_B_SPLINE, 2 },
+ { ::xmloff::token::XML_STEP_START, 3 },
+ { ::xmloff::token::XML_STEP_END, 4 },
+ { ::xmloff::token::XML_STEP_CENTER_X, 5 },
+ { ::xmloff::token::XML_STEP_CENTER_Y, 6 },
+ { ::xmloff::token::XML_GNM_STEP_START, 7 },
+ { ::xmloff::token::XML_GNM_STEP_END, 8 },
+ { ::xmloff::token::XML_GNM_STEP_CENTER_X, 9 },
+ { ::xmloff::token::XML_GNM_STEP_CENTER_Y, 10 },
+ { ::xmloff::token::XML_TOKEN_INVALID, 0 }
};
SvXMLEnumMapEntry aXMLChartDataLabelPlacementEnumMap[] =
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index afd52ba..c2d94d4 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -2556,6 +2556,15 @@
TOKEN( "interpolation", XML_INTERPOLATION ),
TOKEN( "cubic-spline", XML_CUBIC_SPLINE ),
TOKEN( "b-spline", XML_B_SPLINE ),
+ TOKEN( "step-start", XML_STEP_START ),
+ TOKEN( "step-end", XML_STEP_END ),
+ TOKEN( "step-center-x", XML_STEP_CENTER_X ),
+ TOKEN( "step-center-y", XML_STEP_CENTER_Y ),
+ // also understand the older Gnumeric tookens
+ TOKEN( "gnm:step-start", XML_GNM_STEP_START ),
+ TOKEN( "gnm:step-end", XML_GNM_STEP_END ),
+ TOKEN( "gnm:step-center-x", XML_GNM_STEP_CENTER_X ),
+ TOKEN( "gnm:step-center-y", XML_GNM_STEP_CENTER_Y ),
TOKEN( "urn:oasis:names:tc:opendocument:xmlns:database:1.0", XML_N_DB_OASIS ),
TOKEN( "show-filter-button", XML_SHOW_FILTER_BUTTON ),
diff --git a/xmloff/source/transform/StyleOASISTContext.cxx b/xmloff/source/transform/StyleOASISTContext.cxx
index 6f7caf7..f5fc845 100644
--- a/xmloff/source/transform/StyleOASISTContext.cxx
+++ b/xmloff/source/transform/StyleOASISTContext.cxx
@@ -315,18 +315,26 @@
break;
case XML_OPTACTION_INTERPOLATION:
{
- // 0: none
- sal_Int32 nSplineType = 0;
+ // 0: none (default)
+ sal_Int32 nLineType = 0;
if( IsXMLToken( rAttrValue, XML_CUBIC_SPLINE ))
- nSplineType = 1;
+ nLineType = 1;
else if( IsXMLToken( rAttrValue, XML_B_SPLINE ))
- nSplineType = 2;
+ nLineType = 2;
+ else if( IsXMLToken( rAttrValue, XML_STEP_START ) || IsXMLToken( rAttrValue, XML_GNM_STEP_START ) )
+ nLineType = 3;
+ else if( IsXMLToken( rAttrValue, XML_STEP_END ) || IsXMLToken( rAttrValue, XML_GNM_STEP_END ) )
+ nLineType = 4;
+ else if( IsXMLToken( rAttrValue, XML_STEP_CENTER_X ) || IsXMLToken( rAttrValue, XML_GNM_STEP_CENTER_X ) )
+ nLineType = 5;
+ else if( IsXMLToken( rAttrValue, XML_STEP_CENTER_Y ) || IsXMLToken( rAttrValue, XML_GNM_STEP_CENTER_Y ) )
+ nLineType = 6;
pAttrList->AddAttribute(
GetTransformer().GetNamespaceMap().GetQNameByKey(
XML_NAMESPACE_CHART,
GetXMLToken( XML_SPLINES )),
- OUString::valueOf( nSplineType ));
+ OUString::valueOf( nLineType ));
}
break;
case XML_OPTACTION_INTERVAL_MAJOR:
--
To view, visit https://gerrit.libreoffice.org/2476
To unsubscribe, visit https://gerrit.libreoffice.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0f04a779de4b65326ed7ce6de56191f11b51c596
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: master
Gerrit-Owner: Eric Seynaeve <github at nosperse.com>
More information about the LibreOffice
mailing list