jvcllaz: Better layout of title and x axis positions.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@7180 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
wp_xxyyzz 2019-11-10 20:03:43 +00:00
parent 1508d443ac
commit 2b16ccc6bf
6 changed files with 235 additions and 142 deletions

View File

@ -29,10 +29,8 @@ object JvChartDemoForm: TJvChartDemoForm
Options.XOrigin = 0
Options.YOrigin = 0
Options.XStartOffset = 60
Options.YStartOffset = 42
Options.PrimaryYAxis.YMax = 20
Options.PrimaryYAxis.YMin = 0
Options.PrimaryYAxis.YDivisions = 20
Options.PrimaryYAxis.YLegendDecimalPlaces = 1
Options.SecondaryYAxis.YMax = 140
Options.SecondaryYAxis.YMin = 0
@ -41,8 +39,6 @@ object JvChartDemoForm: TJvChartDemoForm
Options.MouseDragObjects = False
Options.Legend = clChartLegendBelow
Options.LegendRowCount = 1
Options.PenLineWidth = 2
Options.AxisLineWidth = 3
Options.XValueCount = 20
Options.HeaderFont.Color = clWindowText
Options.LegendFont.Color = clWindowText
@ -50,8 +46,6 @@ object JvChartDemoForm: TJvChartDemoForm
Options.AxisTitleFont.Height = -16
Options.AxisTitleFont.Orientation = 900
Options.AxisTitleFont.Style = [fsBold]
Options.PaperColor = clWhite
Options.AxisLineColor = clBlack
Options.CursorColor = clBlack
Options.CursorStyle = psDot
OnBeginFloatingMarkerDrag = ChartBeginFloatingMarkerDrag
@ -578,9 +572,9 @@ object JvChartDemoForm: TJvChartDemoForm
Caption = 'Use Positive and Negative Demo Values (-20..+20)'
OnClick = MenuNegValueTestClick
end
object MenuSecondaryAxisMode: TMenuItem
object mnuSecondaryAxisMode: TMenuItem
Caption = '&Plot Markers+Values using Alternate Scale (0-120%)'
OnClick = MenuSecondaryAxisModeClick
OnClick = mnuSecondaryAxisModeClick
end
object N4: TMenuItem
Caption = '-'

View File

