lazarus/components/tachart/demo/barseriestools/main.pas

219 lines
6.1 KiB
ObjectPascal

unit main;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, FileUtil, TAGraph, TASeries, TASources, TATools, Forms,
Controls, Graphics, Dialogs, StdCtrls, ComCtrls, ExtCtrls, Types,
TAChartUtils, TACustomSeries, TAStyles, TADataTools;
type
{ TMainForm }
TMainForm = class(TForm)
CalculatedChartSource: TCalculatedChartSource;
Chart: TChart;
BarSeriesREDYELLOW: TBarSeries;
BarSeriesBLUE: TBarSeries;
ChartStyles: TChartStyles;
ChartToolset: TChartToolset;
DataPointDragTool: TDataPointDragTool;
DataPointClickTool: TDataPointClickTool;
DataPointHintTool: TDataPointHintTool;
CbHorizontal: TCheckBox;
Cb100Percent: TCheckBox;
LblToolTargets: TLabel;
LblInfo: TLabel;
ListChartSourceLABELS: TListChartSource;
ListChartSourceREDYELLOW: TListChartSource;
ListChartSourceBLUE: TListChartSource;
Log: TMemo;
ToolInfoPanel: TPanel;
TargetPanel: TPanel;
LeftPanel: TPanel;
RbToolTargetDataPoint: TRadioButton;
RbToolTargetBar: TRadioButton;
LogSplitter: TSplitter;
procedure DataPointClickToolPointClick(ATool: TChartTool;
{%H-}APoint: TPoint);
procedure DataPointDragToolBeforeMouseDown(ATool: TChartTool; {%H-}APoint: TPoint);
procedure DataPointDragToolDrag(ASender: TDataPointDragTool;
var AGraphPoint: TDoublePoint);
procedure DataPointHintToolHint(ATool: TDataPointHintTool;
const {%H-}APoint: TPoint; var AHint: String);
procedure CbHorizontalChange(Sender: TObject);
procedure Cb100PercentChange(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure ToolTargetChanged(Sender: TObject);
private
public
end;
var
MainForm: TMainForm;
implementation
{$R *.lfm}
uses
LCLType;
{ TMainForm }
{ Flip x and y axes of the chart }
procedure TMainForm.CbHorizontalChange(Sender: TObject);
begin
if CbHorizontal.Checked then
begin
TChartSeries(Chart.Series[0]).AxisIndexX := 0;
TChartSeries(Chart.Series[0]).AxisIndexY := 1;
TChartSeries(Chart.Series[1]).AxisIndexX := 0;
TChartSeries(Chart.Series[1]).AxisIndexY := 1;
Chart.LeftAxis.Marks.Source := ListChartSourceLABELS;
Chart.LeftAxis.Marks.Style := smsLabel;
Chart.BottomAxis.Marks.Source := nil;
Chart.BottomAxis.Marks.Style := smsValue;
Chart.Margins.Left := 0;
Chart.Margins.Bottom := 4;
end else
begin
TChartSeries(Chart.Series[0]).AxisIndexX := 1;
TChartSeries(Chart.Series[0]).AxisIndexY := 0;
TChartSeries(Chart.Series[1]).AxisIndexX := 1;
TChartSeries(Chart.Series[1]).AxisIndexY := 0;
Chart.BottomAxis.Marks.Source := ListChartSourceLABELS;
Chart.BottomAxis.Marks.Style := smsLabel;
Chart.LeftAxis.Marks.Source := nil;
Chart.LeftAxis.Marks.Style := smsValue;
Chart.Margins.Bottom := 0;
Chart.Margins.Left := 4;
end;
end;
{ Normalize the stacked bars to 100% }
procedure TMainForm.Cb100PercentChange(Sender: TObject);
begin
if Cb100Percent.Checked then
BarSeriesREDYELLOW.Source := CalculatedChartSource
else
BarSeriesREDYELLOW.Source := ListChartSourceREDYELLOW;
end;
{ Every click detected by the DatapointClickTool creates an entry in the
log memo }
procedure TMainForm.DataPointClickToolPointClick(ATool: TChartTool;
APoint: TPoint);
var
ser: TChartSeries;
idx: Integer;
yidx: Integer;
ttl: String;
begin
with TDatapointClickTool(ATool) do begin
ser := Series as TChartSeries;
idx := PointIndex;
yidx := YIndex;
end;
if ser <> nil then begin
ttl := ser.Title;
if yidx > 0 then
ttl := TBarSeries(ser).Styles.Styles[yidx].Text;
Log.Lines.Add(Format('"%s" clicked:', [ttl]));
Log.Lines.Add(Format(' point #%d, x = %.1f (%s), y = %.1f',
[ idx, ser.GetXValue(idx), ListChartSourceLABELS.Item[idx]^.Text,
ser.Source[idx]^.GetY(yidx) ]
));
Log.SelStart := Length(Log.Lines.Text);
end;
end;
{ Prevent an exception if the DragTool wants to change the non-editable
calculated chart source }
procedure TMainForm.DataPointDragToolBeforeMouseDown(ATool: TChartTool;
APoint: TPoint);
begin
if Cb100Percent.Checked then begin
ShowMessage('Please uncheck the 100% checkbox.');
ATool.Handled;
end;
end;
{ Make sure to keep x value fixed (or y value, if series is rotated) }
procedure TMainForm.DataPointDragToolDrag(ASender: TDataPointDragTool;
var AGraphPoint: TDoublePoint);
var
ser: TChartSeries;
begin
ser := TChartSeries(ASender.Series);
if ser.IsRotated then
AGraphPoint.Y := ASender.Origin.Y
else
AGraphPoint.X := ASender.Origin.X;
end;
{ Prepare the text for the hint popup window of the DataPointHintTool }
procedure TMainForm.DataPointHintToolHint(ATool: TDataPointHintTool;
const APoint: TPoint; var AHint: String);
var
ser: TChartSeries;
idx: Integer;
yidx: Integer;
ttl: String;
begin
with TDatapointHintTool(ATool) do begin
ser := Series as TChartSeries;
idx := PointIndex;
yidx := YIndex;
end;
if ser <> nil then begin
if yidx > 0 then
ttl := TBarSeries(ser).Styles.Styles[yidx].Text else
ttl := ser.Title;
AHint := Format(
'Mouse over "%s": point #%d, x value %.1f (%s), y value %.1f',
[ ttl, idx, ser.GetXValue(idx), ListChartSourceLABELS.Item[idx]^.Text,
ser.Source[idx]^.GetY(yidx) ]
);
end else
AHint := '';
end;
procedure TMainForm.FormCreate(Sender: TObject);
var
i: Integer;
begin
for i:=0 to 5 do begin
ListChartSourceRedYellow.AddXYList(i, [random*50, random*60]);
ListChartSourceBlue.Add(i, Random*80);
ListChartSourceLABELS.Add(i, i, char(ord('A') + i));
end;
CbHorizontalChange(nil);
end;
{ Change the clicking behavior of the click and hint tools by modifying their
Targets. }
procedure TMainForm.ToolTargetChanged(Sender: TObject);
begin
if Sender = RbToolTargetDatapoint then begin
DataPointClickTool.Targets := DataPointClickTool.Targets - [nptCustom];
DataPointHintTool.Targets := DatapointHintTool.Targets - [nptCustom];
end else
if Sender = RbToolTargetBar then begin
DataPointClickTool.Targets := DataPointClickTool.Targets + [nptCustom];
DataPointHintTool.Targets := DatapointHintTool.Targets + [nptCustom];
end;
end;
end.