fpspreadsheet: xlsx chart reader supports error bars.
git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@9136 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
parent
988772c25a
commit
168a151e65
@ -404,6 +404,7 @@ type
|
||||
FRange: Array[0..1] of TsChartRange;
|
||||
FValue: Array[0..1] of Double; // 0 = positive, 1 = negative error bar value
|
||||
FShow: Array[0..1] of Boolean;
|
||||
FShowEndCap: Boolean;
|
||||
function GetRange(AIndex: Integer): TsChartRange;
|
||||
function GetShow(AIndex: Integer): Boolean;
|
||||
function GetValue(AIndex: Integer): Double;
|
||||
@ -430,6 +431,7 @@ type
|
||||
property RangePos: TsChartRange index 0 read GetRange write SetRange;
|
||||
property RangeNeg: TsChartRange index 1 read GetRange write SetRange;
|
||||
property Series: TsChartSeries read FSeries;
|
||||
property ShowEndCap: Boolean read FShowEndCap write FShowEndCap;
|
||||
property ShowPos: Boolean index 0 read GetShow write SetShow;
|
||||
property ShowNeg: Boolean index 1 read GetShow write SetShow;
|
||||
property ValuePos: Double index 0 read GetValue write SetValue;
|
||||
@ -1602,6 +1604,7 @@ begin
|
||||
FRange[1] := TsChartRange.Create(ASeries.Chart);
|
||||
FShow[0] := false;
|
||||
FShow[1] := false;
|
||||
FShowEndCap := true;
|
||||
end;
|
||||
|
||||
destructor TsChartErrorBars.Destroy;
|
||||
@ -1622,6 +1625,7 @@ begin
|
||||
FRange[1].CopyFrom(TsChartErrorBars(ASource).RangeNeg);
|
||||
FShow[0] := TsChartErrorBars(ASource).ShowPos;
|
||||
FShow[1] := TsChartErrorBars(ASource).ShowNeg;
|
||||
FShowEndCap := TsChartErrorBars(ASource).ShowEndCap;
|
||||
FValue[0] := TsChartErrorBars(ASource).ValuePos;
|
||||
FValue[1] := TsChartErrorBars(ASource).ValueNeg;
|
||||
FLine.CopyFrom(TsChartErrorBars(ASource).Line);
|
||||
|
||||
@ -39,6 +39,7 @@ type
|
||||
procedure ReadChartLineSeries(ANode: TDOMNode; AChart: TsChart);
|
||||
procedure ReadChartPlotArea(ANode: TDOMNode; AChart: TsChart);
|
||||
procedure ReadChartScatterSeries(ANode: TDOMNode; AChart: TsChart);
|
||||
procedure ReadChartSeriesErrorBars(ANode: TDOMNode; ASeries: TsChartSeries);
|
||||
procedure ReadChartSeriesLabels(ANode: TDOMNode; ASeries: TsChartSeries);
|
||||
procedure ReadChartSeriesMarker(ANode: TDOMNode; ASeries: TsCustomLineSeries);
|
||||
procedure ReadChartSeriesProps(ANode: TDOMNode; ASeries: TsChartSeries);
|
||||
@ -725,10 +726,10 @@ begin
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads the properties of a line series
|
||||
Reads the properties of the series marker
|
||||
|
||||
@@param ANode Points to the <c:marker> subnode of <c:ser> node
|
||||
@@param ASeries Instance of the TsLineSeries created by ReadChartLineSeries
|
||||
@@param ASeries Instance of the TsCustomLineSeries created by ReadChartLineSeries
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadOOXMLChartReader.ReadChartSeriesMarker(ANode: TDOMNode; ASeries: TsCustomLineSeries);
|
||||
var
|
||||
@ -854,6 +855,96 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads the error bar parameters of a series.
|
||||
|
||||
@@param ANode Is the first child of the <c:errBars> subnode of <c:ser>.
|
||||
@@param ASeries Series to which the error bars belong.
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadOOXMLChartReader.ReadChartSeriesErrorBars(ANode: TDOMNode;
|
||||
ASeries: TsChartSeries);
|
||||
var
|
||||
nodeName, s: String;
|
||||
node: TDOMNode;
|
||||
val: Double;
|
||||
errorBars: TsChartErrorBars = nil;
|
||||
part: String = '';
|
||||
begin
|
||||
if ANode = nil then
|
||||
exit;
|
||||
|
||||
// We must first find out whether the node is for x or y error bars and
|
||||
// whether it is for positive, negative or both error parts.
|
||||
node := ANode;
|
||||
while Assigned(node) do
|
||||
begin
|
||||
nodeName := node.NodeName;
|
||||
s := GetAttrValue(node, 'val');
|
||||
case nodeName of
|
||||
'c:errDir':
|
||||
begin
|
||||
case s of
|
||||
'x': errorBars := ASeries.XErrorBars;
|
||||
'y': errorBars := ASeries.YErrorBars;
|
||||
end;
|
||||
end;
|
||||
'c:errBarType':
|
||||
part := s;
|
||||
end;
|
||||
if (errorBars <> nil) and (part <> '') then
|
||||
break;
|
||||
node := node.NextSibling;
|
||||
end;
|
||||
|
||||
errorBars.ShowPos := (part = 'both') or (part = 'plus');
|
||||
errorBars.ShowNeg := (part = 'both') or (part = 'minus');
|
||||
|
||||
node := ANode;
|
||||
while Assigned(node) do
|
||||
begin
|
||||
nodeName := node.NodeName;
|
||||
s := GetAttrValue(node, 'val');
|
||||
case nodeName of
|
||||
'c:errValType':
|
||||
case s of
|
||||
'fixedVal': errorBars.Kind := cebkConstant;
|
||||
'percentage': errorBars.Kind := cebkPercentage;
|
||||
'cust': errorBars.Kind := cebkCellRange;
|
||||
'stdDev': errorBars.Visible := false; // not supported
|
||||
'stdErr': errorBars.Visible := false; // not supported
|
||||
end;
|
||||
'c:val':
|
||||
if (s <> '') and TryStrToFloat(s, val, FPointSeparatorSettings) then
|
||||
case part of
|
||||
'both':
|
||||
begin
|
||||
errorBars.ValuePos := val;
|
||||
errorBars.ValueNeg := val;
|
||||
end;
|
||||
'plus':
|
||||
errorBars.ValuePos := val;
|
||||
'minus':
|
||||
errorBars.ValueNeg := val;
|
||||
end;
|
||||
'c:plus':
|
||||
ReadChartSeriesRange(node.FirstChild, errorBars.RangePos);
|
||||
'c:minus':
|
||||
ReadChartSeriesRange(node.FirstChild, errorBars.RangeNeg);
|
||||
'c:spPr':
|
||||
ReadChartLineProps(node.FirstChild, ASeries.Chart, errorBars.Line);
|
||||
'c:noEndCap':
|
||||
errorBars.ShowEndCap := (s <> '1');
|
||||
end;
|
||||
node := node.NextSibling;
|
||||
end;
|
||||
end;
|
||||
|
||||
{@@ ----------------------------------------------------------------------------
|
||||
Reads the labels assigned to the series data points.
|
||||
|
||||
@@param ANode Is the first child of the <c:dLbls> subnode of <c:ser>.
|
||||
@@param ASeries Series to which the labels belong.
|
||||
-------------------------------------------------------------------------------}
|
||||
procedure TsSpreadOOXMLChartReader.ReadChartSeriesLabels(ANode: TDOMNode;
|
||||
ASeries: TsChartSeries);
|
||||
var
|
||||
@ -865,6 +956,7 @@ begin
|
||||
while Assigned(ANode) do
|
||||
begin
|
||||
nodeName := ANode.NodeName;
|
||||
s := GetAttrValue(ANode, 'val');
|
||||
case nodeName of
|
||||
'c:spPr':
|
||||
ReadChartFillAndLineProps(ANode.FirstChild, ASeries.Chart, ASeries.LabelBackground, ASeries.LabelBorder);
|
||||
@ -888,35 +980,20 @@ begin
|
||||
end;
|
||||
end;
|
||||
'c:showLegendKey':
|
||||
begin
|
||||
s := GetAttrValue(ANode, 'val');
|
||||
if (s <> '') and (s <> '0') then
|
||||
ASeries.DataLabels := ASeries.DataLabels + [cdlSymbol];
|
||||
end;
|
||||
if (s <> '') and (s <> '0') then
|
||||
ASeries.DataLabels := ASeries.DataLabels + [cdlSymbol];
|
||||
'c:showVal':
|
||||
begin
|
||||
s := GetAttrValue(ANode, 'val');
|
||||
if (s <> '') and (s <> '0') then
|
||||
ASeries.DataLabels := ASeries.DataLabels + [cdlValue];
|
||||
end;
|
||||
if (s <> '') and (s <> '0') then
|
||||
ASeries.DataLabels := ASeries.DataLabels + [cdlValue];
|
||||
'c:showCatName':
|
||||
begin
|
||||
s := GetAttrValue(ANode, 'val');
|
||||
if (s <> '') and (s <> '0') then
|
||||
ASeries.DataLabels := ASeries.DataLabels + [cdlCategory];
|
||||
end;
|
||||
if (s <> '') and (s <> '0') then
|
||||
ASeries.DataLabels := ASeries.DataLabels + [cdlCategory];
|
||||
'c:showSerName':
|
||||
begin
|
||||
s := GetAttrValue(ANode, 'val');
|
||||
if (s <> '') and (s <> '0') then
|
||||
ASeries.DataLabels := ASeries.DataLabels + [cdlSeriesName];
|
||||
end;
|
||||
if (s <> '') and (s <> '0') then
|
||||
ASeries.DataLabels := ASeries.DataLabels + [cdlSeriesName];
|
||||
'c:showPercent':
|
||||
begin
|
||||
s := GetAttrValue(ANode, 'val');
|
||||
if (s <> '') and (s <> '0') then
|
||||
ASeries.DataLabels := ASeries.DataLabels + [cdlPercentage];
|
||||
end;
|
||||
if (s <> '') and (s <> '0') then
|
||||
ASeries.DataLabels := ASeries.DataLabels + [cdlPercentage];
|
||||
'c:showBubbleSize':
|
||||
;
|
||||
'c:showLeaderLines':
|
||||
@ -954,6 +1031,8 @@ begin
|
||||
ReadChartSeriesLabels(ANode.Firstchild, ASeries);
|
||||
'c:trendline':
|
||||
ReadChartSeriesTrendLine(ANode.FirstChild, ASeries);
|
||||
'c:errBars':
|
||||
ReadChartSeriesErrorBars(ANode.FirstChild, ASeries);
|
||||
'c:invertIfNegative':
|
||||
;
|
||||
'c:extLst':
|
||||
|
||||
@ -2112,6 +2112,7 @@ end;
|
||||
procedure TsWorkbookChartLink.UpdateChartErrorBars(AWorkbookSeries: TsChartSeries;
|
||||
ASeries: TBasicPointSeries);
|
||||
const
|
||||
EPS = 1E-16;
|
||||
ERRORBAR_KINDS: array[TsChartErrorBarKind] of TChartErrorBarKind = (
|
||||
ebkConst, ebkPercent, ebkChartSource);
|
||||
|
||||
@ -2137,13 +2138,19 @@ begin
|
||||
// TAChart supports error bars only for single-values sources!
|
||||
if source.XCount = 1 then
|
||||
begin
|
||||
series.XErrorBars.Visible := AWorkbookSeries.XErrorBars.ShowPos or AWorkbookSeries.XErrorBars.ShowNeg;;
|
||||
series.XErrorBars.Visible := AWorkbookSeries.XErrorBars.ShowPos or AWorkbookSeries.XErrorBars.ShowNeg;
|
||||
UpdateChartPen(AWorkbookSeries.Chart, AWorkbookSeries.XErrorBars.Line, series.XErrorBars.Pen);
|
||||
source.XErrorBarData.Kind := ERRORBAR_KINDS[AWorkbookSeries.XErrorBars.Kind];
|
||||
source.XErrorBarData.ValuePlus := AWorkbookSeries.XErrorBars.ValuePos;
|
||||
source.XErrorBarData.ValueMinus := AWorkbookSeries.XErrorBars.ValueNeg;
|
||||
if not AWorkbookSeries.XErrorBars.ShowPos then
|
||||
source.XErrorBarData.ValuePlus := EPS; // Note: 0 would mean "no error bar at all" for TAChart!
|
||||
if not AWorkbookSeries.XErrorBars.ShowNeg then
|
||||
source.XErrorBarData.ValueMinus := EPS;
|
||||
if (AWorkbookSeries.XErrorBars.Kind = cebkCellRange) then
|
||||
source.SetXErrorBarRange(AWorkbookSeries.XErrorBars.RangePos, AWorkbookSeries.XErrorBars.RangeNeg);
|
||||
if not AWorkbookSeries.XErrorBars.ShowEndCap then
|
||||
series.XErrorBars.Width := 0;
|
||||
end;
|
||||
|
||||
if source.YCount = 1 then
|
||||
@ -2153,8 +2160,14 @@ begin
|
||||
source.YErrorBarData.Kind := ERRORBAR_KINDS[AWorkbookSeries.YErrorBars.Kind];
|
||||
source.YErrorBarData.ValuePlus := AWorkbookSeries.YErrorBars.ValuePos;
|
||||
source.YErrorBarData.ValueMinus := AWorkbookSeries.YErrorBars.ValueNeg;
|
||||
if not AWorkbookSeries.YErrorBars.ShowPos then
|
||||
source.YErrorBarData.ValuePlus := EPS;
|
||||
if not AWorkbookSeries.YErrorBars.ShowNeg then
|
||||
source.YErrorBarData.ValueMinus := EPS;
|
||||
if (AWorkbookSeries.YErrorBars.Kind = cebkCellRange) then
|
||||
source.SetYErrorBarRange(AWorkbookSeries.YErrorBars.RangePos, AWorkbookSeries.YErrorBars.RangeNeg);
|
||||
if not AWorkbookSeries.YErrorBars.ShowEndCap then
|
||||
series.YErrorBars.Width := 0;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user