diff --git a/components/tachart/editors/tadatapointseditor.lfm b/components/tachart/editors/tadatapointseditor.lfm index ceb1e09718..a870f95698 100644 --- a/components/tachart/editors/tadatapointseditor.lfm +++ b/components/tachart/editors/tadatapointseditor.lfm @@ -2,48 +2,50 @@ object DataPointsEditorForm: TDataPointsEditorForm Left = 418 Height = 303 Top = 235 - Width = 357 + Width = 288 ClientHeight = 303 - ClientWidth = 357 + ClientWidth = 288 OnCreate = FormCreate - LCLVersion = '1.7' + Position = poScreenCenter + ShowHint = True + LCLVersion = '2.1.0.0' object sgData: TStringGrid - Left = 0 - Height = 257 - Top = 0 - Width = 357 + Left = 6 + Height = 251 + Top = 6 + Width = 276 Align = alClient - AutoFillColumns = True + BorderSpacing.Around = 6 Columns = < item Alignment = taRightJustify Title.Alignment = taCenter Title.Font.Style = [fsBold] Title.Caption = 'X' - Width = 80 + Width = 63 end item Alignment = taRightJustify Title.Alignment = taCenter Title.Font.Style = [fsBold] Title.Caption = 'Y' - Width = 80 + Width = 63 end item ButtonStyle = cbsEllipsis Title.Alignment = taCenter Title.Font.Style = [fsBold] Title.Caption = 'Color' - Width = 80 + Width = 63 end item Title.Alignment = taCenter Title.Font.Style = [fsBold] Title.Caption = 'Text' - Width = 81 + Width = 63 end> DefaultColWidth = 32 - Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goColSizing, goRowMoving, goEditing, goAutoAddRows, goAlwaysShowEditor, goSmoothScroll, goFixedRowNumbering] + Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goColSizing, goRowMoving, goEditing, goAutoAddRows, goAlwaysShowEditor, goSmoothScroll, goFixedRowNumbering, goTruncCellHints, goCellEllipsis] PopupMenu = pmRows TabOrder = 0 OnDrawCell = sgDataDrawCell @@ -51,17 +53,17 @@ object DataPointsEditorForm: TDataPointsEditorForm OnPrepareCanvas = sgDataPrepareCanvas ColWidths = ( 32 - 80 - 80 - 80 - 81 + 63 + 63 + 63 + 63 ) end object ButtonPanel1: TButtonPanel Left = 6 Height = 34 Top = 263 - Width = 345 + Width = 276 OKButton.Name = 'OKButton' OKButton.DefaultCaption = True HelpButton.Name = 'HelpButton' diff --git a/components/tachart/editors/tadatapointseditor.pas b/components/tachart/editors/tadatapointseditor.pas index bab1b510b9..6420814580 100644 --- a/components/tachart/editors/tadatapointseditor.pas +++ b/components/tachart/editors/tadatapointseditor.pas @@ -41,9 +41,10 @@ type strict private FCurrentRow: Integer; FDataPoints: TStrings; + FXCount: Integer; FYCount: Integer; public - procedure InitData(AYCount: Integer; ADataPoints: TStrings); + procedure InitData(AXCount, AYCount: Integer; ADataPoints: TStrings); procedure ExtractData(out AModified: Boolean); end; @@ -52,7 +53,7 @@ procedure Register; implementation uses - LCLIntf, Math, PropEdits, + LCLIntf, LCLType, Math, PropEdits, TAChartStrConsts, TAChartUtils, TASources; {$R *.lfm} @@ -100,26 +101,47 @@ begin end; procedure TDataPointsEditorForm.InitData( - AYCount: Integer; ADataPoints: TStrings); + AXCount, AYCount: Integer; ADataPoints: TStrings); var i: Integer; + w: Integer; begin + FXCount := AXCount; FYCount := AYCount; FDataPoints := ADataPoints; sgData.RowCount := Max(ADataPoints.Count + 1, 2); + { wp: What is this good for? for i := sgData.Columns.Count - 1 downto 0 do with sgData.Columns[i].Title do if (Caption[1] = 'Y') and (Caption <> 'Y') then sgData.Columns.Delete(i); - for i := 2 to AYCount do begin + } + if AXCount > 1 then + sgData.Columns[0].Title.Caption := 'X1'; + if AYCount > 1 then + sgData.Columns[1].Title.Caption := 'Y1'; + for i := 2 to AYCount do with sgData.Columns.Add do begin Assign(sgData.Columns[1]); Title.Caption := 'Y' + IntToStr(i); Index := i; end; - end; + for i := 2 to AXCount do + with sgData.Columns.Add do begin + Assign(sgData.Columns[0]); + Title.Caption := 'X' + IntToStr(i); + Index := i - 1; + end; for i := 0 to ADataPoints.Count - 1 do - Split('|' + ADataPoints[i], sgData.Rows[i + 1]) + Split('|' + ADataPoints[i], sgData.Rows[i + 1]); + + // Adjust column widths + w := sgData.Canvas.TextWidth('$000000') + 3*varCellPadding + sgData.DefaultRowHeight; + for i := 0 to sgData.Columns.Count-1 do + sgData.Columns[i].Width := w; + + Width := sgData.ColWidths[0] + sgData.Columns.Count * w + 2*sgData.Left + + sgData.GridLineWidth * (sgData.Columns.Count-1); end; procedure TDataPointsEditorForm.miDeleteRowClick(Sender: TObject); @@ -158,7 +180,7 @@ procedure TDataPointsEditorForm.sgDataButtonClick( ASender: TObject; ACol, ARow: Integer); begin Unused(ASender); - if (ARow < 1) or (ACol <> FYCount + 2) then exit; + if (ARow < 1) or (ACol <> FXCount + FYCount + 1) then exit; cdItemColor.Color := StrToIntDef(sgData.Cells[ACol, ARow], clRed); if not cdItemColor.Execute then exit; sgData.Cells[ACol, ARow] := IntToColorHex(cdItemColor.Color); @@ -170,12 +192,12 @@ var c: Integer; begin Unused(ASender, AState); - if (ARow < 1) or (ACol <> FYCount + 2) then exit; + if (ARow < 1) or (ACol <> FXCount + FYCount + 1) then exit; if not TryStrToInt(sgData.Cells[ACol, ARow], c) then exit; sgData.Canvas.Pen.Color := clBlack; sgData.Canvas.Brush.Color := c; - InflateRect(ARect, -2, -2); - ARect.Left := ARect.Right - 12; + InflateRect(ARect, -varCellPadding, -varCellPadding); + ARect.Left := ARect.Right - (ARect.Bottom - ARect.Top);; sgData.Canvas.Rectangle(ARect); end; @@ -201,8 +223,10 @@ begin with TDataPointsEditorForm.Create(nil) do try InitData( + (GetComponent(0) as TListChartsource).XCount, (GetComponent(0) as TListChartSource).YCount, - GetObjectValue as TStrings); + GetObjectValue as TStrings + ); if ShowModal = mrOK then begin ExtractData(dataModified); if dataModified then Modified; diff --git a/components/tachart/tadrawercanvas.pas b/components/tachart/tadrawercanvas.pas index 9c4e45a1ec..91432dad4a 100644 --- a/components/tachart/tadrawercanvas.pas +++ b/components/tachart/tadrawercanvas.pas @@ -93,7 +93,7 @@ type implementation uses - GraphType, Math, LCLIntf, LCLType, IntfGraphics, + GraphType, LCLIntf, LCLType, IntfGraphics, TAGeometry; function CanvasGetFontOrientationFunc(AFont: TFPCustomFont): Integer; diff --git a/components/tachart/tamultiseries.pas b/components/tachart/tamultiseries.pas index fe13459df3..47daffc235 100644 --- a/components/tachart/tamultiseries.pas +++ b/components/tachart/tamultiseries.pas @@ -1620,28 +1620,28 @@ begin if not RectIntersectsRect(ext, ParentChart.CurrentExtent) then exit; lPen := TPen.Create; - lPen.Assign(FPen); - - if (AxisIndexX < 0) and (AxisIndexY < 0) then begin - // Optimization: bypass transformations in the default case - for i := 0 to Count - 1 do - if GetVectorPoints(i, p1, p2) then begin - lPen.Color := GetColor(i); - DrawVector(ADrawer, p1, p2, lPen); - end; - end else begin - for i := 0 to Count - 1 do - if GetVectorPoints(i, p1, p2) then begin - p1 := AxisToGraph(p1); - p2 := AxisToGraph(p2); - //p1 := DoublePoint(AxisToGraphX(p1.X), AxisToGraphY(p1.Y)); - //p2 := DoublePoint(AxisToGraphX(p2.X), AxisToGraphY(p2.Y)); - lPen.Color := GetColor(i); - DrawVector(ADrawer, p1, p2, lPen); - end; + try + lPen.Assign(FPen); + if (AxisIndexX < 0) and (AxisIndexY < 0) then begin + // Optimization: bypass transformations in the default case + for i := 0 to Count - 1 do + if GetVectorPoints(i, p1, p2) then begin + lPen.Color := GetColor(i); + DrawVector(ADrawer, p1, p2, lPen); + end; + end else begin + for i := 0 to Count - 1 do + if GetVectorPoints(i, p1, p2) then begin + p1 := AxisToGraph(p1); + p2 := AxisToGraph(p2); + lPen.Color := GetColor(i); + DrawVector(ADrawer, p1, p2, lPen); + end; + end; + DrawLabels(ADrawer); + finally + lPen.Free; end; - - lPen.Free; end; procedure TFieldSeries.DrawVector(ADrawer: IChartDrawer; diff --git a/components/tachart/taseries.pas b/components/tachart/taseries.pas index 2e717635d6..750bc4510b 100644 --- a/components/tachart/taseries.pas +++ b/components/tachart/taseries.pas @@ -1671,7 +1671,7 @@ var procedure CollectPoints(AStart, AEnd: Integer); var - i, j: Integer; + i: Integer; a, b: TDoublePoint; singlePoint: Boolean; begin diff --git a/components/tachart/tasources.pas b/components/tachart/tasources.pas index d9de974206..dfd0be99a4 100644 --- a/components/tachart/tasources.pas +++ b/components/tachart/tasources.pas @@ -41,6 +41,7 @@ type procedure SetYCount(AValue: Cardinal); override; public type + EXListEmptyError = class(EChartError); EYListEmptyError = class(EChartError); public constructor Create(AOwner: TComponent); override; @@ -49,6 +50,8 @@ type function Add( AX, AY: Double; const ALabel: String = ''; AColor: TChartColor = clTAColor): Integer; + function AddXListYList(const AX, AY: array of Double; ALabel: String = ''; + AColor: TChartColor = clTAColor): Integer; function AddXYList( AX: Double; const AY: array of Double; const ALabel: String = ''; AColor: TChartColor = clTAColor): Integer; @@ -68,6 +71,7 @@ type published property DataPoints: TStrings read FDataPoints write SetDataPoints; property Sorted: Boolean read FSorted write SetSorted default false; + property XCount; property XErrorBarData; property YErrorBarData; property YCount; @@ -301,6 +305,8 @@ begin fs.DecimalSeparator := '.'; with FSource[Index]^ do begin Result := Format('%g', [X], fs); + for i := 0 to High(XList) do + Result += Format('|%g', [XList[i]], fs); if FSource.YCount > 0 then Result += Format('|%g', [Y], fs); for i := 0 to High(YList) do @@ -344,10 +350,13 @@ var begin parts := Split(AString); try - if FSource.YCount + 3 < Cardinal(parts.Count) then + if (FSource.XCount = 1) and (FSource.YCount + 3 < Cardinal(parts.Count)) then FSource.YCount := parts.Count - 3; with ADataItem^ do begin X := StrToFloatOrDateTimeDef(NextPart); + if FSource.XCount > 1 then + for i := 0 to High(XList) do + XList[i] := StrToFloatOrDateTimeDef(NextPart); if FSource.YCount > 0 then begin Y := StrToFloatOrDateTimeDef(NextPart); for i := 0 to High(YList) do @@ -365,7 +374,7 @@ procedure TListChartSourceStrings.Put(Index: Integer; const S: String); begin FSource.BeginUpdate; try - Parse(S, FSource[Index]); + Parse(S, FSource[Index]); finally FSource.EndUpdate; end; @@ -410,6 +419,20 @@ begin UpdateCachesAfterAdd(AX, AY); end; +function TListChartSource.AddXListYList(const AX, AY: array of Double; + ALabel: String = ''; AColor: TChartColor = clTAColor): Integer; +begin + if Length(AX) = 0 then + raise EXListEmptyError.Create('AddXListYList: XList is empty'); + if Length(AY) = 0 then + raise EYListEmptyError.Create('AddXListYList: YList is empty'); + Result := Add(AX[0], AY[0], ALabel, AColor); + if Length(AX) > 1 then + SetXList(Result, AX[1..High(AX)]); + if Length(AY) > 1 then + SetYList(Result, AY[1..High(AY)]); +end; + function TListChartSource.AddXYList( AX: Double; const AY: array of Double; const ALabel: String; AColor: TChartColor): Integer;