@ -37,9 +37,9 @@ unit JvChartDemoFm;
interface
uses
Windows, SysUtils, Messages, Classes, Graphics, Controls,
SysUtils, Classes, Graphics, Controls, Menus,
Forms, Dialogs, ExtCtrls, StdCtrls, Buttons, Spin, PrintersDlgs,
JvChart, JvComponent, JvExControls, StatsClasses, Menus;
JvChart, StatsClasses;
type
@ -109,7 +109,7 @@ type
PrintOptions1: TMenuItem;
PrinterSetupDialog1: TPrinterSetupDialog;
PrintDialog1: TPrintDialog;
MenuSecondaryAxisMode: TMenuItem;
mnuSecondaryAxisMode: TMenuItem;
MenuNegValueTest: TMenuItem;
SpeedButtonTestMouseOver: TSpeedButton;
NewFeaturesfor20071: TMenuItem;
@ -151,7 +151,7 @@ type
procedure FormDestroy(Sender: TObject);
procedure PrintOptions1Click(Sender: TObject);
procedure MenuSecondaryAxisModeClick(Sender: TObject);
procedure mnuSecondaryAxisModeClick(Sender: TObject);
procedure ListBox1Click(Sender: TObject);
procedure ListBox1DblClick(Sender: TObject);
@ -203,6 +203,7 @@ var
implementation
uses
LCLIntf, // OpenURL
LCLType, // MB_OK
Math, // Math:NaN handling, function isNan in D6 and higher.
JvPenEditor;
@ -289,7 +290,7 @@ begin
// if Chart.Options.XAxisDateTimeMode was also set.
Chart.Options.XLegends.Add(FormatDateTime('hh:nn:ss', Fds));
if MenuSecondaryAxisMode.Checked then
if mnuSecondaryAxisMode.Checked then
begin
if I = 1 then
Chart.Data.Value[3, I] := 100
@ -461,7 +462,7 @@ begin
PenStyle[1] := psDash;
PenStyle[2] := psDot;
if MenuSecondaryAxisMode.Checked then
if mnuSecondaryAxisMode.Checked then
begin
PenCount := 4; // Add a pen for right side demo.
SecondaryYAxis.YMax := 140; // Example shows Q/A percentage. Experimental results
@ -488,14 +489,14 @@ begin
PenLegends.Add('HgT');
PenLegends.Add('Hg0');
PenLegends.Add('Hg2+');
if MenuSecondaryAxisMode.Checked then
if mnuSecondaryAxisMode.Checked then
PenLegends.Add('Quality%');
PenUnit.Clear;
PenUnit.Add('ug/m3');
PenUnit.Add('ug/m3');
PenUnit.Add('ug/m3');
if MenuSecondaryAxisMode.Checked then
if mnuSecondaryAxisMode.Checked then
PenUnit.Add('%'); // Optional Pen in percentage scale.
//ShowLegend := TRUE;
@ -586,8 +587,8 @@ end;
procedure TJvChartDemoForm.SpinEdit1Change(Sender: TObject);
begin
// Chart.Options.PrimaryYAxis.YPixelGap := SpinEdit1.Value;
// Chart.Options.YStartOffset := SpinEdit1.Value;
Chart.Options.XStartOffset := SpinEdit1.Value;
Chart.Options.YStartOffset := SpinEdit1.Value;
// Chart.Options.XStartOffset := SpinEdit1.Value;
// Chart.Options.ColorScheme := SpinEdit1.Value;
// Chart.PlotGraph;
end;
@ -622,7 +623,8 @@ end;
procedure TJvChartDemoForm.Panel2DblClick(Sender: TObject);
begin
ShellExecute(HWND(nil), 'show', 'http://jvcl.delphi-jedi.org/', nil, nil, SW_SHOW);
OpenURL('http://jvcl.delphi-jedi.org/');
// ShellExecute(HWND(nil), 'show', 'http://jvcl.delphi-jedi.org/', nil, nil, SW_SHOW);
end;
procedure TJvChartDemoForm.ShowgapinLineChart1Click(Sender: TObject);
@ -679,7 +681,7 @@ var
w: Integer;
begin
s := InputBox('Set Axis Linewidth', 'Value:', IntToStr(Chart.Options.AxisLineWidth));
if TryStrToInt(s, w) and (w > 0) then
if TryStrToInt(s, w) and (w >= 0) then
Chart.Options.AxisLineWidth := w
else
MessageDlg('No valid number for axis linewidth', mtError, [mbOk], 0);
@ -889,11 +891,11 @@ begin
PrinterSetupDialog1.Execute;
end;
procedure TJvChartDemoForm.MenuSecondaryAxisModeClick(Sender: TObject);
procedure TJvChartDemoForm.mnuSecondaryAxisModeClick(Sender: TObject);
begin
MenuSecondaryAxisMode.Checked := not MenuSecondaryAxisMode.Checked;
mnuSecondaryAxisMode.Checked := not mnuSecondaryAxisMode.Checked;
if MenuSecondaryAxisMode.Checked then
if mnuSecondaryAxisMode.Checked then
begin
ButtonLine.Down := true;
ButtonLineClick(Sender);

View File

