Inhalt

Aktueller Ordner: duesseldorfer-schuelerinventar-freepascal-client
⬅ Übergeordnet

u_timeseries.pas

unit u_timeseries;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Grids,
  ExtCtrls, TAGraph, TASeries, fpjson, u_norms, u_api;

type

  { TTimeSeriesForm }

  TTimeSeriesForm = class(TForm)
    btnClose: TButton;
    cboCompetence: TComboBox;
    Label1: TLabel;
    StringGrid1: TStringGrid;
    Chart1: TChart;
    Splitter1: TSplitter;
    procedure btnCloseClick(Sender: TObject);
    procedure cboCompetenceChange(Sender: TObject);
  private
    FUserID: string;
    FSession: string;
    FProfiles: TJSONArray;
    FGroupName: string;
    FLineSeries: TLineSeries;
    FData: array of record
      ProfilID: string;
      Name: string;
      Values: array[1..6] of Integer;
    end;
    procedure LoadData;
    procedure UpdateGrid;
    procedure UpdateChart;
  public
    constructor Create(AOwner: TComponent; const UserID, Session: string; const GroupName: string; Profiles: TJSONArray); reintroduce;
  end;

implementation

{$R *.lfm}

constructor TTimeSeriesForm.Create(AOwner: TComponent; const UserID, Session: string; const GroupName: string; Profiles: TJSONArray);
var
  i: Integer;
  TopPanel: TPanel;
begin
  inherited Create(AOwner);
  FUserID := UserID;
  FSession := Session;
  FGroupName := GroupName;
  FProfiles := Profiles;
  Caption := 'Zeitreihe - ' + GroupName;
  Width := 1000;
  Height := 700;
  Position := poScreenCenter;
  
  // Oberes Panel für ComboBox
  TopPanel := TPanel.Create(Self);
  TopPanel.Parent := Self;
  TopPanel.SetBounds(0, 0, 1000, 45);
  TopPanel.Align := alTop;
  TopPanel.Height := 45;
  TopPanel.BevelOuter := bvNone;
  
  // Label
  Label1 := TLabel.Create(TopPanel);
  Label1.Parent := TopPanel;
  Label1.SetBounds(12, 14, 66, 13);
  Label1.Caption := 'Kompetenz:';
  
  // ComboBox
  cboCompetence := TComboBox.Create(TopPanel);
  cboCompetence.Parent := TopPanel;
  cboCompetence.SetBounds(90, 10, 250, 21);
  cboCompetence.Style := csDropDownList;
  cboCompetence.DropDownCount := 6;
  for i := 1 to 6 do
    cboCompetence.Items.Add(KOMPETENZEN[i]);
  cboCompetence.ItemIndex := 0;
  cboCompetence.OnChange := @cboCompetenceChange;
  
  // Chart
  Chart1 := TChart.Create(Self);
  Chart1.Parent := Self;
  Chart1.SetBounds(0, 45, 1000, 250);
  Chart1.Align := alTop;
  Chart1.Title.Text.Text := 'Zeitreihe - ' + GroupName;
  Chart1.LeftAxis.Title.Caption := 'Wert (1-5)';
  Chart1.BottomAxis.Title.Caption := 'Profile (Nr.)';
  
  FLineSeries := TLineSeries.Create(Chart1);
  FLineSeries.SeriesColor := clBlue;
  FLineSeries.LinePen.Width := 2;
  FLineSeries.ShowPoints := True;
  FLineSeries.Pointer.Brush.Color := clBlue;
  Chart1.AddSeries(FLineSeries);
  
  // Splitter
  Splitter1 := TSplitter.Create(Self);
  Splitter1.Parent := Self;
  Splitter1.SetBounds(0, 295, 1000, 5);
  Splitter1.Align := alTop;
  
  // StringGrid
  StringGrid1 := TStringGrid.Create(Self);
  StringGrid1.Parent := Self;
  StringGrid1.SetBounds(0, 300, 1000, 350);
  StringGrid1.Anchors := [akLeft, akTop, akRight, akBottom];
  StringGrid1.FixedCols := 1;
  StringGrid1.FixedRows := 1;
  StringGrid1.Options := StringGrid1.Options + [goRowSelect];
  StringGrid1.DefaultRowHeight := 22;
  StringGrid1.ColCount := 8;
  StringGrid1.ScrollBars := ssAutoBoth;
  
  // Spaltenbreiten
  StringGrid1.ColWidths[0] := 40;
  StringGrid1.ColWidths[1] := 180;
  for i := 2 to 7 do
    StringGrid1.ColWidths[i] := 90;
  
  // Kopfzeile
  StringGrid1.Cells[0, 0] := 'Nr.';
  StringGrid1.Cells[1, 0] := 'Name';
  StringGrid1.Cells[2, 0] := KOMPETENZEN[1];
  StringGrid1.Cells[3, 0] := KOMPETENZEN[2];
  StringGrid1.Cells[4, 0] := KOMPETENZEN[3];
  StringGrid1.Cells[5, 0] := KOMPETENZEN[4];
  StringGrid1.Cells[6, 0] := KOMPETENZEN[5];
  StringGrid1.Cells[7, 0] := KOMPETENZEN[6];
  
  // Button
  btnClose := TButton.Create(Self);
  btnClose.Parent := Self;
  btnClose.SetBounds(450, 660, 100, 30);
  btnClose.Caption := 'Schließen';
  btnClose.OnClick := @btnCloseClick;
  
  // Daten laden
  LoadData;
