mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-07 06:38:06 +02:00
TAChart: Add TChartListbox by Werner Pamler
git-svn-id: trunk@31630 -
This commit is contained in:
parent
afebc43889
commit
2d6a277be3
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -2571,6 +2571,7 @@ components/tachart/icons/tcalculatedchartsource.png -text svneol=unset#images/pn
|
||||
components/tachart/icons/tchart.png -text svneol=unset#images/png
|
||||
components/tachart/icons/tchartaxistransformations.png -text svneol=unset#images/png
|
||||
components/tachart/icons/tchartlegendpanel.png -text
|
||||
components/tachart/icons/tchartlistbox.png -text svneol=unset#images/png
|
||||
components/tachart/icons/tchartnavpanel.png -text svneol=unset#images/png
|
||||
components/tachart/icons/tchartnavscrollbar.png -text svneol=unset#images/png
|
||||
components/tachart/icons/tchartstyles.png -text svneol=unset#images/png
|
||||
@ -2595,6 +2596,7 @@ components/tachart/tachartfpvectorial.lpk svneol=native#text/plain
|
||||
components/tachart/tachartfpvectorial.pas svneol=native#text/pascal
|
||||
components/tachart/tachartlazaruspkg.lpk svneol=native#text/plain
|
||||
components/tachart/tachartlazaruspkg.pas svneol=native#text/plain
|
||||
components/tachart/tachartlistbox.pas svneol=native#text/pascal
|
||||
components/tachart/tachartprint.lpk svneol=native#text/plain
|
||||
components/tachart/tachartprint.pas svneol=native#text/pascal
|
||||
components/tachart/tachartutils.pas svneol=native#text/plain
|
||||
|
BIN
components/tachart/icons/tchartlistbox.png
Normal file
BIN
components/tachart/icons/tchartlistbox.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 880 B |
@ -30,7 +30,7 @@
|
||||
for details about the copyright.
|
||||
"/>
|
||||
<Version Major="1"/>
|
||||
<Files Count="28">
|
||||
<Files Count="29">
|
||||
<Item1>
|
||||
<Filename Value="tagraph.pas"/>
|
||||
<HasRegisterProc Value="True"/>
|
||||
@ -155,6 +155,11 @@
|
||||
<Filename Value="tachartaxisutils.pas"/>
|
||||
<UnitName Value="TAChartAxisUtils"/>
|
||||
</Item28>
|
||||
<Item29>
|
||||
<Filename Value="tachartlistbox.pas"/>
|
||||
<HasRegisterProc Value="True"/>
|
||||
<UnitName Value="tachartlistbox"/>
|
||||
</Item29>
|
||||
</Files>
|
||||
<LazDoc Paths="$(LazarusDir)\components\tachart\fpdoc"/>
|
||||
<Type Value="RunAndDesignTime"/>
|
||||
|
@ -12,7 +12,7 @@ uses
|
||||
TATypes, TADrawUtils, TAMultiSeries, TALegend, TAStyles, TAFuncSeries,
|
||||
TALegendPanel, TARadialSeries, TACustomSource, TAGeometry, TANavigation,
|
||||
TADrawerCanvas, TADrawerSVG, TAIntervalSources, TAChartAxisUtils,
|
||||
LazarusPackageIntf;
|
||||
TAChartListbox, LazarusPackageIntf;
|
||||
|
||||
implementation
|
||||
|
||||
@ -28,6 +28,7 @@ begin
|
||||
RegisterUnit('TALegendPanel', @TALegendPanel.Register);
|
||||
RegisterUnit('TANavigation', @TANavigation.Register);
|
||||
RegisterUnit('TAIntervalSources', @TAIntervalSources.Register);
|
||||
RegisterUnit('TAChartListbox', @TAChartListbox.Register);
|
||||
end;
|
||||
|
||||
initialization
|
||||
|
613
components/tachart/tachartlistbox.pas
Normal file
613
components/tachart/tachartlistbox.pas
Normal file
@ -0,0 +1,613 @@
|
||||
{
|
||||
/***************************************************************************
|
||||
TAChartListbox.pas
|
||||
------------------
|
||||
Component Library Standard Graph Listbox
|
||||
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
*****************************************************************************
|
||||
* *
|
||||
* See the file COPYING.modifiedLGPL.txt, included in this distribution, *
|
||||
* for details about the copyright. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
||||
* *
|
||||
*****************************************************************************
|
||||
|
||||
Authors: Werner Pamler, Alexander Klenin
|
||||
|
||||
Usage:
|
||||
- Add the ChartListbox to a form with a TChart
|
||||
- Connect the chart to the listbox by setting the chart property of the
|
||||
TChartlistbox. The ChartListbox will be populated with the series in the
|
||||
chart und will automatically track changes of the series.
|
||||
- Check/uncheck series in the ChartListbox to show/hide them in the chart.
|
||||
As usual, checking is done by mouse clicks or by pressing the space bar.
|
||||
- Play with the properties to modify the standard behavior, e.g. set
|
||||
CheckStyle to cbsRadioButton in order to get a radiobutton behavior, i.e. to
|
||||
allow only one visible series.
|
||||
}
|
||||
|
||||
unit TAChartListbox;
|
||||
|
||||
{$mode objfpc}{$H+}
|
||||
|
||||
interface
|
||||
|
||||
uses
|
||||
Classes, Controls, SysUtils, LCLType, StdCtrls,
|
||||
TAChartUtils, TACustomSeries, TALegend, TAGraph;
|
||||
|
||||
type
|
||||
TChartListboxIndexEvent = procedure(Sender:TObject; Index:integer) of object;
|
||||
|
||||
TCheckBoxesStyle = (cbsCheckbox, cbsRadiobutton);
|
||||
|
||||
TChartListbox = class(TCustomListbox)
|
||||
private
|
||||
FChart : TChart;
|
||||
FListener : TListener;
|
||||
FLegendItems : TChartLegendItems;
|
||||
FShowSeriesIcons : boolean;
|
||||
FShowCheckboxes : boolean;
|
||||
FCheckStyle : TCheckBoxesStyle;
|
||||
FLockCount : integer;
|
||||
FSeriesIconClicked : integer;
|
||||
FOnCheckboxClick : TChartListboxIndexEvent;
|
||||
FOnSeriesIconClick : TChartListboxIndexEvent;
|
||||
FOnItemClick : TChartListboxIndexEvent;
|
||||
FOnPopulate : TNotifyEvent;
|
||||
function GetChecked(AIndex:integer) : boolean;
|
||||
function GetLegendItem(AIndex:integer) : TLegendItem;
|
||||
function GetSeries(AIndex:integer) : TCustomChartSeries;
|
||||
function GetSeriesCount : integer;
|
||||
procedure SeriesChanged(ASender:TObject);
|
||||
procedure SetChart(AValue:TChart);
|
||||
procedure SetChecked(AIndex:integer; AValue:boolean);
|
||||
procedure SetCheckStyle(AValue:TCheckBoxesStyle);
|
||||
procedure SetShowCheckboxes(AValue:boolean);
|
||||
procedure SetShowSeriesIcons(AValue:boolean);
|
||||
|
||||
protected
|
||||
procedure CalcRects(const AItemRect:TRect; out CheckboxRect,SeriesIconRect: TRect);
|
||||
procedure ClickedCheckbox(AIndex:integer); virtual;
|
||||
procedure ClickedItem(AIndex:integer); virtual;
|
||||
procedure ClickedSeriesIcon(AIndex:integer); virtual;
|
||||
function CreateLegendItems : TChartLegendItems;
|
||||
procedure DblClick; override;
|
||||
procedure DrawItem(Index: Integer; ARect: TRect; AState: TOwnerDrawState); override;
|
||||
function FirstCheckedIndex : integer;
|
||||
function IsLocked : boolean;
|
||||
procedure KeyDown(var Key: Word; Shift: TShiftState); override;
|
||||
procedure Lock;
|
||||
procedure MouseDown(AButton: TMouseButton; AShift: TShiftState; AX, AY: Integer); override;
|
||||
procedure Notification(AComponent: TComponent; AOperation: TOperation); override;
|
||||
procedure Populate;
|
||||
procedure Unlock;
|
||||
|
||||
public
|
||||
constructor Create(AOwner:TComponent); override;
|
||||
destructor Destroy; override;
|
||||
function FindSeriesIndex(ASeries:TCustomChartSeries) : integer;
|
||||
procedure MeasureItem(Index: Integer; var AHeight: Integer); override;
|
||||
procedure RemoveSeries(ASeries:TCustomChartSeries);
|
||||
property Checked[AIndex:integer] : boolean read GetChecked write SetChecked;
|
||||
property Series[AIndex:integer] : TCustomChartSeries read GetSeries;
|
||||
property SeriesCount : integer read GetSeriesCount;
|
||||
|
||||
published
|
||||
property Chart : TChart
|
||||
read FChart write SetChart;
|
||||
property CheckStyle : TCheckBoxesStyle
|
||||
read FCheckStyle write SetCheckStyle default cbsCheckbox;
|
||||
property ShowCheckboxes : boolean
|
||||
read FShowCheckboxes write SetShowCheckboxes default true;
|
||||
property ShowSeriesIcons : boolean
|
||||
read FShowSeriesIcons write SetShowSeriesIcons default true;
|
||||
property OnCheckboxClick : TChartListboxIndexEvent
|
||||
read FOnCheckboxClick write FOnCheckboxClick;
|
||||
property OnItemClick : TChartListboxIndexEvent
|
||||
read FOnItemClick write FOnItemClick;
|
||||
property OnSeriesIconClick : TChartListboxIndexEvent
|
||||
read FOnSeriesIconClick write FOnSeriesIconClick;
|
||||
property OnPopulate : TNotifyEvent
|
||||
read FOnPopulate write FOnPopulate;
|
||||
|
||||
property Align;
|
||||
// property AllowGrayed;
|
||||
property Anchors;
|
||||
property BidiMode;
|
||||
property BorderSpacing;
|
||||
property BorderStyle;
|
||||
property Color;
|
||||
property Columns;
|
||||
property Constraints;
|
||||
property DragCursor;
|
||||
property DragMode;
|
||||
property ExtendedSelect;
|
||||
property Enabled;
|
||||
property Font;
|
||||
property IntegralHeight;
|
||||
// property Items;
|
||||
property ItemHeight;
|
||||
property MultiSelect;
|
||||
property OnChangeBounds;
|
||||
property OnClick;
|
||||
// property OnClickCheck;
|
||||
property OnContextPopup;
|
||||
property OnDblClick;
|
||||
property OnDrawItem;
|
||||
property OnDragDrop;
|
||||
property OnDragOver;
|
||||
property OnEndDrag;
|
||||
property OnEnter;
|
||||
property OnExit;
|
||||
// property OnItemClick;
|
||||
property OnKeyPress;
|
||||
property OnKeyDown;
|
||||
property OnKeyUp;
|
||||
property OnMouseMove;
|
||||
property OnMouseDown;
|
||||
property OnMouseUp;
|
||||
property OnMouseEnter;
|
||||
property OnMouseLeave;
|
||||
property OnMouseWheel;
|
||||
property OnMouseWheelDown;
|
||||
property OnMouseWheelUp;
|
||||
property OnResize;
|
||||
property OnShowHint;
|
||||
property OnStartDrag;
|
||||
property OnUTF8KeyPress;
|
||||
property ParentBidiMode;
|
||||
property ParentFont;
|
||||
property ParentShowHint;
|
||||
property PopupMenu;
|
||||
property ShowHint;
|
||||
property Sorted;
|
||||
// property Style;
|
||||
property TabOrder;
|
||||
property TabStop;
|
||||
property TopIndex;
|
||||
property Visible;
|
||||
end;
|
||||
|
||||
procedure Register;
|
||||
|
||||
|
||||
implementation
|
||||
|
||||
uses
|
||||
math, LCLIntf, Themes, TAGeometry, TADrawUtils, TADrawerCanvas;
|
||||
|
||||
procedure Register;
|
||||
begin
|
||||
RegisterComponents(CHART_COMPONENT_IDE_PAGE, [TChartListbox]);
|
||||
end;
|
||||
|
||||
constructor TChartListbox.Create(AOwner:TComponent);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
Style := lbOwnerDrawFixed;
|
||||
FListener := TListener.Create(@FChart, @SeriesChanged);
|
||||
FShowSeriesIcons := true;
|
||||
FShowCheckboxes := true;
|
||||
end;
|
||||
|
||||
destructor TChartListbox.Destroy;
|
||||
begin
|
||||
FreeAndNil(FListener);
|
||||
FreeAndNil(FLegendItems);
|
||||
inherited Destroy;
|
||||
end;
|
||||
|
||||
procedure TChartListbox.CalcRects(const AItemRect:TRect;
|
||||
out CheckboxRect,SeriesIconRect: TRect);
|
||||
{ based on the rect of a listbox item, calculates the locations of the
|
||||
checkbox and of the series icon }
|
||||
var
|
||||
w, x: integer;
|
||||
begin
|
||||
CheckBoxRect := Rect(-1, -1, -1, -1);
|
||||
SeriesIconRect := Rect(-1, -1, -1, -1);
|
||||
w := GetSystemMetrics(SM_CYMENUCHECK);
|
||||
x := 2;
|
||||
if FShowCheckboxes then begin
|
||||
CheckboxRect := Bounds(AItemRect.Left+1, AItemRect.Top+1, w, w);
|
||||
if FShowSeriesIcons then
|
||||
inc(x, CheckboxRect.Right);
|
||||
end else begin
|
||||
if FShowSeriesIcons then
|
||||
inc(x, AItemRect.Left);
|
||||
end;
|
||||
if FShowSeriesIcons then
|
||||
SeriesIconRect := Rect(x, AItemRect.Top+2, x+FChart.Legend.SymbolWidth, AItemRect.Bottom-2);
|
||||
end;
|
||||
|
||||
procedure TChartListbox.ClickedCheckbox(AIndex:integer);
|
||||
begin
|
||||
Checked[AIndex] := not Checked[AIndex];
|
||||
if Assigned(OnCheckboxClick) then
|
||||
OnCheckboxClick(self, AIndex);
|
||||
end;
|
||||
|
||||
procedure TChartListbox.ClickedItem(AIndex:integer);
|
||||
begin
|
||||
if Assigned(OnItemClick) then
|
||||
OnItemClick(self, AIndex);
|
||||
end;
|
||||
|
||||
procedure TChartListbox.ClickedSeriesIcon(AIndex:integer);
|
||||
begin
|
||||
if Assigned(OnSeriesIconClick) then
|
||||
OnSeriesIconClick(self, AIndex);
|
||||
end;
|
||||
|
||||
function TChartListbox.CreateLegendItems : TChartLegendItems;
|
||||
{ creates the a TLegendItems list and populates it with information for
|
||||
all series contained in the Chart. In case of MultiLegend items, only
|
||||
a single legend item is used }
|
||||
var
|
||||
i : integer;
|
||||
j : integer = MaxInt;
|
||||
begin
|
||||
result := TChartLegendItems.Create;
|
||||
try
|
||||
if FChart <> nil then
|
||||
for i:=0 to FChart.SeriesCount-1 do begin
|
||||
if (FChart.Series[i] is TCustomChartSeries) then begin
|
||||
TCustomChartSeries(FChart.Series[i]).GetSingleLegendItem(result);
|
||||
result[i].Owner := FChart.Series[i];
|
||||
end;
|
||||
end;
|
||||
for i := Result.Count - 1 downto 0 do
|
||||
if Result[i].Order = LEGEND_ITEM_ORDER_AS_ADDED then begin
|
||||
Result[i].Order := j;
|
||||
j -= 1;
|
||||
end;
|
||||
except
|
||||
FreeAndNil(Result);
|
||||
raise;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TChartListbox.DblClick;
|
||||
begin
|
||||
inherited DblClick;
|
||||
if (FSeriesIconClicked <> -1) then
|
||||
ClickedSeriesIcon(FSeriesIconClicked);
|
||||
end;
|
||||
|
||||
procedure TChartListbox.DrawItem(Index: Integer; ARect: TRect;
|
||||
AState: TOwnerDrawState);
|
||||
{ draws the listbox item }
|
||||
const
|
||||
IsChecked : array[TCheckboxesStyle, Boolean] of integer = (
|
||||
(DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED),
|
||||
(DFCS_BUTTONRADIO, DFCS_BUTTONRADIO or DFCS_CHECKED)
|
||||
);
|
||||
var
|
||||
id : IChartDrawer;
|
||||
Rcb, Ricon: TRect;
|
||||
te : TThemedElementDetails;
|
||||
x : integer;
|
||||
begin
|
||||
Unused(AState);
|
||||
|
||||
if FChart = nil then
|
||||
exit;
|
||||
|
||||
CalcRects(ARect, Rcb, Ricon);
|
||||
|
||||
if FShowCheckboxes then begin
|
||||
if ThemeServices.ThemesEnabled then begin
|
||||
case FCheckStyle of
|
||||
cbsCheckbox :
|
||||
if Checked[Index] then
|
||||
te := ThemeServices.GetElementDetails(tbCheckBoxCheckedNormal)
|
||||
else
|
||||
te := ThemeServices.GetElementDetails(tbCheckBoxUncheckedNormal);
|
||||
cbsRadioButton :
|
||||
if Checked[Index] then
|
||||
te := ThemeServices.GetElementDetails(tbRadioButtonCheckedNormal)
|
||||
else
|
||||
te := ThemeServices.GetElementDetails(tbRadioButtonUnCheckedNormal);
|
||||
end;
|
||||
ThemeServices.DrawElement(Canvas.Handle, te, Rcb);
|
||||
end else
|
||||
DrawFrameControl(Canvas.Handle, Rcb, DFC_BUTTON, IsChecked[FCheckStyle, Checked[Index]]);
|
||||
x := Rcb.Right;
|
||||
end else
|
||||
x := ARect.Left;
|
||||
|
||||
if FShowSeriesIcons then begin
|
||||
id := TCanvasDrawer.Create(Canvas);
|
||||
id.Pen := Chart.Legend.SymbolFrame;
|
||||
FLegendItems[Index].Draw(id, Ricon);
|
||||
end else
|
||||
Canvas.TextOut(x+2, ARect.Top, FLegendItems.Items[Index].Text);
|
||||
end;
|
||||
|
||||
function TChartListbox.FindSeriesIndex(ASeries:TCustomChartSeries) : integer;
|
||||
{ searches the internal legend items list for the specified series }
|
||||
var
|
||||
i : integer;
|
||||
ser : TBasicChartSeries;
|
||||
begin
|
||||
for i:=0 to FLegendItems.Count-1 do begin
|
||||
ser := GetSeries(i);
|
||||
if ser = ASeries then begin
|
||||
result := i;
|
||||
exit;
|
||||
end;
|
||||
end;
|
||||
result := -1;
|
||||
end;
|
||||
|
||||
function TChartListbox.FirstCheckedIndex : integer;
|
||||
{ Returns the index of the first listbox series that is active }
|
||||
var
|
||||
i : integer;
|
||||
begin
|
||||
for i:=0 to FLegendItems.Count-1 do
|
||||
if Checked[i] then begin
|
||||
result := i;
|
||||
exit;
|
||||
end;
|
||||
result := -1;
|
||||
end;
|
||||
|
||||
function TChartListbox.GetChecked(AIndex:integer) : boolean;
|
||||
{ report the checked status. This is determined by the visibility of the
|
||||
series with the given index. }
|
||||
var
|
||||
ser : TBasicChartSeries;
|
||||
begin
|
||||
ser := GetSeries(AIndex);
|
||||
result := ser.Active;
|
||||
end;
|
||||
|
||||
function TChartListbox.GetLegendItem(AIndex:integer) : TLegendItem;
|
||||
begin
|
||||
result := FLegendItems[AIndex];
|
||||
end;
|
||||
|
||||
function TChartListbox.GetSeries(AIndex:integer) : TCustomChartSeries;
|
||||
{ extracts, for the given index, the series from the internal
|
||||
legend items list. }
|
||||
var
|
||||
legitem : TLegendItem;
|
||||
begin
|
||||
legitem := GetLegendItem(AIndex);
|
||||
if (legitem <> nil) and (legitem.Owner is TCustomChartSeries) then
|
||||
result := TCustomChartSeries(legitem.Owner)
|
||||
else
|
||||
result := nil;
|
||||
end;
|
||||
|
||||
function TChartListbox.GetSeriesCount : integer;
|
||||
{ determines the number of series displayed in the listbox.
|
||||
Note that this may be different from the Chart.SeriesCount if
|
||||
RemoveSeries has been called }
|
||||
begin
|
||||
result := FLegendItems.Count;
|
||||
end;
|
||||
|
||||
function TChartListbox.IsLocked : boolean;
|
||||
begin
|
||||
result := FLockCount <> 0;
|
||||
end;
|
||||
|
||||
procedure TChartListBox.KeyDown(var Key: Word; Shift: TShiftState);
|
||||
{ allows checking/unchecking of items by means of pressing the space bar }
|
||||
begin
|
||||
if (Key = VK_SPACE) and (Shift=[]) and FShowCheckboxes then begin
|
||||
ClickedCheckbox(ItemIndex);
|
||||
Key := VK_UNKNOWN;
|
||||
end else
|
||||
inherited KeyDown(Key,Shift);
|
||||
end;
|
||||
|
||||
procedure TChartListBox.Lock;
|
||||
{ locking mechanism to avoid excessive broadcasting of chart changes.
|
||||
See also: IsLocked and UnLock }
|
||||
begin
|
||||
inc(FLockCount);
|
||||
end;
|
||||
|
||||
procedure TChartListBox.MeasureItem(Index: Integer; var AHeight: Integer);
|
||||
{ inherited from ancestor: measures the height of a listbox item taking into
|
||||
account the height of the checkbox }
|
||||
begin
|
||||
Unused(Index);
|
||||
AHeight := CalculateStandardItemHeight;
|
||||
if FShowCheckboxes then
|
||||
AHeight := Max(AHeight, GetSystemMetrics(SM_CYMENUCHECK) + 2);
|
||||
end;
|
||||
|
||||
procedure TChartListbox.MouseDown(AButton: TMouseButton; AShift: TShiftState;
|
||||
AX, AY: Integer);
|
||||
{ standard MouseDown handler: checks if the click occured on the checkbox,
|
||||
on the series icon, or on the text.
|
||||
The visibility state of the item's series is changed when clicking on the
|
||||
checkbox, and an event OnCheckboxClick is generated.
|
||||
An event OnSeriesIconClick is generated when double-clicking on the
|
||||
series icon; the method stores the series list index here.
|
||||
An event OnItemClick is generated when the click occured neither on the
|
||||
checkbox nor the series icon.
|
||||
}
|
||||
var
|
||||
Rcb, Ricon : TRect;
|
||||
index : integer;
|
||||
P : TPoint;
|
||||
done : boolean;
|
||||
begin
|
||||
if (AButton = mbLeft) then begin
|
||||
P := Point(AX, AY);
|
||||
index := GetIndexAtXY(AX, AY);
|
||||
CalcRects(ItemRect(index), Rcb, Ricon);
|
||||
FSeriesIconClicked := -1;
|
||||
done := false;
|
||||
if FShowCheckboxes and IsPointInRect(P, Rcb) then begin
|
||||
ClickedCheckbox(index);
|
||||
done := true;
|
||||
end;
|
||||
if FShowSeriesIcons and PtInRect(Ricon, P) then begin
|
||||
FSeriesIconClicked := index;
|
||||
// remember the clicked index for the double click event
|
||||
done := true;
|
||||
end;
|
||||
if not done then
|
||||
ClickedItem(index);
|
||||
end;
|
||||
inherited MouseDown(AButton, AShift, AX, AY);
|
||||
end;
|
||||
|
||||
procedure TChartListbox.Notification(AComponent: TComponent;
|
||||
AOperation: TOperation);
|
||||
{ avoids AV if Chart is deleted from its container form }
|
||||
begin
|
||||
if (AOperation = opRemove) and (AComponent = FChart) then
|
||||
SetChart(nil);
|
||||
inherited Notification(AComponent, AOperation);
|
||||
end;
|
||||
|
||||
procedure TChartListbox.Populate;
|
||||
{ populates the listbox with all series contained in the chart. Use the event
|
||||
OnPopulate if you don't omit special series from the listbox (RemoveSeries) }
|
||||
var
|
||||
i : integer;
|
||||
begin
|
||||
try
|
||||
Items.BeginUpdate;
|
||||
Items.Clear;
|
||||
if FChart <> nil then begin
|
||||
FreeAndNil(FLegendItems);
|
||||
FLegendItems := CreateLegendItems;
|
||||
for i:=0 to FLegendItems.Count-1 do
|
||||
Items.Add('');
|
||||
// the caption is owner-drawn using info from the FLegendItems
|
||||
// --> no need to pass the text here
|
||||
|
||||
if Assigned(OnPopulate) then
|
||||
OnPopulate(self);
|
||||
end;
|
||||
finally
|
||||
Items.EndUpdate;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TChartListbox.RemoveSeries(ASeries:TCustomChartSeries);
|
||||
{ removes the series from the listbox, but keeps it in the chart }
|
||||
var
|
||||
index : integer;
|
||||
begin
|
||||
index := FindSeriesIndex(ASeries);
|
||||
if index <> -1 then begin
|
||||
FLegendItems.Delete(index);
|
||||
Items.Delete(index);
|
||||
Invalidate;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TChartListbox.SeriesChanged(ASender:TObject);
|
||||
{ Notification procedure of the listener. Responds to chart broadcasts
|
||||
by populating the listbox with the chart's series }
|
||||
var
|
||||
index : integer;
|
||||
begin
|
||||
if not IsLocked then begin
|
||||
Populate;
|
||||
{ in case of radiobutton mode, it is necessary to uncheck the other
|
||||
series; there can be only one active series in this mode }
|
||||
if (FCheckStyle = cbsRadioButton) and (ASender is TBasicChartSeries) then
|
||||
begin
|
||||
index := FindSeriesIndex(ASender as TCustomChartSeries);
|
||||
if (index <> -1) then
|
||||
Checked[index] := (ASender as TCustomChartSeries).Active;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TChartListbox.SetChart(AValue:TChart);
|
||||
{ connects the ListBox to the chart }
|
||||
begin
|
||||
if FChart = AValue then exit;
|
||||
|
||||
if FListener.IsListening then
|
||||
FChart.Broadcaster.Unsubscribe(FListener);
|
||||
FChart := AValue;
|
||||
if FChart <> nil then
|
||||
FChart.Broadcaster.Subscribe(FListener);
|
||||
SeriesChanged(nil);
|
||||
end;
|
||||
|
||||
procedure TChartListbox.SetChecked(AIndex:integer; AValue:boolean);
|
||||
{ shows/hides the series with the specified index of its listbox item.
|
||||
In case of radiobutton style, all other series are hidden if AValue=true }
|
||||
var
|
||||
ser : TBasicChartSeries;
|
||||
i : integer;
|
||||
begin
|
||||
ser := GetSeries(AIndex);
|
||||
if ser <> nil then begin
|
||||
Lock;
|
||||
try
|
||||
ser.Active := AValue;
|
||||
if AValue and (FCheckStyle = cbsRadioButton) then
|
||||
for i:=0 to FLegendItems.Count-1 do begin
|
||||
ser := GetSeries(i);
|
||||
if (i <> AIndex) and (ser <> nil) then
|
||||
ser.Active := false;
|
||||
end;
|
||||
Invalidate;
|
||||
finally
|
||||
Unlock;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TChartlistbox.SetCheckStyle(AValue:TCheckBoxesStyle);
|
||||
{ selects "checkbox" or "radiobutton" styles. In radiobutton mode, only
|
||||
one series can be visible }
|
||||
var
|
||||
j : integer;
|
||||
begin
|
||||
if AValue <> FCheckStyle then begin
|
||||
if AValue = cbsRadioButton then
|
||||
j := FirstCheckedIndex
|
||||
else
|
||||
j := -1;
|
||||
FCheckStyle := AValue;
|
||||
if (FCheckStyle = cbsRadioButton) and (j <> -1) then
|
||||
Checked[j] := true;
|
||||
Invalidate;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TChartListbox.SetShowCheckboxes(AValue:boolean);
|
||||
begin
|
||||
if AValue <> FShowCheckboxes then begin
|
||||
FShowCheckboxes := AValue;
|
||||
Invalidate;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TChartListbox.SetShowSeriesIcons(AValue:boolean);
|
||||
begin
|
||||
if AValue <> FShowSeriesIcons then begin
|
||||
FShowSeriesIcons := AValue;
|
||||
Invalidate;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TChartListbox.Unlock;
|
||||
begin
|
||||
dec(FLockCount);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -58,6 +58,40 @@ LazarusResources.Add('tchartlegendpanel','PNG',[
|
||||
+'p'#150'G'#244'3'#7#173'n4'#243#194#193#13#20#153#185#254#246'4'#255#18#233
|
||||
+#13#248#238#202'A'#8#175'F'#133#0#0#0#0'IEND'#174'B`'#130
|
||||
]);
|
||||
LazarusResources.Add('tchartlistbox','PNG',[
|
||||
#137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#8#6#0#0#0#224'w='#248#0
|
||||
+#0#0#9'pHYs'#0#0#14#196#0#0#14#196#1#149'+'#14#27#0#0#0#7'tIME'#7#219#7#7#21
|
||||
+''''#9'".'#201#191#0#0#0#7'tEXtAuthor'#0#169#174#204'H'#0#0#0#12'tEXtDescrip'
|
||||
+'tion'#0#19#9'!#'#0#0#0#10'tEXtCopyright'#0#172#15#204':'#0#0#0#14'tEXtCreat'
|
||||
+'ion time'#0'5'#247#15#9#0#0#0#9'tEXtSoftware'#0']p'#255':'#0#0#0#11'tEXtDis'
|
||||
+'claimer'#0#183#192#180#143#0#0#0#8'tEXtWarning'#0#192#27#230#135#0#0#0#7'tE'
|
||||
+'XtSource'#0#245#255#131#235#0#0#0#8'tEXtComment'#0#246#204#150#191#0#0#0#6
|
||||
+'tEXtTitle'#0#168#238#210''''#0#0#1#0'IDATx'#156#173#150'?h'#19'Q'#28#199'?'
|
||||
+#175'dQ;9'#184')'#13'tJ'#209#4#23'A'#154#134#6#19'S'#220#226#208'@&'#233#224
|
||||
+#16#131#180'C{'#17#156'2'#228#169'`'#208','#5')N'#130#25#26'q('#169#169'\'
|
||||
+#139'`'#29'DMS'#219#169#208#148'B'#7#7'qp'#20#206'!'#188#243'rw'#185#220#169
|
||||
+'_8x'#247#187#247'>'#223#247'{~'#156'XZzj'#16'P'#194#16'T'#30#220#17'~'#250
|
||||
+#134#0'4-'#223#23#156#185#191'C'#179#28'ut'#150#242#5'ssi^'#173#190#246'='
|
||||
+#153#17'+'#212#14'O&'#211#230#163#180#178#210#226#251#143'S'#190#13'B'#170
|
||||
+#209',G'#185#245#168''#230#186#222'r'#12#168'T'#138'l'#189'{'#27#204'`'#183
|
||||
+#189#7#192'B*'#196'n{'#143#197#213'_<'#188#25'r'#29#176#161'o'#147'J^C'#211
|
||||
+'jC'#247'N'#202#162'0)'#10'j'#133#223']'#152#7#224#201#227#170'9('#149#188
|
||||
+#202#155#150#142#148'E'#255#25#0#14#184#29'l'#205#224'z:I'#183'{'#224#9'>>:!'
|
||||
+#158#166#196#13#140#0#0#1#0'IDAT'#152#234#25'\'#140'M'#0#208#140#245'>'#14':'
|
||||
+'Ek'#235'm3'#131'{'#165'E3'#222'h'#188#28#158#129#130#218'O'#145#146#218#240
|
||||
+#143#159#247#137'ON{B]'#13#236'p+'#212#170#203#177#8#31#222'w8'#225#180'/'
|
||||
+#131#17#235#139#130#171';'#225'&}k'#155#201#248'%_'#240'>'#3#191#23'M'#223
|
||||
+#248'D'#169'Ts'#133#141'm'#150#25#219','#247#197#2'/'#209#141#153'('#24#130
|
||||
+'p'#189#202#225#236#252#208#12'B'#208#171'1'#0#137'3 '#229'W'#207#1'k'#205#29
|
||||
+#132'!'#224','#132#235'U'#140#245'}'#0#186#207#159#185#27'HYtTEM'#171#25'R'
|
||||
+#22#233'v'#15#200'fs|'#153#189#226#152#237'm2'#132#235'UD&b'#154#0#136'o'#163
|
||||
+#28'Z'#250#245'm'#242' '#217#225#133#194'8'#133#194#184#25#23#153#136#9#183
|
||||
+#203#151#1#192'r'''#207'r'''#239#136#171#217#135#235#189'[o'#156#251#249'w'#6
|
||||
+'^R&v'#248'3'#0#231'2*'#185#215'd'#155#178#217#156#217'n'#145#179#196#173
|
||||
+#157#254#196#27#211#1#12'i'#195'pn'#0#0#0'#IDAT'#252#214#156'A'#242'48>:'#249
|
||||
+''''#184#167#129#166#185#151#131' '#138''''#166#16#134#17#248#175'%'#144'~'#3
|
||||
+#176'l'#216#8#140'a'#7'G'#0#0#0#0'IEND'#174'B`'#130
|
||||
]);
|
||||
LazarusResources.Add('tchartnavpanel','PNG',[
|
||||
#137'PNG'#13#10#26#10#0#0#0#13'IHDR'#0#0#0#24#0#0#0#24#4#3#0#0#0#18'Y '#203#0
|
||||
+#0#0'''PLTE'#0#0#0'@@@ww'#146'JJ'#255#0#136'jw'#177'6'#255'@@'#255#158'^'#128
|
||||
|
Loading…
Reference in New Issue
Block a user