TAChart: Add new demo "datapointtools"

git-svn-id: trunk@54311 -
This commit is contained in:
wp 2017-02-28 21:43:21 +00:00
parent c45e27567f
commit d3e72e4492
5 changed files with 772 additions and 0 deletions

4
.gitattributes vendored
View File

@ -4184,6 +4184,10 @@ components/tachart/demo/combobox/combodemo.lpi svneol=native#text/plain
components/tachart/demo/combobox/combodemo.lpr svneol=native#text/plain
components/tachart/demo/combobox/main.lfm svneol=native#text/plain
components/tachart/demo/combobox/main.pas svneol=native#text/plain
components/tachart/demo/datapointtools/datapointtooldemo.lpi svneol=native#text/plain
components/tachart/demo/datapointtools/datapointtooldemo.lpr svneol=native#text/plain
components/tachart/demo/datapointtools/main.lfm svneol=native#text/plain
components/tachart/demo/datapointtools/main.pas svneol=native#text/plain
components/tachart/demo/db/dbdemo.lpi svneol=native#text/plain
components/tachart/demo/db/dbdemo.lpr svneol=native#text/pascal
components/tachart/demo/db/main.lfm svneol=native#text/plain

View File

@ -0,0 +1,81 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="10"/>
<PathDelim Value="\"/>
<General>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="datapointtooldemo"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<Icon Value="0"/>
</General>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<RequiredPackages Count="2">
<Item1>
<PackageName Value="TAChartLazarusPkg"/>
</Item1>
<Item2>
<PackageName Value="LCL"/>
</Item2>
</RequiredPackages>
<Units Count="2">
<Unit0>
<Filename Value="datapointtooldemo.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="main.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="MainForm"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="datapointtooldemo"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Linking>
<Debugging>
<UseExternalDbgSyms Value="True"/>
</Debugging>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

View File

@ -0,0 +1,21 @@
program datapointtooldemo;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, main, tachartlazaruspkg
{ you can add units after this };
{$R *.res}
begin
RequireDerivedFormResource := True;
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.

View File