end;

procedure TTimeSeriesForm.LoadData;
var
  i, j, k: Integer;
  Profile: TJSONObject;
  Items: array[1..36] of Integer;
  Sums: array[1..6] of Integer;
  Values: array[1..6] of Integer;
begin
  SetLength(FData, FProfiles.Count);
  
  for i := 0 to FProfiles.Count - 1 do
  begin
    Profile := TJSONObject(FProfiles.Objects[i]);
    FData[i].ProfilID := Profile.Get('profilID', '');
    FData[i].Name := Profile.Get('name', '');
    
    for j := 1 to 36 do
      Items[j] := Profile.Get('item' + IntToStr(j), 2);
    
    // Summen berechnen
    Sums[1] := 0; for j := 1 to 10 do Sums[1] := Sums[1] + Items[j];
    Sums[2] := 0; for j := 11 to 20 do Sums[2] := Sums[2] + Items[j];
    Sums[3] := 0; for j := 21 to 28 do Sums[3] := Sums[3] + Items[j];
    Sums[3] := Sums[3] + Items[9] + Items[10];
    Sums[4] := 0; for j := 29 to 36 do Sums[4] := Sums[4] + Items[j];
    Sums[5] := Items[1] + Items[2] + Items[6] + Items[7] + Items[8] + Items[9] + Items[10] +
               Items[12] + Items[13] + Items[14] + Items[15];
    Sums[6] := Items[3] + Items[4] + Items[5] + Items[9] + Items[10] + Items[11] + Items[17] + Items[18];
    
    // Profilwerte (0-4) dann umwandeln in 1-5
    for k := 1 to 6 do
    begin
      Values[k] := 4;
      for j := 1 to 5 do
        if Sums[k] < NORM_SE_HS[k, j] then
        begin
          Values[k] := j - 1;
          Break;
        end;
    end;
    
    for k := 1 to 6 do
      FData[i].Values[k] := Values[k] + 1;
  end;
  
  // Tabelle füllen
  StringGrid1.RowCount := Length(FData) + 1;
  for i := 0 to Length(FData) - 1 do
  begin
    StringGrid1.Cells[0, i + 1] := IntToStr(i + 1);
    StringGrid1.Cells[1, i + 1] := FData[i].Name;
    for k := 1 to 6 do
      StringGrid1.Cells[k + 1, i + 1] := IntToStr(FData[i].Values[k]);
  end;
  
  UpdateGrid;
  UpdateChart;
end;

procedure TTimeSeriesForm.UpdateGrid;
var
  k: Integer;
  compIdx: Integer;
begin
  compIdx := cboCompetence.ItemIndex + 1;
  
  // Kopfzeile aktualisieren (markierte Kompetenz)
  for k := 1 to 6 do
  begin
    if k = compIdx then
      StringGrid1.Cells[k + 1, 0] := '>>> ' + KOMPETENZEN[k] + ' <<<'
    else
      StringGrid1.Cells[k + 1, 0] := KOMPETENZEN[k];
  end;
  
  StringGrid1.Refresh;
end;

procedure TTimeSeriesForm.UpdateChart;
var
  i: Integer;
  compIdx: Integer;
begin
  compIdx := cboCompetence.ItemIndex + 1;
  
  FLineSeries.Clear;
  for i := 0 to Length(FData) - 1 do
    FLineSeries.AddXY(i + 1, FData[i].Values[compIdx]);
  
  Chart1.Invalidate;
end;

procedure TTimeSeriesForm.cboCompetenceChange(Sender: TObject);
begin
  UpdateGrid;
  UpdateChart;
end;

procedure TTimeSeriesForm.btnCloseClick(Sender: TObject);
begin
  Close;
end;

end.