@ -1,10 +1,11 @@
object PenEditorForm: TPenEditorForm
Left = 347
Height = 291
Height = 302
Top = 128
Width = 505
BorderStyle = bsDialog
Caption = 'PenEditorForm'
ClientHeight = 291
ClientHeight = 302
ClientWidth = 505
OnCreate = FormCreate
OnDestroy = FormDestroy
@ -13,7 +14,7 @@ object PenEditorForm: TPenEditorForm
object btnPenColor: TButton
Left = 232
Height = 25
Top = 216
Top = 232
Width = 64
AutoSize = True
Caption = 'Color...'
@ -22,7 +23,7 @@ object PenEditorForm: TPenEditorForm
end
object rgPenStyle: TRadioGroup
Left = 224
Height = 160
Height = 168
Top = 40
Width = 121
AutoFill = True
@ -34,7 +35,7 @@ object PenEditorForm: TPenEditorForm
ChildSizing.ShrinkVertical = crsScaleChilds
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 1
ClientHeight = 140
ClientHeight = 148
ClientWidth = 117
Items.Strings = (
'Solid'
@ -50,7 +51,7 @@ object PenEditorForm: TPenEditorForm
object ButtonPanel1: TButtonPanel
Left = 6
Height = 34
Top = 251
Top = 262
Width = 493
OKButton.Name = 'OKButton'
OKButton.DefaultCaption = True
@ -65,7 +66,7 @@ object PenEditorForm: TPenEditorForm
end
object lbPens: TListBox
Left = 8
Height = 200
Height = 216
Top = 8
Width = 200
ItemHeight = 0
@ -77,7 +78,7 @@ object PenEditorForm: TPenEditorForm
object btnAdd: TButton
Left = 11
Height = 25
Top = 216
Top = 232
Width = 48
AutoSize = True
Caption = 'Add'
@ -87,7 +88,7 @@ object PenEditorForm: TPenEditorForm
object btnDelete: TButton
Left = 64
Height = 25
Top = 216
Top = 232
Width = 59
AutoSize = True
Caption = 'Delete'
@ -105,7 +106,7 @@ object PenEditorForm: TPenEditorForm
object btnClear: TButton
Left = 128
Height = 25
Top = 216
Top = 232
Width = 53
AutoSize = True
Caption = 'Clear'
@ -123,12 +124,12 @@ object PenEditorForm: TPenEditorForm
object ColorSample: TShape
Left = 304
Height = 25
Top = 216
Top = 232
Width = 25
end
object rgMarker: TRadioGroup
Left = 376
Height = 160
Height = 136
Top = 40
Width = 112
AutoFill = True
@ -140,7 +141,7 @@ object PenEditorForm: TPenEditorForm
ChildSizing.ShrinkVertical = crsScaleChilds
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 1
ClientHeight = 140
ClientHeight = 116
ClientWidth = 108
Items.Strings = (
'None'
@ -152,6 +153,29 @@ object PenEditorForm: TPenEditorForm
OnClick = rgMarkerClick
TabOrder = 8
end
object rgAxis: TRadioGroup
Left = 376
Height = 64
Top = 192
Width = 113
AutoFill = True
Caption = 'y Axis'
ChildSizing.LeftRightSpacing = 6
ChildSizing.EnlargeHorizontal = crsHomogenousChildResize
ChildSizing.EnlargeVertical = crsHomogenousChildResize
ChildSizing.ShrinkHorizontal = crsScaleChilds
ChildSizing.ShrinkVertical = crsScaleChilds
ChildSizing.Layout = cclLeftToRightThenTopToBottom
ChildSizing.ControlsPerLine = 1
ClientHeight = 44
ClientWidth = 109
Items.Strings = (
'Primary'
'Secondary'
)
OnClick = rgAxisClick
TabOrder = 9
end
object ColorDialog: TColorDialog
Color = clBlack
CustomColors.Strings = (

View File

@ -15,6 +15,7 @@ type
Color: TColor;
Style: TPenStyle;
Marker: TJvChartPenMarkerKind;
SecondaryAxis: Boolean;
end;
{ TPenEditorForm }
@ -29,6 +30,7 @@ type
edPenLegend: TEdit;
lblLegend: TLabel;
lbPens: TListBox;
rgAxis: TRadioGroup;
rgMarker: TRadioGroup;
rgPenStyle: TRadioGroup;
ColorSample: TShape;
@ -42,6 +44,7 @@ type
procedure lbPensDrawItem(Control: TWinControl; Index: Integer;
ARect: TRect; State: TOwnerDrawState);
procedure lbPensSelectionChange(Sender: TObject; User: boolean);
procedure rgAxisClick(Sender: TObject);
procedure rgMarkerClick(Sender: TObject);
procedure rgPenStyleClick(Sender: TObject);
private
@ -62,7 +65,7 @@ implementation
{$R *.lfm}
uses
LCLType;
Math, LCLType;
{ TPenEditorForm }
@ -94,6 +97,7 @@ begin
pen.Style := psSolid;
pen.Color := clBlack;
pen.Marker := pmkNone;
pen.SecondaryAxis := false;
FPens.Add(pen);
lbPens.Items.Add('');
end;
@ -141,6 +145,7 @@ begin
pen.Style := TPenStyle(rgPenStyle.ItemIndex);
pen.Marker := TJvChartPenMarkerKind(rgMarker.ItemIndex);
pen.Color := ColorSample.Brush.Color;
pen.SecondaryAxis := rgAxis.ItemIndex = 1;
end;
procedure TPenEditorForm.edPenLegendEditingDone(Sender: TObject);
@ -257,21 +262,34 @@ begin
exit;
pen := TPenObj(FPens[AIndex]);
edPenLegend.Text := pen.Legend;
if pen.Style = psClear then
rgPenStyle.ItemIndex := rgPenStyle.Items.Count-1
else
rgPenStyle.ItemIndex := ord(pen.Style);
rgMarker.ItemIndex := ord(pen.Marker);
rgAxis.ItemIndex := IfThen(pen.SecondaryAxis, 1, 0);
ColorSample.Brush.Color := pen.Color;
edPenLegend.Enabled := true;
rgPenStyle.Enabled := true;
rgMarker.Enabled := true;
rgAxis.Enabled := true;
btnPenColor.Enabled := true;
ColorSample.Visible := true;
end;
procedure TPenEditorForm.rgAxisClick(Sender: TObject);
var
pen: TPenObj;
begin
pen := GetCurrentPen;
if pen = nil then
exit;
pen.SecondaryAxis := rgAxis.ItemIndex = 1;
end;
procedure TPenEditorForm.rgMarkerClick(Sender: TObject);
var
pen: TPenObj;
@ -314,6 +332,7 @@ begin
pen.Color := AChart.Options.PenColor[i];
pen.Style := AChart.Options.PenStyle[i];
pen.Marker := AChart.Options.PenMarkerKind[i];
pen.SecondaryAxis := AChart.Options.PenSecondaryAxisFlag[i];;
FPens.Add(pen);
lbPens.Items.Add('');
end;
@ -321,6 +340,7 @@ begin
edPenLegend.Enabled := false;
rgPenStyle.Enabled := false;
rgMarker.Enabled := false;
rgAxis.Enabled := false;
btnPenColor.Enabled := false;
ColorSample.Visible := false;
end;

View File

@ -33,55 +33,45 @@ Known Issues:
unit StatsClasses;
interface
type
TStatArray = class
TStatArray = class
protected
//FFirst:Boolean;
FGrows:Boolean; // false=rolling average (circular buffer mode), true=average or sd of any number of samples (array grows without limit)
FValues:Array of Double;
FLength, // Array absolute size (may still be no data even if this is >0)
FIndex, // Where will the next sample be stored into the array?
FCount: // How many valid samples are in the array right now?
Integer;
procedure SetLen(aLength:Integer);
FGrows: Boolean; // false=rolling average (circular buffer mode), true=average or sd of any number of samples (array grows without limit)
FValues: Array of Double;
FLength: Integer; // Array absolute size (may still be no data even if this is >0)
FIndex: Integer; // Where will the next sample be stored into the array?
FCount: Integer; // How many valid samples are in the array right now?
procedure SetLen(aLength:Integer);
public
procedure AddValue(aValue:Double);
function Average:Double;
function StandardDeviation:Double;
property Grows:Boolean read FGrows write FGrows; // false=rolling average, true=average ALL samples (grows to fit)
property Length:Integer read FLength write SetLen;
property Count:Integer read FCount;
//property First:Boolean read FFirst;
procedure Reset; // Clear everything!
constructor Create; overload;
constructor Create(initialLength:Integer); overload;
destructor Destroy; override;
procedure AddValue(aValue:Double);
function Average:Double;
function StandardDeviation:Double;
property Grows:Boolean read FGrows write FGrows; // false=rolling average, true=average ALL samples (grows to fit)
property Length:Integer read FLength write SetLen;
property Count:Integer read FCount;
//property First:Boolean read FFirst;
procedure Reset; // Clear everything!
end;
implementation
uses //Windows, // OutputDebugString
SysUtils, // FloatToStr
Math; // VCL's statistics routines. StdDev, etc.
uses
SysUtils, // FloatToStr
Math; // VCL's statistics routines. StdDev, etc.
// Begin Rolling Average
constructor TStatArray.Create; // overload;
constructor TStatArray.Create; // overload;
begin
//FFirst := true;
FLength := 0;
@ -123,24 +113,24 @@ begin
end;
function TStatArray.Average:Double;
function TStatArray.Average:Double;
var
last,i:Integer;
sum:Double;
last,i:Integer;
sum:Double;
begin
if FCount <= 0 then begin
if FCount <= 0 then begin
result := 0;
end else begin
end else begin
sum := 0;
if (FCount>FLength) then
last :=FLength-1
last :=FLength-1
else
last :=FCount-1;
last :=FCount-1;
for i := 0 to last do begin
sum := sum + FValues[i];
sum := sum + FValues[i];
end;
result := sum / (last+1);
end;
end;
end;
function TStatArray.StandardDeviation:Double;

View File

@ -98,7 +98,7 @@ unit JvChart;
{$MODE OBJFPC}{$H+}
{$DEFINE TJVCHART_ARRAY_OF_ARRAY}
//{$I jvcl.inc}
{.$DEFINE TEXT_BOX}
interface
@ -112,8 +112,8 @@ const
JvDefaultHintColor = TColor($00DDFBFA);
JvDefaultAvgLineColor = TColor($00EEDDDD);
JvDefaultDivisionLineColor = clLtGray; //NEW!
JvDefaultShadowColor = clDkGray; //NEW!
JvDefaultDivisionLineColor = clLtGray;
JvDefaultShadowColor = clDkGray;
JvDefaultPaperColor = clWhite;
JvDefaultYLegends = 20;
@ -749,12 +749,13 @@ type
procedure MyYHeader(ACanvas: TCanvas; StrText: string); // NEW
procedure MyHeaderFont(ACanvas: TCanvas);
procedure MyAxisFont(ACanvas: TCanvas);
procedure MyAxisTitleFont(ACanvas: TCanvas; Vertical: Boolean);
procedure MySmallGraphFont(ACanvas: TCanvas);
function MyTextHeight(ACanvas: TCanvas; StrText: string): Longint;
{ TEXTOUT stuff }
procedure MyRightTextOut(ACanvas: TCanvas; X, Y: Integer; const AText: string); // RIGHT TEXT
procedure MyCenterTextOut(ACanvas: TCanvas; X, Y: Integer; const AText: string); // CENTER TEXT
procedure MyLeftTextOut(ACanvas: TCanvas; X, Y: Integer; const AText: string); // LEFT ALIGN TEXT
procedure MyLeftTextOut(ACanvas: TCanvas; X, Y: Integer; const AText: string; Vertical: Boolean = false); // LEFT ALIGN TEXT
// Use HintColor:
procedure MyLeftTextOutHint(ACanvas: TCanvas; X, Y: Integer; const AText: string);
@ -808,6 +809,7 @@ type
procedure GraphYAxis;
procedure GraphYAxisDivisionMarkers;
procedure GraphXAxisDivisionMarkers; // new.
function CalcXAxisTextHeight: Integer; // calculate height of x axis labels and title;
procedure CalcYEnd; // Determine where the below-the bottom axis area starts
function GetChartCanvas(isFloating:Boolean): TCanvas; // Get Picture.Bitmap Canvas.
@ -987,6 +989,9 @@ const
DEFAULT_VALUE_COUNT = 100;
// By Default TJvChartData holds 100 values per pen. Grows autofragellisticexpialidociously. :-)
X_TITLE_LABEL_DISTANCE = 4;
TITLE_MARGIN = 4;
// NEW 2007:
// HELPER FUNCTIONS - NEW 2007
@ -1868,7 +1873,6 @@ begin
FLegendFont := TFont.Create;
FAxisFont := TFont.Create;
FAxisTitleFont := TFont.Create;
FAxisTitleFont.Orientation := 900;
//FShowLegend := True;
FMouseEdit := True;
@ -3785,11 +3789,11 @@ begin { Enough local functions for ya? -WP }
begin
MyHeaderFont(ACanvas);
// nOldY := Options.YStartOffset;
nMaxTextHeight := CanvasMaxTextHeight(ACanvas) + 8;
nMaxTextHeight := CanvasMaxTextHeight(ACanvas) + 2 * TITLE_MARGIN;
// Bump bottom margins if the fonts don't fit!
if Options.YStartOffset < 2 * nMaxTextHeight then
if Options.YStartOffset < nMaxTextHeight then
begin
Options.YStartOffset := nMaxTextHeight * 2;
Options.YStartOffset := nMaxTextHeight;
//Options.YEnd := Options.YEnd + (nOldY - Options.YStartOffset);
CalcYEnd;
Options.PrimaryYAxis.Normalize;
@ -3898,20 +3902,17 @@ end;
procedure TJvChart.DrawChartLegendBelow(ACanvas: TCanvas); {accidentally deleted during Jedi_new to Jedi_2009 branch. Restored by WP June 2009}
var
I,Y,nTextHeight:Integer;
BoxWidth:Integer;
LLabel:String;
I,Y,nTextHeight:Integer;
BoxWidth:Integer;
LLabel:String;
begin
if (Options.Legend <> clChartLegendBelow) then exit;
if (Options.Legend <> clChartLegendBelow) then exit;
if (Options.YStartOffset<=0) or (Options.XStartOffset<=0) then exit;
if (Options.YStartOffset<=0) or (Options.XStartOffset<=0) then exit;
// space-saving pen-legend below chart
MySmallGraphFont(ACanvas);
{10 % extra space for line height}
nTextHeight := Round(CanvasMaxTextHeight(ACanvas) * 1.01);
// space-saving pen-legend below chart
MySmallGraphFont(ACanvas);
nTextHeight := CanvasMaxTextHeight(ACanvas);
//BoxHeight := nTextHeight - 2;
@ -3922,7 +3923,7 @@ begin
if Options.GetPenMarkerKind(I) = pmkNone then
Continue; // Skip invisible pens.
Y := Options.YStartOffset + Options.YEnd + (nTextHeight div 2);
Y := Options.YStartOffset + Options.YEnd + X_TITLE_LABEL_DISTANCE; //(nTextHeight div 2);
// If chart has X legends:
if (Options.XLegends.Count > 0) or Options.XAxisDateTimeMode then
@ -3944,7 +3945,7 @@ begin
BoxWidth - 2, {width}
nTextHeight - 2, {height}
Options.FXLegendHoriz, {X=}
Y + 4); {Y=}
Y + 2); {Y=}
end;
//SetFontColor(ACanvas, jvChartAxisColorIndex); XXX
@ -3997,6 +3998,8 @@ var
{ draw x axis text at various alignments:}
function LeftXAxisText: Boolean;
var
Y: Integer;
begin
Result := True;
// Don't exceed right margin - causes some undesirable clipping. removed. -wpostma.
@ -4022,9 +4025,8 @@ var
begin
if Options.FXLegendHoriz < XOverlap then
Exit; // would overlap, don't draw it.
MyLeftTextOut(ACanvas, Options.FXLegendHoriz,
{bottom:}FXAxisPosition + Options.AxisLineWidth {top: Round(YTempOrigin - Options.PrimaryYAxis.YPixelGap)},
Options.XLegends[I]);
Y := FXAxisPosition + Options.AxisLineWidth div 2;
MyLeftTextOut(ACanvas, Options.FXLegendHoriz, Y, Options.XLegends[I]);
XOverlap := Options.FXLegendHoriz + ACanvas.TextWidth(Options.XLegends[I]);
end
else
@ -4032,6 +4034,8 @@ var
end;
function RightXAxisText: Boolean;
var
Y: Integer;
begin
Result := True;
// Label X axis above or below?
@ -4039,17 +4043,18 @@ var
begin
if I < Options.XLegends.Count then // fix exception. June 23, 2004- WPostma.
MyRightTextOut(ACanvas, Options.FXLegendHoriz, Options.YEnd + 3, Options.XLegends[I])
end
else
end else
if I < Options.XLegends.Count then
MyRightTextOut(ACanvas, Options.FXLegendHoriz,
{bottom:}FXAxisPosition + Options.AxisLineWidth {top: Round(YTempOrigin - Options.PrimaryYAxis.YPixelGap)},
Options.XLegends[I])
else
begin
Y := FXAxisPosition + Options.AxisLineWidth div 2;
MyRightTextOut(ACanvas, Options.FXLegendHoriz, Y, Options.XLegends[I]);
end else
Result := False;
end;
function CenterXAxisText: Boolean;
var
Y: Integer;
begin
Result := True;
// Label X axis above or below?
@ -4060,16 +4065,17 @@ var
end
else
if I < Options.XLegends.Count then
MyCenterTextOut(ACanvas, Options.FXLegendHoriz,
{bottom:}FXAxisPosition + Options.AxisLineWidth {top: Round(YTempOrigin - Options.PrimaryYAxis.YPixelGap)},
Options.XLegends[I])
else
begin
Y := FXAxisPosition + Options.AxisLineWidth div 2;
MyCenterTextOut(ACanvas, Options.FXLegendHoriz, Y, Options.XLegends[I]);
end else
Result := False;
end;
procedure XAxisDateTimeModeLabels1; // Classic mode [REFACTORED 2007]
var
L: Integer;
Y: Integer;
begin
// classic JvChart XAxisDateTime mode labels painting code.
@ -4095,10 +4101,8 @@ var
// Check if writing this label would collide with previous label, if not, plot it
if (Options.FXLegendHoriz - (ACanvas.TextWidth(TimestampStr) div 2)) > XOverlap then
begin
MyCenterTextOut(ACanvas, Options.FXLegendHoriz,
{bottom:}FXAxisPosition + Options.AxisLineWidth
{top: Round(YTempOrigin - Options.PrimaryYAxis.YPixelGap)},
TimestampStr);
Y := FXAxisPosition + Options.AxisLineWidth div 2;
MyCenterTextOut(ACanvas, Options.FXLegendHoriz, Y, TimeStampStr);
// draw a ticky-boo (technical term used by scientists the world over)
// so that we can see where on the chart the X axis datetime is pointing to.
@ -4119,7 +4123,7 @@ var
procedure XAxisDateTimeModeLabels2; // [NEW 2007]
var
L: Integer;
X: Integer;
X, Y: Integer;
DivPixels: Integer;
TextWidth: Integer;
Modn: Integer;
@ -4158,9 +4162,8 @@ var
if X = Options.XStartOffset then
Continue; // don't draw dotted line right at X Axis.
MyCenterTextOut(ACanvas, X,
{bottom:}FXAxisPosition + Options.AxisLineWidth,
TimestampStr);
Y := FXAxisPosition + Options.AxisLineWidth div 2;
MyCenterTextOut(ACanvas, X, Y, TimeStampStr);
ACanvas.Pen.Color := Options.GetPenColor(jvChartDivisionLineColorIndex);
MyDrawDotLine(ACanvas, X, Options.YStartOffset + 1, X, FXAxisPosition - 1);
@ -4169,8 +4172,8 @@ var
procedure DefaultXAxisLegendMode;
var
count:Integer;
K:Integer;
count: Integer;
K: Integer;
begin
{default X axis legend mode: use text legends}
if Options.FXAxisLegendSkipBy < 1 then
@ -4185,12 +4188,9 @@ var
Options.FXLegendHoriz := Round(Options.XStartOffset + Options.XPixelGap * I );
case Options.FXAxisLabelAlignment of
taLeftJustify:
if not leftXAxisText then break;
taRightJustify:
if not rightXAxisText then break;
taCenter:
if not centerXAxisText then break;
taLeftJustify: if not leftXAxisText then break;
taRightJustify: if not rightXAxisText then break;
taCenter: if not centerXAxisText then break;
end;
end; {for K}
end; {default mode}
@ -4457,6 +4457,27 @@ begin
Result := Self.Height;
end;
function TJvChart.CalcXAxisTextHeight: Integer;
var
lCanvas: TCanvas;
begin
lCanvas := GetChartCanvas(false);
Result := TITLE_MARGIN;
if FOptions.XLegends.Count > 0 then
begin
MyAxisFont(lCanvas);
Result := Result + lCanvas.TextHeight('Tg')
end;
if FOptions.XAxisHeader <> '' then
begin
MyAxisTitleFont(lCanvas, false);
Result := Result + lCanvas.TextHeight('Tg') + X_TITLE_LABEL_DISTANCE;
end;
end;
procedure TJvChart.CalcYEnd;
var
aHeight: Integer;
@ -4468,7 +4489,8 @@ begin
aHeight := FBitmap.Height;
end;
Options.YEnd := aHeight - 2 * Options.YStartOffset; {canvas size, excluding margin}
// Options.YEnd := aHeight - 2 * Options.YStartOffset; {canvas size, excluding margin}
Options.YEnd := aHeight - Options.YStartOffset - CalcXAxisTextHeight;
end;
@ -4588,9 +4610,11 @@ begin
if StrText = '' then
exit;
H := ACanvas.TextHeight(StrText);
MyAxisFont(ACanvas);
Y := Options.YStartOffset + Options.YEnd + Round(1.6 * H);
H := ACanvas.TextHeight(StrText); // Height of labels
MyAxisTitleFont(ACanvas, false);
Y := Options.YStartOffset + Options.YEnd + H + X_TITLE_LABEL_DISTANCE;
if Options.Legend = clChartLegendBelow then
begin
{ left aligned X Axis Title, right after the legend itself}
@ -4611,17 +4635,19 @@ var
begin
if Length(StrText) = 0 then
Exit;
ACanvas.Brush.Color := Color;
ACanvas.Font.Assign(FOptions.AxisTitleFont);
MyAxisTitleFont(ACanvas, true);
if Options.XStartOffset > 10 then
begin
WD := ACanvas.TextWidth(StrText);
//Vert := Options.YStartOffset + WD; // top-aligned
Vert := Max(0, Options.YStartOffset + (Options.YEnd + WD) div 2); // centered
Horiz := 2;
MyLeftTextOut(ACanvas, Horiz, Vert, StrText);
MyLeftTextOut(ACanvas, Horiz, Vert, StrText, true);
end;
MyAxisFont(ACanvas);
// MyAxisFont(ACanvas);
end;
@ -5427,7 +5453,7 @@ begin
MyHeaderFont(ACanvas);
MyCenterTextOut(ACanvas,
(Options.XStartOffset + Round(Options.XEnd)) div 2,
(Options.YStartOffset - MyTextHeight(ACanvas, StrText)) div 2,
TITLE_MARGIN,
StrText
);
MyAxisFont(ACanvas);
@ -5449,6 +5475,19 @@ begin
ACanvas.Font.Assign(Options.AxisFont);
end;
procedure TJvChart.MyAxisTitleFont(ACanvas: TCanvas; Vertical: Boolean);
const
ORIENTATION: Array[boolean] of Integer = (0, 900);
begin
Assert(Assigned(ACanvas));
Assert(Assigned(ACanvas.Brush));
Assert(Assigned(ACanvas.Font));
Assert(Assigned(Options));
ACanvas.Brush.Color := Options.PaperColor; // was hard coded to clWhite.
ACanvas.Font.Assign(Options.AxisTitleFont);
ACanvas.Font.Orientation := ORIENTATION[Vertical];
end;
(*
{ !!warning: uses Win32 only font-handle stuff!!}
@ -5498,11 +5537,20 @@ end;
{ Text Left Aligned to X,Y boundary }
procedure TJvChart.MyLeftTextOut(ACanvas: TCanvas; X, Y: Integer; const AText: string);
procedure TJvChart.MyLeftTextOut(ACanvas: TCanvas; X, Y: Integer;
const AText: string; Vertical: Boolean = false);
begin
Assert(Assigned(ACanvas));
Assert(Assigned(ACanvas.Brush));
ACanvas.Brush.Color := Options.PaperColor; // non default paper color.
{$IFDEF TEXT_BOX}
ACanvas.Brush.Style := bsSolid;
if Vertical then
ACanvas.Rectangle(X, Y, X + ACanvas.TextHeight(AText), Y - ACanvas.TextWidth(AText))
else
ACanvas.Rectangle(X, Y, X + ACanvas.TextWidth(AText), Y + ACanvas.TextHeight(AText));
ACanvas.Brush.Style := bsClear;
{$ENDIF}
ACanvas.TextOut(X, Y + 1, AText);
end;
@ -5511,6 +5559,11 @@ begin
Assert(Assigned(ACanvas));
Assert(Assigned(ACanvas.Brush));
ACanvas.Brush.Color := Options.HintColor;
{$IFDEF TEXT_BOX}
ACanvas.Brush.Style := bsSolid;
ACanvas.Rectangle(X, Y, X + ACanvas.TextWidth(AText), Y + ACanvas.TextHeight(AText));
ACanvas.Brush.Style := bsClear;
{$ENDIF}
ACanvas.TextOut(X, Y + 1, AText);
end;
@ -5519,7 +5572,14 @@ begin
Assert(Assigned(ACanvas));
Assert(Assigned(ACanvas.Brush));
ACanvas.Brush.Color := Options.PaperColor; // non default paper color.
ACanvas.TextOut(X - Round(ACanvas.TextWidth(AText) / 2), Y + 1, AText);
X := X - ACanvas.TextWidth(AText) div 2;
Y := Y + 1;
{$IFDEF TEXT_BOX}
ACanvas.Brush.Style := bsSolid;
ACanvas.Rectangle(X, Y, X + ACanvas.TextWidth(AText), Y + ACanvas.TextHeight(AText));
ACanvas.Brush.Style := bsClear;
{$ENDIF}
ACanvas.TextOut(X, Y, AText);
end;
procedure TJvChart.MyRightTextOut(ACanvas: TCanvas; X, Y: Integer; const AText: string);
@ -5527,11 +5587,14 @@ begin
Assert(Assigned(ACanvas));
Assert(Assigned(ACanvas.Brush));
ACanvas.Brush.Color := Options.PaperColor; // non default paper color.
ACanvas.TextOut(
X - ACanvas.TextWidth(AText),
Y - Round(ACanvas.TextHeight(AText) / 2),
AText
);
X := X - ACanvas.TextWidth(AText);
Y := Y - ACanvas.TextHeight(AText) div 2;
{$IFDEF TEXT_BOX}
ACanvas.Brush.Style := bsSolid;
ACanvas.Rectangle(X, Y, X + ACanvas.TextWidth(AText), Y + ACanvas.TextHeight(AText));
ACanvas.Brush.Style := bsClear;
{$ENDIF}
ACanvas.TextOut(X, Y, AText);
end;
procedure TJvChart.MyRectangle(ACanvas: TCanvas; X, Y, X2, Y2: Integer);