@ -0,0 +1,335 @@
object MainForm: TMainForm
Left = 280
Height = 488
Top = 130
Width = 637
Caption = 'Datapoint Tools Demo'
ClientHeight = 488
ClientWidth = 637
OnCreate = FormCreate
LCLVersion = '1.7'
object TabControl: TTabControl
Left = 0
Height = 347
Top = 0
Width = 637
MultiLine = True
OnChange = TabControlChange
TabIndex = 9
Tabs.Strings = (
'Line series'
'Bar series'
'Area series'
'Polar series'
'Cubic spline series'
'BSpline series'
'Fit series'
'Open-High-Low-Close series'
'Box-Whisker series'
'Bubble series'
'Field series'
'Function series'
'Constant line'
)
Align = alClient
TabOrder = 0
object Chart: TChart
Left = 2
Height = 302
Top = 43
Width = 633
AutoFocus = True
AxisList = <
item
Minors = <>
Range.Max = 10
Range.UseMax = True
Range.UseMin = True
Title.LabelFont.Orientation = 900
end
item
Intervals.MaxLength = 80
Intervals.MinLength = 30
Alignment = calBottom
Minors = <>
end>
Foot.Brush.Color = clBtnFace
Foot.Font.Color = clBlue
Legend.Visible = True
Title.Brush.Color = clBtnFace
Title.Brush.Style = bsClear
Title.Font.Color = clBlue
Title.Text.Strings = (
'Datapoint tools demo'
)
Title.Visible = True
Toolset = Toolset
Align = alClient
Color = clDefault
object LineSeries: TLineSeries
Legend.Multiplicity = lmStyle
Active = False
Title = 'Line series'
Pointer.Style = psCircle
ShowPoints = True
Stacked = True
Source = ListChartSource
Styles = ChartStyles
end
object BarSeries: TBarSeries
Legend.Multiplicity = lmStyle
Active = False
Title = 'Bar series'
BarBrush.Color = clRed
BarWidthStyle = bwPercentMin
Source = ListChartSource
Styles = ChartStyles
end
object AreaSeries: TAreaSeries
Legend.Multiplicity = lmStyle
Active = False
Title = 'Area series'
AreaLinesPen.Style = psClear
Source = ListChartSource
Styles = ChartStyles
end
object PolarSeries: TPolarSeries
Active = False
Title = 'Polar series'
LinePen.Color = clRed
Pointer.HorizSize = 5
Pointer.Style = psDiamond
Pointer.VertSize = 5
ShowPoints = True
Source = ListChartSource
end
object CubicSplineSeries: TCubicSplineSeries
Active = False
Title = 'Cubic spline series'
Pointer.Brush.Color = clRed
Pointer.HorizSize = 6
Pointer.Style = psFullStar
Pointer.VertSize = 6
Source = ListChartSource
Pen.Color = clRed
end
object BSplineSeries: TBSplineSeries
Active = False
Title = 'BSpline series'
Source = ListChartSource
Pen.Color = clGreen
Pointer.Brush.Color = clGreen
Pointer.HorizSize = 7
Pointer.Style = psHexagon
Pointer.VertSize = 7
end
object OHLCSeries: TOpenHighLowCloseSeries
Active = False
Title = 'OHLC series'
CandlestickDownBrush.Color = clRed
CandlestickLinePen.Width = 2
CandlestickUpBrush.Color = clGreen
DownLinePen.Color = clRed
DownLinePen.Width = 2
LinePen.Color = clGreen
LinePen.Width = 2
Mode = mOHLC
end
object BoxWhiskerSeries: TBoxAndWhiskerSeries
Active = False
Title = 'Box-and-whisker series'
BoxBrush.Color = clSkyBlue
WidthStyle = bwsPercentMin
end
object BubbleSeries: TBubbleSeries
Active = False
Title = 'Bubble series'
BubbleBrush.Color = clSkyBlue
end
object ConstantLineSeries: TConstantLine
Active = False
Pen.Color = clFuchsia
Position = 4.5
Title = 'Constant line'
end
object FuncSeries: TFuncSeries
Active = False
Extent.UseXMax = True
Extent.UseXMin = True
Extent.XMax = 10
Title = 'Function series'
OnCalculate = FuncSeriesCalculate
Pen.Color = clBlue
end
object FieldSeries: TFieldSeries
Active = False
Title = 'Field series'
Arrow.Length = 20
Arrow.Visible = True
Arrow.Width = 10
Pen.Color = clGreen
end
object FitSeries: TFitSeries
Active = False
Title = 'Fit series'
FitEquation = feLinear
ParamCount = 2
Pen.Color = clBlue
Pointer.Brush.Color = 16750487
Pointer.HorizSize = 5
Pointer.Style = psCircle
Pointer.VertSize = 5
end
end
end
object Panel1: TPanel
Left = 0
Height = 141
Top = 347
Width = 637
Align = alBottom
AutoSize = True
BevelOuter = bvNone
ClientHeight = 141
ClientWidth = 637
TabOrder = 1
object CbDragXY: TCheckBox
AnchorSideLeft.Control = Panel1
AnchorSideTop.Control = Panel1
Left = 8
Height = 19
Top = 8
Width = 113
BorderSpacing.Left = 8
BorderSpacing.Top = 8
BorderSpacing.Bottom = 8
Caption = 'Drag both x and y'
Checked = True
OnChange = CbDragXYChange
State = cbChecked
TabOrder = 0
end
object DatapointInfo: TLabel
AnchorSideLeft.Control = CbDragXY
AnchorSideLeft.Side = asrBottom
Left = 145
Height = 15
Top = 11
Width = 73
BorderSpacing.Left = 24
Caption = 'DatapointInfo'
ParentColor = False
end
object LblNOTE: TLabel
AnchorSideLeft.Control = Panel1
AnchorSideTop.Control = Label2
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Panel1
AnchorSideRight.Side = asrBottom
Left = 8
Height = 15
Top = 118
Width = 621
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 8
BorderSpacing.Right = 8
BorderSpacing.Bottom = 8
Caption = 'lblNOTE'
ParentColor = False
WordWrap = True
end
object Label2: TLabel
AnchorSideLeft.Control = Panel1
AnchorSideTop.Control = CbDragXY
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Panel1
AnchorSideRight.Side = asrBottom
Left = 8
Height = 75
Top = 35
Width = 621
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Left = 8
BorderSpacing.Right = 8
BorderSpacing.Bottom = 8
Caption = 'USAGE:'#13#10'Drag a datapoint with the left mouse button.'#13#10'Press CTRL for crosshair cursor, see a datapoint info below the chart.'#13#10'Press SHIFT to see a hint window with the datapoint info.'#13#10'CTRL+Left-click to see the hint windows in a message box.'
ParentColor = False
end
object CbCandleStick: TCheckBox
AnchorSideLeft.Control = DatapointInfo
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = CbDragXY
AnchorSideRight.Control = Panel1
AnchorSideRight.Side = asrBottom
Left = 545
Height = 19
Top = 8
Width = 84
Anchors = [akTop, akRight]
BorderSpacing.Left = 24
BorderSpacing.Right = 8
Caption = 'Candle stick'
OnChange = CbCandleStickChange
TabOrder = 1
Visible = False
end
end
object Toolset: TChartToolset
left = 256
top = 72
object BubbleSeriesDatapointDragTool: TDataPointDragTool
Shift = [ssLeft]
AffectedSeries = '8'
GrabRadius = 12
end
object FieldSeriesDatapointDragTool: TDataPointDragTool
Shift = [ssLeft]
GrabRadius = 12
end
object DataPointDragTool: TDataPointDragTool
Shift = [ssLeft]
AffectedSeries = '0,1,2,3,4,5,6,7'
GrabRadius = 12
Targets = [nptPoint, nptXList, nptYList]
OnDrag = DataPointDragToolDragXY
end
object ClickTool: TDataPointClickTool
Shift = [ssCtrl, ssLeft]
GrabRadius = 12
OnPointClick = ClickToolPointClick
end
object HintTool: TDataPointHintTool
Shift = [ssShift]
GrabRadius = 12
OnHint = HintToolHint
end
object CrosshairTool: TDataPointCrosshairTool
Shift = [ssCtrl]
OnAfterKeyUp = CrosshairToolAfterKeyUp
OnAfterMouseUp = CrosshairToolAfterMouseUp
GrabRadius = 12
OnDraw = CrosshairToolDraw
Size = 12
end
end
object ChartStyles: TChartStyles
Styles = <
item
Brush.Color = clRed
Pen.Color = clRed
Text = 'Red'
end
item
Brush.Color = clBlue
Pen.Color = clBlue
Text = 'Blue'
end>
left = 256
top = 144
end
object ListChartSource: TListChartSource
YCount = 2
left = 112
top = 72
end
end

