Search code examples
delphivcldelphi-xe5teechart

Storing reference to object in TeeChart


I'm using TeeChart with Delphi XE5 and utilizing the BubbleSeries component to show X/Y/Radius bubbles in a chart.

I'm building the chart using an list of objects that I have, calculating X/Y/Radius values for these objects on the fly and inserting them using the TBubbleSeries.AddBubble method.

The problem is when I want to perform some action on the objects when the corresponding bubble is hovered/clicked/etc. I use the TChartSeries.Clicked method to find out which bubble is clicked, but the index I get returned is only usable for finding out the xy/radius values of the bubble, not which object originated it.

Maybe I'm missing something simple, because this seems to be something that any charting library should handle easily. I tried using the returned index from AddBubble method, but this index is only valid until another call to AddBubble is performed, at which point, the internal list seems to be re-ordered.

Edit: Was asked for some code, here it is!

procedure TBubbleReportForm.ChartMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
var
  Index: Integer;
  Device: TDevice;
begin

  Index := BubbleSeries.Clicked(X,Y);

  if Index = -1 then
  begin
    BubbleChart.ShowHint := False;
    Exit;
  end;

  // This does not work as indexing does seems to correspond to the order which the bubbles was added.
  Device := FDevices[Index];


  BubbleChart.Hint := Device.Name;
  BubbleChart.ShowHint := True;

end;



procedure TBubbleReportForm.FormCreate(Sender: TObject);
var
  Device: TDevice;
begin


  BubbleChart.OnMouseMove := ChartMouseMove;

  // FDevices is of TObjectList type.
  for Device in FDevices do
  begin

    BubbleSeries.AddBubble(Device.CalculateXVal,Device.CalculateYVal,Device.CalculateRadius);

  end;

end;

Solution

  • You can exploit unused AXLabel argument like this:

    for DevIndex := 0 to DeviceCount - 1 do begin
        Device := FDevices[DevIndex]; 
        BubbleSeries.AddBubble(Device.CalculateXVal,Device.CalculateYVal, Device.CalculateRadius, IntToStr(DevIndex));
    end; 
    
    // to avoid labels' text ox X-Axis:
    Chart1.BottomAxis.LabelStyle := talValue; 
    
      //in Clicked:
       DeviceIndex := StrToInt(BubbleSeries.Labels[Index]);