TAChart – חלק שלישי

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

כתיבת קוד

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

הלכתי קודם לכפתור הנקרא btnAddItem , לחצתי עליו פעמים, והוא פתח בעורך הטקסט מתודת Callback בשם btnAddItemClick. ניתן לראות אותה גם בObject Inspector במידה ונלך לטאב הנקרא Events. זהו אירוע ברירת המחדל של כפתור, ולכן הוא זה שבעצם הוגדר.

הקוד עבור הcallback מאוד פשוט. אנחנו הולכים להוסיף לו 2 שורות. הראשונה אומרת להוסיף עוד שורה, השניה הולכת לשים מספור מתאים לתא, ובכך נקבל מספורים כדוגמת "1, 2, 3" וכו' … פר שורה:

procedure TForm1.btnAddItemClick(Sender: TObject);
begin
  sgGraphDetails.RowCount := sgGraphDetails.RowCount + 1;
  sgGraphDetails.Cells[0,sgGraphDetails.RowCount -1] := IntToStr(sgGraphDetails.RowCount -1);
end;

השלב הבא יהיה להסיר שורה על ידי הוספת Callback עבור btnRemoveLastItem:

procedure TForm1.btnRemoveLastItemClick(Sender: TObject);
begin
  if sgGraphDetails.RowCount > 1 then
    sgGraphDetails.RowCount := sgGraphDetails.RowCount - 1;
end;

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

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

procedure TForm1.sgGraphDetailsColRowDeleted(Sender: TObject; IsColumn: Boolean;
  sIndex, tIndex: Integer);
begin
  btnRemoveLastItem.Enabled := sgGraphDetails.RowCount > 1;
  btnApply.Enabled          := sgGraphDetails.RowCount > 1;
end;

אני מבצע בדיקה לוגית (במקום שאלת if), האם יש יותר משורה אחת בודדה, ואם כן, רק אז לאפשר את הכפתורים.
אבל זה לא מספיק ! הרי מה קורה כאשר אני מוסיף שורה ?
אז חזרתי לטאב הEvents של sgGraphDetails, ובאירוע OnColRowInserted בחרתי מהרשימה את sgGraphDetailsColRowDeleted, ולמעשה יש לי שני Callbacks אשר מצביעים על אותו הקוד, רק מתרחשים בזמנים שונים.

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

procedure TForm1.FormCreate(Sender: TObject);
begin
  sgGraphDetails.Cells[0,0] := '#';
  btnRemoveLastItem.Enabled := sgGraphDetails.RowCount > 1;
  btnApply.Enabled          := sgGraphDetails.RowCount > 1;
end;

עד כאן הקוד מאוד פשוט נכון ?
זוכרים שזרקתי על החלון, רכיב דיאלוג של צבעים ?
הגיע הזמן להשתמש בו, ולקשר אותו בעצם לטבלה ששמתי.
אז הלכתי לאירוע של OnButtonClick ברכיב sgGraphDetails ולחצתי עליו פעמיים.
שם בעצם אני בודק קודם כל מה העמודה שלחצו בה, ורק אם זו העמודה הנכונה, אני מציג את הדיאלוג.
לאחר הצגת הדיאלוג, במידה והמשתמש מאפשר לי (כלומר לא לחץ על cancel), אני מוסיף את הצבע הנבחר.
התאוריה נחמדה, והיא נראת ככה בצורה מעשית:

procedure TForm1.sgGraphDetailsButtonClick(Sender: TObject; aCol, aRow: Integer);
begin
  if (aRow >= 1) and (aCol = 3) then
    begin
      if ColorDialog.Execute then
        begin
          sgGraphDetails.Cells[aCol, aRow] := ColorToString(ColorDialog.Color);
        end;
    end;
end;

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

procedure TForm1.sgGraphDetailsSetEditText(Sender: TObject; ACol, ARow: Integer;
  const Value: string);
var num : double;
begin
  if (ACol = 2) and (Value  '') then
    begin
      if not TryStrToFloat(Value, num) then // do we have a real floating point number ?
        begin
          sgGraphDetails.Cells[ACol, ARow] := '';
        end;
    end;
end;

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

בחלק הבא (כאמור), אציג כיצד להגיע תאכלס ליצירת הגרף.

מחשבה אחת על “TAChart – חלק שלישי

  1. פינגבק: TAChart – חלק רביעי | לראות שונה

כתיבת תגובה

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

הלוגו של WordPress.com

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

תמונת Twitter

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

תמונת Facebook

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

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

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

מתחבר ל-%s