View File

@ -0,0 +1,331 @@
unit main;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, TAGraph, TASeries, TATools, TAStyles, TASources,
Forms, Controls, Graphics, Dialogs, ComCtrls, ExtCtrls, StdCtrls,
TAChartUtils, TAMultiSeries, TARadialSeries, TAFuncSeries, Types;
type
{ TMainForm }
TMainForm = class(TForm)
Chart: TChart;
BarSeries: TBarSeries;
AreaSeries: TAreaSeries;
CbCandleStick: TCheckBox;
BoxWhiskerSeries: TBoxAndWhiskerSeries;
BubbleSeries: TBubbleSeries;
BSplineSeries: TBSplineSeries;
FitSeries: TFitSeries;
FieldSeries: TFieldSeries;
FuncSeries: TFuncSeries;
ConstantLineSeries: TConstantLine;
CubicSplineSeries: TCubicSplineSeries;
ClickTool: TDataPointClickTool;
FieldSeriesDatapointDragTool: TDataPointDragTool;
PolarSeries: TPolarSeries;
OHLCSeries: TOpenHighLowCloseSeries;
ChartStyles: TChartStyles;
CbDragXY: TCheckBox;
DatapointInfo: TLabel;
LblNOTE: TLabel;
Label2: TLabel;
ListChartSource: TListChartSource;
CrosshairTool: TDataPointCrosshairTool;
HintTool: TDataPointHintTool;
BubbleSeriesDatapointDragTool: TDataPointDragTool;
Panel1: TPanel;
Toolset: TChartToolset;
LineSeries: TLineSeries;
DataPointDragTool: TDataPointDragTool;
TabControl: TTabControl;
procedure CbCandleStickChange(Sender: TObject);
procedure CbDragXYChange(Sender: TObject);
procedure ClickToolPointClick(ATool: TChartTool; APoint: TPoint);
procedure CrosshairToolAfterKeyUp(ATool: TChartTool; APoint: TPoint);
procedure CrosshairToolAfterMouseUp(ATool: TChartTool; APoint: TPoint);
procedure CrosshairToolDraw(ASender: TDataPointDrawTool);
procedure FormCreate(Sender: TObject);
procedure DataPointDragToolDragXY(ASender: TDataPointDragTool;
var AGraphPoint: TDoublePoint);
procedure DataPointDragToolDragY(ASender: TDataPointDragTool;
var AGraphPoint: TDoublePoint);
procedure FuncSeriesCalculate(const AX: Double; out AY: Double);
procedure HintToolHint(ATool: TDataPointHintTool; const APoint: TPoint;
var AHint: String);
procedure TabControlChange(Sender: TObject);
private
function GetDatapointInfo(ATool: TDatapointTool): String;
public
end;
var
MainForm: TMainForm;
implementation
{$R *.lfm}
uses
TACustomSeries;
{ TMainForm }
procedure TMainForm.CbCandleStickChange(Sender: TObject);
begin
if CbCandleStick.Checked then
OHLCSeries.Mode := mCandleStick else
OHLCSeries.Mode := mOHLC;
end;
procedure TMainForm.CbDragXYChange(Sender: TObject);
begin
if CbDragXY.Checked then
begin
DataPointDragTool.OnDrag := @DatapointDragToolDragXY;
BubbleSeriesDataPointDragTool.OnDrag := nil;
end else
begin
DataPointDragTool.OnDrag := @DatapointDragToolDragY;
BubbleSeriesdataPointDragTool.OnDrag := @DatapointDragToolDragY;
end;
end;
procedure TMainForm.ClickToolPointClick(ATool: TChartTool; APoint: TPoint);
begin
DatapointInfo.Caption := '';
ShowMessage(GetDatapointInfo(TDatapointTool(ATool)));
end;
procedure TMainForm.CrosshairToolAfterKeyUp(ATool: TChartTool; APoint: TPoint);
begin
TDatapointCrosshairTool(ATool).Hide;
end;
procedure TMainForm.CrosshairToolAfterMouseUp(ATool: TChartTool; APoint: TPoint
);
begin
TDatapointCrosshairTool(ATool).Hide;
end;
procedure TMainForm.CrosshairToolDraw(ASender: TDataPointDrawTool);
begin
DatapointInfo.Caption := GetDatapointInfo(ASender);
end;
// Avoids changing of the x value while dragging a data point
procedure TMainForm.DataPointDragToolDragY(ASender: TDataPointDragTool;
var AGraphPoint: TDoublePoint);
begin
AGraphPoint.X := ASender.Origin.X;
end;
// Modifies the x value if one of the levels of a multi-y-value series is dragged.
// e.g, stacked series, ohlc, box-whisker.
procedure TMainForm.DataPointDragToolDragXY(ASender: TDataPointDragTool;
var AGraphPoint: TDoublePoint);
var
ser: TChartSeries;
begin
if ASender.YIndex > 0 then begin
ser := TChartSeries(ASender.Series);
ser.XValue[ASender.PointIndex] := AGraphPoint.X;
end;
end;
procedure TMainForm.FormCreate(Sender: TObject);
const
N = 10;
var
i: Integer;
x, x2, y1, y2, y3,yO, yH, yL, yC: Double;
begin
ListChartSource.YCount := 2;
ListChartSource.Sorted := true;
for i:=0 to N-1 do begin
x := i + (Random - 0.5) * 0.4;
y1 := x + Random*2;
y2 := y1 + Random*2;
ListChartSource.AddXYList(x, [y1, y2]);
end;
ListChartSource.Sorted := false;
OHLCSeries.ListSource.YCount := 4;
OHLCSeries.ListSource.Sorted := true;
for i:=0 to N-1 do begin
x := i + Random;
yL := x + Random;
yH := yL + Random + 5;
yO := yL + Random * 5;
yC := yL + Random * 5;
OHLCSeries.AddXOHLC(x, yO, yH, yL, yC);
end;
OHLCSeries.ListSource.Sorted := false;
BoxWhiskerSeries.ListSource.YCount := 5;
BoxWhiskerSeries.ListSource.Sorted := true;
for i:=0 to N-1 do begin
x := i + (Random-0.5)*0.4;
yL := x * Random;
y1 := yL + Random;
y2 := y1 + Random;
y3 := y2 + Random;
yH := y3 + Random;
BoxWhiskerSeries.AddXY(x, yL, y1, y2, y3, yH);
end;
BoxWhiskerSeries.ListSource.Sorted := true;
BubbleSeries.ListSource.YCount := 3;
for i:=0 to N-1 do begin
x := (Random - 0.5) * 2.0;
y1 := (Random - 0.5) * 2.0;
y2 := Random*0.3;
BubbleSeries.AddXY(x, y1, y2);
end;
FitSeries.Clear;
for i:= 0 to N - 1 do begin
x := Random * 10;
y1 := x + random * 1;
FitSeries.AddXY(x, y1);
end;
FieldSeries.ListSource.XCount := 2;
FieldSeries.ListSource.YCount := 2;
for i:=0 to N-1 do begin
x := Random * 10;
x2 := x + Random;
y1 := Random * 10;
y2 := y1 + Random;
FieldSeries.AddVector(x, y1, x2, y2);
end;
LineSeries.Index := 0;
BarSeries.Index := 1;
AreaSeries.Index := 2;
PolarSeries.Index := 3;
CubicSplineSeries.Index := 4;
BSplineSeries.Index := 5;
FitSeries.Index := 6;
OHLCSeries.Index := 7;
BoxWhiskerSeries.Index := 8;
BubbleSeries.Index := 9;
FieldSeries.Index := 10;
FuncSeries.Index := 11;
ConstantLineSeries.Index := 12;
TabControlChange(nil);
DatapointInfo.Caption := '';
end;
procedure TMainForm.FuncSeriesCalculate(const AX: Double; out AY: Double);
begin
AY := sin(AX);
end;
function TMainForm.GetDataPointInfo(ATool: TDataPointTool): String;
var
ser: TChartSeries;
begin
Result := '';
if ATool.Series is TConstantLine then
Result := Format('"%s": Position %.2f', [
TConstantLine(ATool.Series).Title, TConstantLine(ATool.Series).Position
])
else
if ATool.Series is TFuncSeries then
Result := Format('"%s": x = %.2f, y = %,2f', [
TFuncSeries(ATool.Series).Title, ATool.NearestGraphPoint.X, ATool.NearestGraphPoint.Y
])
else
if ATool.Series is TChartSeries then begin
ser := TChartSeries(ATool.Series);
if ser <> nil then begin
if (ATool.YIndex = -1) and
((ser is TFitSeries) or (ser is TCubicSplineSeries) or (ser is TBSplineSeries))
then
Result := Format('"%s": x = %.2f, y = %.2f', [
ser.Title,
ATool.NearestGraphPoint.X, ATool.NearestGraphPoint.Y
])
else
if (ATool.PointIndex > -1) and (ATool.YIndex > -1) then
Result := Format('"%s": Point index %d, x = %.2f, y = %.2f (y index %d)', [
ser.Title,
ATool.PointIndex,
ser.XValue[ATool.PointIndex],
ser.YValues[ATool.PointIndex, ATool.YIndex],
ATool.YIndex
]);
end;
end;
end;
procedure TMainForm.HintToolHint(ATool: TDataPointHintTool;
const APoint: TPoint; var AHint: String);
begin
AHint := GetDatapointInfo(ATool);
DatapointInfo.Caption := '';
end;
procedure TMainForm.TabControlChange(Sender: TObject);
var
ser: TBasicChartSeries;
s: String;
begin
// Show only the series of the corresponding tab
for ser in Chart.Series do
ser.Active := ser.Index = TabControl.TabIndex;
// Avoid tools react on hidden series
s := IntToStr(TabControl.TabIndex);
CrosshairTool.AffectedSeries := s;
HintTool.AffectedSeries := s;
BubbleSeriesDatapointDragTool.Enabled := TabControl.TabIndex = BubbleSeries.Index;
FieldSeriesDatapointDragTool.Enabled := TabControl.TabIndex = FieldSeries.Index;
DataPointDragTool.Enabled := not
(BubbleSeriesDatapointDragTool.Enabled or FieldSeriesDatapointDragtool.Enabled);
if BubbleSeriesDatapointDragTool.Enabled then
BubbleSeriesDatapointDragTool.AffectedSeries := s
else
if FieldSeriesDatapointDragTool.Enabled then
FieldSeriesDatapointDragTool.AffectedSeries := s
else
DatapointDragtool.AffectedSeries := s;
// Treatment of special requirements of particular series
CbCandleStick.Visible := OHLCSeries.Active;
LblNOTE.Visible := LineSeries.Active or BarSeries.Active or AreaSeries.Active;
Chart.LeftAxis.Range.UseMax := ConstantLineSeries.Active;
Chart.LeftAxis.Range.UseMin := ConstantLineSeries.Active;
s := '';
if LineSeries.Active or BarSeries.Active or AreaSeries.Active then begin
s := 'These are stacked series, i.e. they share the same x ' +
'value defined by the red series --> When you drag a datapoint of any ' +
'series the x value of the other series will follow.';
if BarSeries.Active then
s := s + LineEnding + 'Grab the bars at their upper ends.';
end else
if FieldSeries.Active then begin
s := 'Rotate an arrow by grabbing it at its ends.' + LineEnding +
'Shift it by grabbing it in the middle.' + LineEnding +
'The checkbox "Drag both x and y" is not operating here.';
end;
if s <> '' then
LblNOTE.Caption := 'NOTE:' + LineEnding + s;
LblNote.Visible := (s <> '');
end;
end.