Search code examples
postgresqldelphiscrollteechart

Load only current data into TChart


I am using Delphi 10 with TChart, TPointSeries, horizontal scrolling, and currently there is too much data (100 curves, each of them contains many thousands of points) loaded from PostgreSQL database.

  • Is it possible to load from database (with LIMIT and OFFSET) only the data which needs to be displayed in current scrolling "window" of TChart?
  • Is there some "Data needed" event that fires when I scroll to region with no data?
  • Is it possible to inform TChart how much points I have without loading all this points?
  • Is it possible to have all the curves' descriptions in Legend with loading actual data to chart only when I check the corresponding checkboxes in legend? I do not want that Chart displays all the series available in database but want it to show in legend all the available series. When user clicks at particular series in legend, corresponding series data will be loaded and represented as curve.

Solution

    • Is it possible to load from database (with LIMIT and OFFSET) only the data which needs to be displayed in current scrolling "window" of TChart?

    You can do this manually looping the data and calling Add()/AddXY() functions.
    Then, at OnScroll event you can remove points that are out/far from the axes range and add those in/next to the axis range.

    • Is there some "Data needed" event that fires when I scroll to region with no data?

    No. You should use OnScroll event and check it yourself.

    Update

    An example of what could be done is provided below:

    constructor TForm1.Create(AOwner: TComponent);
    begin
      inherited;
      chart.OnScroll := chartScroll;
      chart.OnZoom := chartZoom;
    end;
    
    procedure TForm1.displayRange();
    var startDate, endDate: TDateTime;
    begin
      startDate := TDateTime(chart.BottomAxis.Minimum);
      endDate   := TDateTime(chart.BottomAxis.Maximum);
      Log(Format('start=%d, end=%d', [
        FindClosestIndex(startDate, chart.Series[0].XValues),
        FindClosestIndex(endDate, chart.Series[0].XValues)
      ]));
    end;
    
    procedure TForm1.chartScroll(Sender: TObject);
    begin
      displayRange();
    end;
    
    procedure TForm1.chartZoom(Sender: TObject);
    begin
      displayRange();
    end;
    

    An example of FindClosestIndex could be taken here.

    End of update

    • Is it possible to inform TChart how much points I have without loading all this points?

    No, but you can maintain variables doing it.

    • Is it possible to have all the curves' descriptions in Legend with loading actual data to chart only when I check the corresponding checkboxes in legend? I do not want that Chart displays all the series available in database but want it to show in legend all the available series. When user clicks at particular series in legend, corresponding series data will be loaded and represented as curve.

    You can use OnCLickLegend event and loop your series. At this moment the Active property of the series is up to date so you can Clear those that are not Active and you can Add/AddXY points to those that are Active.