TAChart – חלק רביעי

בחלק הקודם התעסקתי רק על הפיכת הטבלה לדבר לפעולה התשרת את הוספת הערכים לעוגה. הגיע הזמן אבל ליצור עוגה, כי אם מקודם הייתי קצת רעב, תארו לכם מה קורה אחרי ארבעה ימים…

יצירת הגרף

את פעולת היצירה חילקתי לשני חלקים:

  1. אתחול המידע
  2. הזנת הנתונים לעוגה

TAGraph עובד עם "סדרות". הסדרות הללו הן למעשה סוגי הגרפים עבור TAGraph. אתם בטח מבינים כי מן הסתם, סדרה בשם TPieSeries מדברת על גרף מסוג Pie.
התחלתי קודם בחלק האתחול. היות והוא צריך לרוץ רק פעם אחת, אבל הכנסתי אותו למתודה משל עצמו וקראתי לה בשם initpie. יצרתי גם שדה בשם pie מסוג TPieSeries שהוא גלובלי במחלקה של החלון.

בראש ובראשונה אני רוצה לאתחל את pie, אח"כ לספק לו כותרת. במידה ואתם רוצים (אני לא אוהב את זה במיוחד), ניתן גם להגיד לו לפצל כל פלח בעוגה.
לאחר מכן, אני החלטתי לטפל קצת באיך המקרא יראה, כולל איזה טקסט יוצג שם (עבודה עם חוקי format string של פסקל). גם החלטתי כי הקבוצה שאליה הגרף שייך היא קבוצה מספר 0.

לאחר המקרא, החלטתי להתחיל לטפל באיך כל נתון יקבל ייחס. החלטתי לתת צבע צהוב בהיר לרקע התווית, ושהעט המציירת אותה תהיה ברוחב 2 פקסלים.
התווית עצמה תציג גם את השם וגם את הערך של כל איבר בגרף.

לאחר מכן, החלתי לטפל קצת במקרא של Chart עצמו. והוספתי קבוצה מספר 0, בשם Pie. לאחר מכן, הוספתי את הסדרה שיצרתי:

procedure TForm1.initpie;
begin
  Chart.ClearSeries;
  pie          := TPieSeries.Create(Chart1);
  pie.Title    := 'Pie Chart';
  pie.Exploded := False;
  with pie.Legend do
   begin
     Multiplicity := lmPoint;
     Format       := '%2:s (%1:.2f%%)';
     GroupIndex   := 0;
   end;

  with Pie.Marks do
   begin
     LabelBrush.Color  := $80FFFF;
     LinkPen.Width     := 2;
     Style             := smsLabelPercent;
     OverlapPolicy     := opHideNeighbour;
     Visible           := true;
   end;

  with Chart.Legend do
   begin
     GroupTitles.Clear;
     GroupTitles.Add('Pie');
     Chart.AddSeries(pie);
   end;
end;

חשוב לזכור כי את כל הדברים האלו ניתן גם לבצע בצורה גרפית לחלוטין, אבל רציתי קצת להראות איך הקוד נראה, במידה ואנחנו בוחרים לעשות את זה בקוד.
היות ואנחנו יוצרים את pie, צריך גם לשחרר אותה. אז הלכתי לאירוע של החלון הנקרא OnDestroy והוספתי שם את הקוד הבא:

procedure TForm1.FormDestroy(Sender: TObject);
begin
  if Assigned(pie) then
    FreeAndNil(pie);
end;

וכך אני מונע דליפת זיכרון בקוד שלי, בעת סגירת החלון.

השלב הבא שלי, היה בעצם לספק את הנתונים עבור הגרף. וברגע שאני מסיים לספק אותם, הם מוצגים על המסך.
לשם כך הלכתי לאירוע של btnApply והוספתי שם את הקוד הבא:

procedure TForm1.btnApplyClick(Sender: TObject);
var i    : integer;
    acol : TColor;
