1
unit LUX.FMX.ScatterPlotFrame;
3
interface //#################################################################### ■
6
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
7
FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls, FMX.Objects,
10
type //$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【型】
12
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TScaleLine
21
constructor Create( const Scale_,Thick_:Single; const Color_:TAlphacolor );
24
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TScatterPlotFrame
26
TScatterPlotFrame = class(TFrame)
36
_BackColor :TAlphaColor;
37
_AreaColor :TAlphaColor;
38
_Plots :TArray<TSingle2D>;
41
_PlotColor :TAlphaColor;
44
_ScaleX :TArray<TScaleLine>;
45
_ScaleY :TArray<TScaleLine>;
47
_FontColor :TAlphaColor;
49
procedure SetMargin( const Margin_:Single ); virtual;
50
procedure SetMinX( const MinX_:Single ); virtual;
51
procedure SetMaxX( const MaxX_:Single ); virtual;
52
procedure SetMinY( const MinY_:Single ); virtual;
53
procedure SetMaxY( const MaxY_:Single ); virtual;
54
procedure SetBackColor( const BackColor_:TAlphaColor ); virtual;
55
procedure SetAreaColor( const AreaColor_:TAlphaColor ); virtual;
56
function GetPlot( const I_:Integer ) :TSingle2D; virtual;
57
procedure SetPlot( const I_:Integer; const Plot_:TSingle2D ); virtual;
58
procedure SetPlotsN( const PlotsN_:Integer ); virtual;
59
procedure SetPlotSize( const PlotSize_:Single ); virtual;
60
procedure SetPlotColor( const PlotColor_:TAlphaColor ); virtual;
61
procedure SetFocus( const Focus_:Integer ); virtual;
62
procedure SetHover( const Hover_:Integer ); virtual;
63
function GetScaleX( const I_:Integer ) :TScaleLine; virtual;
64
procedure SetScaleX( const I_:Integer; const ScaleX_:TScaleLine ); virtual;
65
function GetScaleY( const I_:Integer ) :TScaleLine; virtual;
66
procedure SetScaleY( const I_:Integer; const ScaleY_:TScaleLine ); virtual;
67
procedure SetScaleN( const ScaleN_:Integer ); virtual;
68
procedure SetFontColor( const FontColor_:TAlphaColor ); virtual;
70
procedure MouseDown( Button_:TMouseButton; Shift_:TShiftState; X_,Y_:Single ); override;
71
procedure MouseMove( Shift_:TShiftState; X_,Y_:Single); override;
72
procedure MouseUp( Button_:TMouseButton; Shift_:TShiftState; X_,Y_:Single ); override;
73
procedure Paint; override;
74
procedure Resize; override;
75
function ScrToPos( const S_:TPointF ) :TSingle2D;
76
function PosToScr( const P_:TSingle2D ) :TPointF;
79
procedure DrawScaleX( const Interval_:Single );
80
procedure DrawScaleY( const Interval_:Single );
81
procedure DrawValuesX( const Interval_:Single; const Digits_:Integer );
82
procedure DrawValuesY( const Interval_:Single; const Digits_:Integer );
84
property Hover :Integer read _Hover write SetHover;
87
constructor Create( AOwner_:TComponent ); override;
88
destructor Destroy; override;
90
property Margin :Single read _Margin write SetMargin ;
91
property Area :TRectF read _Area ;
92
property MinX :Single read _MinX write SetMinX ;
93
property MaxX :Single read _MaxX write SetMaxX ;
94
property MinY :Single read _MinY write SetMinY ;
95
property MaxY :Single read _MaxY write SetMaxY ;
96
property BackColor :TAlphaColor read _BackColor write SetBackColor;
97
property AreaColor :TAlphaColor read _AreaColor write SetAreaColor;
98
property Plots[ const I_:Integer ] :TSingle2D read GetPlot write SetPlot ; default;
99
property PlotsN :Integer read _PlotsN write SetPlotsN ;
100
property PlotSize :Single read _PlotSize write SetPlotSize ;
101
property PlotColor :TAlphaColor read _PlotColor write SetPlotColor;
102
property Focus :Integer read _Focus write SetFocus ;
103
property ScaleX[ const I_:Integer ] :TScaleLine read GetScaleX write SetScaleX ;
104
property ScaleY[ const I_:Integer ] :TScaleLine read GetScaleY write SetScaleY ;
105
property ScaleN :Integer read _ScaleN write SetScaleN ;
106
property FontColor :TAlphaColor read _FontColor write SetFontColor;
108
function FindNearPlot( const Scr_:TPointF ) :Integer; overload;
109
function FindNearPlot( const Pos_:TSingle2D ) :Integer; overload;
112
implementation //############################################################### ■
118
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【型】
120
//$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$【クラス】
122
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TScaleLine
124
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& private
126
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& public
128
constructor TScaleLine.Create( const Scale_,Thick_:Single; const Color_:TAlphacolor );
135
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% TScatterPlotFrame
137
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& private
139
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& protected
141
/////////////////////////////////////////////////////////////////////// アクセス
143
procedure TScatterPlotFrame.SetMargin( const Margin_:Single );
145
_Margin := Margin_; Repaint;
148
procedure TScatterPlotFrame.SetMinX( const MinX_:Single );
150
_MinX := MinX_; Repaint;
153
procedure TScatterPlotFrame.SetMaxX( const MaxX_:Single );
155
_MaxX := MaxX_; Repaint;
158
procedure TScatterPlotFrame.SetMinY( const MinY_:Single );
160
_MinY := MinY_; Repaint;
163
procedure TScatterPlotFrame.SetMaxY( const MaxY_:Single );
165
_MaxY := MaxY_; Repaint;
168
//------------------------------------------------------------------------------
170
procedure TScatterPlotFrame.SetBackColor( const BackColor_:TAlphaColor );
172
_BackColor := BackColor_; Repaint;
175
procedure TScatterPlotFrame.SetAreaColor( const AreaColor_:TAlphaColor );
177
_AreaColor := AreaColor_; Repaint;
180
//------------------------------------------------------------------------------
182
function TScatterPlotFrame.GetPlot( const I_:Integer ) :TSingle2D;
184
Result := _Plots[ I_ ];
187
procedure TScatterPlotFrame.SetPlot( const I_:Integer; const Plot_:TSingle2D );
189
_Plots[ I_ ] := Plot_;
192
procedure TScatterPlotFrame.SetPlotsN( const PlotsN_:Integer );
196
SetLength( _Plots, _PlotsN );
199
procedure TScatterPlotFrame.SetPlotSize( const PlotSize_:Single );
201
_PlotSize := PlotSize_; Repaint;
204
procedure TScatterPlotFrame.SetPlotColor( const PlotColor_:TAlphaColor );
206
_PlotColor := PlotColor_; Repaint;
209
//------------------------------------------------------------------------------
211
procedure TScatterPlotFrame.SetFocus( const Focus_:Integer );
213
_Focus := Focus_; Repaint;
216
procedure TScatterPlotFrame.SetHover( const Hover_:Integer );
218
_Hover := Hover_; Repaint;
221
//------------------------------------------------------------------------------
223
function TScatterPlotFrame.GetScaleX( const I_:Integer ) :TScaleLine;
225
Result := _ScaleX[ I_ ];
228
procedure TScatterPlotFrame.SetScaleX( const I_:Integer; const ScaleX_:TScaleLine );
230
_ScaleX[ I_ ] := ScaleX_; Repaint;
233
function TScatterPlotFrame.GetScaleY( const I_:Integer ) :TScaleLine;
235
Result := _ScaleY[ I_ ];
238
procedure TScatterPlotFrame.SetScaleY( const I_:Integer; const ScaleY_:TScaleLine );
240
_ScaleY[ I_ ] := ScaleY_; Repaint;
243
procedure TScatterPlotFrame.SetScaleN( const ScaleN_:Integer );
247
SetLength( _ScaleX, _ScaleN );
248
SetLength( _ScaleY, _ScaleN );
253
//------------------------------------------------------------------------------
255
procedure TScatterPlotFrame.SetFontColor( const FontColor_:TAlphaColor );
257
_FontColor := FontColor_; Repaint;
260
/////////////////////////////////////////////////////////////////////// メソッド
262
procedure TScatterPlotFrame.MouseDown( Button_:TMouseButton; Shift_:TShiftState; X_,Y_:Single );
266
Focus := FindNearPlot( TPointF.Create( X_, Y_ ) );
269
procedure TScatterPlotFrame.MouseMove( Shift_:TShiftState; X_,Y_:Single );
273
Hover := FindNearPlot( TPointF.Create( X_, Y_ ) );
276
procedure TScatterPlotFrame.MouseUp( Button_:TMouseButton; Shift_:TShiftState; X_,Y_:Single );
282
//------------------------------------------------------------------------------
284
procedure TScatterPlotFrame.Paint;
292
Stroke.Kind := TBrushKind.Solid;
293
Fill .Kind := TBrushKind.Solid;
301
Fill.Color := _AreaColor;
303
FillRect( _Area, 0, 0, [], 1 );
307
for I := _ScaleN-1 downto 0 do
311
Stroke.Thickness := Thick;
312
Stroke.Color := Color;
319
Stroke.Thickness := Thick;
320
Stroke.Color := Color;
331
Color := TAlphaColors.White;
340
Fill.Color := _FontColor;
342
DrawValuesX( _ScaleX[0].Scale, 1 );
343
DrawValuesY( _ScaleY[0].Scale, 1 );
350
Color := TAlphaColors.Lime;
357
procedure TScatterPlotFrame.Resize;
361
_Area := TRectF.Create( _Margin, _Margin, Width-_Margin, Height-_Margin );
364
//------------------------------------------------------------------------------
366
function TScatterPlotFrame.ScrToPos( const S_:TPointF ) :TSingle2D;
368
Result.X := ( _MaxX - _MinX ) * ( S_.X - _Area.Left ) / _Area.Width + _MinX;
369
Result.Y := ( _MinY - _MaxY ) * ( S_.Y - _Area.Top ) / _Area.Height + _MaxY;
372
function TScatterPlotFrame.PosToScr( const P_:TSingle2D ) :TPointF;
374
Result.X := ( P_.X - _MinX ) / ( _MaxX - _MinX ) * _Area.Width + _Area.Left;
375
Result.Y := ( P_.Y - _MaxY ) / ( _MinY - _MaxY ) * _Area.Height + _Area.Top ;
378
//------------------------------------------------------------------------------
380
procedure TScatterPlotFrame.DrawPlots;
387
for I := 0 to High( _Plots ) do
389
P := PosToScr( _Plots[ I ] );
393
DrawCircle( P, 2 * _PlotSize );
398
Fill.Color := TAlphaColors.Red;
400
FillCircle( P, _PlotSize );
404
Fill.Color := _PlotColor;
406
FillCircle( P, _PlotSize );
412
//------------------------------------------------------------------------------
414
procedure TScatterPlotFrame.DrawAxis;
418
DrawLine( PosToScr( TSingle2D.Create( 0, _MinY ) ),
419
PosToScr( TSingle2D.Create( 0, _MaxY ) ), 1 );
421
DrawLine( PosToScr( TSingle2D.Create( _MinX, 0 ) ),
422
PosToScr( TSingle2D.Create( _MaxX, 0 ) ), 1 );
426
//------------------------------------------------------------------------------
428
procedure TScatterPlotFrame.DrawScaleX( const Interval_ :Single );
433
X0 := Ceil( _MinX / Interval_ ); X1 := Floor( _MaxX / Interval_ );
437
P0.Y := _MinY; P1.Y := _MaxY;
440
P0.X := Interval_ * X; P1.X := P0.X;
442
DrawLine( PosToScr( P0 ), PosToScr( P1 ), 1 );
447
procedure TScatterPlotFrame.DrawScaleY( const Interval_ :Single );
452
Y0 := Ceil( _MinY / Interval_ ); Y1 := Floor( _MaxY / Interval_ );
456
P0.X := _MinX; P1.X := _MaxX;
459
P0.Y := Interval_ * Y; P1.Y := P0.Y;
461
DrawLine( PosToScr( P0 ), PosToScr( P1 ), 1 );
466
//------------------------------------------------------------------------------
468
procedure TScatterPlotFrame.DrawValuesX( const Interval_ :Single; const Digits_:Integer );
475
X0 := Ceil( _MinX / Interval_ ); X1 := Floor( _MaxX / Interval_ );
482
P.X := Interval_ * X;
484
T := FloatToStrF( P.X, TFloatFormat.ffFixed, 7, Digits_ );
488
with S do Y := Y - 0.37*Font.Size + Font.Size/2;
490
DrawText( T, S, TTextAlign.Center, TTextAlign.Leading );
495
procedure TScatterPlotFrame.DrawValuesY( const Interval_ :Single; const Digits_:Integer );
502
Y0 := Ceil( _MinY / Interval_ ); Y1 := Floor( _MaxY / Interval_ );
509
P.Y := Interval_ * Y;
511
T := FloatToStrF( P.Y, TFloatFormat.ffFixed, 7, Digits_ );
515
with S do X := X - Font.Size/2;
517
DrawText( T, S, TTextAlign.Trailing, TTextAlign.Center );
522
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& public
524
constructor TScatterPlotFrame.Create( AOwner_:TComponent );
530
_Area := TRectF.Create( _Margin, _Margin, Width-_Margin, Height-_Margin );
537
_BackColor := TAlphaColors.Dimgray;
538
_AreaColor := TAlphaColors.Black;
543
_PlotColor := TAlphaColors.Yellow;
550
ScaleX[0] := TScaleLine.Create( 1.0, 1.00, $FFC0C0C0 );
551
ScaleX[1] := TScaleLine.Create( 0.5, 0.75, $FF808080 );
552
ScaleX[2] := TScaleLine.Create( 0.1, 0.50, $FF404040 );
554
ScaleY[0] := TScaleLine.Create( 1.0, 1.00, $FFC0C0C0 );
555
ScaleY[1] := TScaleLine.Create( 0.5, 0.75, $FF808080 );
556
ScaleY[2] := TScaleLine.Create( 0.1, 0.50, $FF404040 );
558
_FontColor := TAlphaColors.White;
561
destructor TScatterPlotFrame.Destroy;
567
/////////////////////////////////////////////////////////////////////// メソッド
569
function TScatterPlotFrame.FindNearPlot( const Scr_:TPointF ) :Integer;
574
Result := -1; MinD := 4 * _PlotSize;
576
for I := 0 to PlotsN-1 do
578
D := Scr_.Distance( PosToScr( Plots[ I ] ) );
582
Result := I; MinD := D;
587
function TScatterPlotFrame.FindNearPlot( const Pos_:TSingle2D ) :Integer;
592
Result := -1; MinD := 0.1;
594
for I := 0 to PlotsN-1 do
596
D := Pos_.DistanTo( Plots[ I ] );
600
Result := I; MinD := D;
605
end. //######################################################################### ■