begin
  if not Assigned(pie) then initpie; // first time applying ... it can have memory leak if we apply it every time
  pie.Clear;
  for i := 1 to sgGraphDetails.RowCount -1 do
   begin
     with sgGraphDetails do
      begin
        if Cells[2, i] = '' then continue; // empty content
        acol := clTAColor; // set color automatic
        if Cells[3, i] <> '' then // unless we choose one ...
          acol := StringToColor(Cells[3, i]);

        // Add the values
        pie.Add(StrToFloat(Cells[2, i]), Cells[1, i], acol);
      end;
   end;
end;

ועכשיו אנחנו גם מציגים את העוגה. הבעיה היא שאני עדיין לא יכול לאכול אותה, כי היא נמצאת רק בחלון😦
הבטן מציקה לי מאוד, ואני חייב כבר לאכול את העוגה.

אז הגיע הזמן לייצא את התוצר החוצה.
למרות שיש הרבה מאוד סוגי תמונות אליהם ניתן לייצא, החלטתי לתמוך בהדגמה שלי רק ב6 סוגים נפוצים:

  1. Windows Bitmap (bmp)‎
  2. Jpeg (jpg)‎
  3. Portable Network Graphics (png)‎
  4. Portable Map Graphics (ppm)‎
  5. X Pixmap (xpm)‎
  6. SVG

לשם כך הגדרתי קצת את הפילטר של SaveDialog. אתן לכם לשחק איתו קצת, היות והוא מאוד פשוט להגדרה בצורה גרפית.
הקוד שכתבתי, עובד לפי הסדר שרשמתי כאן ובנוי לפיו.

למעט SVG, לייצא לפורמט מפת סיביות כלשהי, זה יחסית מאוד פשוט. הקוד האמיתי הוא עבור ה SVG.

procedure TForm1.btnExportClick(Sender: TObject);
var fs : TFileStream;
    id : IChartDrawer;
begin
  if not SaveDialog.Execute then exit;

  case SaveDialog.FilterIndex of // lets see what type of image they want
    1 : Chart.SaveToBitmapFile(SaveDialog.FileName);                          // bitmap
    2 : Chart.SaveToFile(TJPEGImage, SaveDialog.FileName);                    // JPeg
    3 : Chart.SaveToFile(TPortableNetworkGraphic, SaveDialog.FileName);       // PNG - our default
    4 : Chart.SaveToFile(TPortableAnyMapGraphic, SaveDialog.FileName);        // PPM
    5 : Chart.SaveToFile(TPixmap, SaveDialog.FileName);                       // XPM
    6 : begin                                                                   // SVG
          fs := TFileStream.Create(SaveDialog.FileName, fmCreate);
          try
            id                       := TSVGDrawer.Create(fs,true);
            id.DoChartColorToFPColor := @ChartColorSysToFPColor;
            Chart.Draw(id, Rect(0,0, Chart.Width, Chart.Height));
          finally
            fs.Free;
          end;
        end;
  end;
end;

החלטתי להשתמש בסטטיסטיקה של w3school על דפדפנים, והשתמשתי בנתונים שלהם לחודש אוגוסט 2012.
זהו, עכשיו אפשר לקחת את התוצר ולאכול. בתאבון🙂
tachart browser statistics

את קוד המקור, ניתן להורד מgithub.

2 מחשבות על “TAChart – חלק רביעי

  1. reuven

    ומה לגבי גרפים מתוחכמים יותר כמו גרף קווי שבו לציר האנכי יש סקלה לוגריתמית?
    המקרא של הגרף יכיל מידע שיצביע על שעורי ההשתנות של התופעה המוצגת.

כתיבת תגובה

הזינו את פרטיכם בטופס, או לחצו על אחד מהאייקונים כדי להשתמש בחשבון קיים:

הלוגו של WordPress.com

אתה מגיב באמצעות חשבון WordPress.com שלך. לצאת מהמערכת / לשנות )

תמונת Twitter

אתה מגיב באמצעות חשבון Twitter שלך. לצאת מהמערכת / לשנות )

תמונת Facebook

אתה מגיב באמצעות חשבון Facebook שלך. לצאת מהמערכת / לשנות )

תמונת גוגל פלוס

אתה מגיב באמצעות חשבון Google+ שלך. לצאת מהמערכת / לשנות )

מתחבר ל-%s