Thread: TChart

Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    21
    Rep Power
    0

    TChart


    Hello all, I have a problem with TChart.

    I want to make graphic at Delphi by using TChart. I want to make the axis of the TChart only showing the number of integer, and if it's not, I want it to shows ' ' (none). But the calculation of the ordinat (vertical position) still show for every axis that I get..

    Here is my listing program and it shows error at the axis..

    I declare a0, b0, and c0 as a global variabel..

    procedure TForm1.Timer2Timer(Sender: TObject);
    begin

    Shape2.Visible := True;
    Shape2.Left := Min(Shape2.Left+1, Image3.Left+22);

    if Shape2.Left >= 104 then
    begin
    a0 := (Shape2.Left-104) DIV 15;
    b0 := (Shape2.Left-104) / 15;
    c0 := b0-a0;
    daya := daya + (ai/15);

    if c0 = 0 then
    Chart1.Series[0].Add(daya,inttostr(a0),clblue)
    else
    Chart1.Series[0].Add(daya,' ',clblue);

    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    a0 := 0;
    b0 := 0;
    c0 := 0;
    end;



    Thanks
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    356
    Rep Power
    7
    Can you please explain this in more detail? I don't understand what it is you are looking for.

    Originally Posted by ClaVahnz
    only showing the number of integer, and if it's not, I want it to shows ' '
    Also, you mention that a0, b0 and c0 are declared as global variables, what data type are each declared as? And where are daya and ai declared, what data types are they and where are you setting their initial values?
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    21
    Rep Power
    0
    Originally Posted by majlumbo
    Can you please explain this in more detail? I don't understand what it is you are looking for.



    Also, you mention that a0, b0 and c0 are declared as global variables, what data type are each declared as? And where are daya and ai declared, what data types are they and where are you setting their initial values?
    I want the axis only showing the integer value, and if I get a float one, I want them to be replaced by nil,, but only for the axis, while the ordinat is still doing the count 'daya'.

    a0 is integer, b0 and c0 are float. 'daya' and 'ai' are declared when Form Create too, 'daya' initial value is 10, and 'ai' is 0.5
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    356
    Rep Power
    7
    I believe the basic issue is this line:

    Code:
    if c0 = 0 then
    ...
    as you mentioned,
    Originally Posted by ClaVahnz
    b0 and c0 are float
    The fundamental issue is that computers just cannot accurately represent floating point values and you are testing for c0 to exactly equal 0, which would probably never happen.

    You should never test for equality (=) and Not Equal (<>) if the value is a floating point variable.

    Delphi does have a way to handle these types of comparisons, using the CompareValue function. It has two basic forms
    Code:
    function CompareValue(const A,B: Integer|Int64): TValueRelationship;
    function CompareValue(const A,B: Single|Double|Extended; delta: Single|Double|Extended) : TValueRelationship;
    These (overloaded) functions are in the Math unit, so you would need to add Math to your uses clause. And the reference to TValueRelationship is in the Types unit, so make sure you have Types in your uses clause.

    the following compares c0 to 0 and if within .002 of 0 then the function will consider them as equal
    Code:
    case CompareValue(0, c0, 0.002) of 
      LessThanValue    : ShowMessage('0 < c0');
      EqualsValue      : ShowMessage('0 = c0');
      GreaterThanValue : ShowMessage('0 > c0');
    end;
    or if you don't want to provide a formal delta values the following compares c0 to 0.
    Code:
    case CompareValue(0, c0) of 
      LessThanValue    : ShowMessage('0 < c0');
      EqualsValue      : ShowMessage('0 = c0');
      GreaterThanValue : ShowMessage('0 > c0');
    end;
    You can read more on this function here :
    Last edited by majlumbo; May 13th, 2013 at 08:53 AM.
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    21
    Rep Power
    0
    Originally Posted by majlumbo
    I believe the basic issue is this line:

    Code:
    if c0 = 0 then
    ...
    as you mentioned,


    The fundamental issue is that computers just cannot accurately represent floating point values and you are testing for c0 to exactly equal 0, which would probably never happen.

    You should never test for equality (=) and Not Equal (<>) if the value is a floating point variable.

    Delphi does have a way to handle these types of comparisons, using the CompareValue function. It has two basic forms
    Code:
    function CompareValue(const A,B: Integer|Int64): TValueRelationship;
    function CompareValue(const A,B: Single|Double|Extended; delta: Single|Double|Extended) : TValueRelationship;
    These (overloaded) functions are in the Math unit, so you would need to add Math to your uses clause. And the reference to TValueRelationship is in the Types unit, so make sure you have Types in your uses clause.

    the following compares c0 to 0 and if within .002 of 0 then the function will consider them as equal
    Code:
    case CompareValue(0, c0, 0.002) of 
      LessThanValue    : ShowMessage('0 < c0');
      EqualsValue      : ShowMessage('0 = c0');
      GreaterThanValue : ShowMessage('0 > c0');
    end;
    or if you don't want to provide a formal delta values the following compares c0 to 0.
    Code:
    case CompareValue(0, c0) of 
      LessThanValue    : ShowMessage('0 < c0');
      EqualsValue      : ShowMessage('0 = c0');
      GreaterThanValue : ShowMessage('0 > c0');
    end;
    You can read more on this function here :
    Where should I put the function and how? I put it at type, at the very begining (I also already put Math at uses)
    Code:
    type {A class to hold the dragged objects}
    TMyDragObject = class(TDragControlObject)
    protected
    function GetDragImages: TDragImageList; override;
    // function CompareValue(const A, B: Double): TValueRelationship; overloaded;
    end;
    and it said that [Error] Unit1.pas(16): Undeclared identifier: 'TValueRelationship'
    And there are some errors too, telling that LessThanValue, Equals and GreaterThanValue are undeclared identifiers.

    And I see that there are 2 function, what is the difference? And if I want to be exactly 0, what function must I use?

    About the ShowMessage, can I change them to c0 := 0 or 1?

    Thanks..
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    356
    Rep Power
    7
    Originally Posted by ClaVahnz
    Unit1.pas(16): Undeclared identifier: 'TValueRelationship'
    And there are some errors too, telling that LessThanValue, Equals and GreaterThanValue are undeclared identifiers.
    As I mentioned,

    And the reference to TValueRelationship is in the Types unit, so make sure you have Types in your uses clause.
    Originally Posted by ClaVahnz
    Where should I put the function and how? I put it at type, at the very begining (I also already put Math at uses)
    You don't have to, by adding the Math Unit (and Types) these functions are made available to you, all you have to do is CALL it just like the example. If you declare it yourself in your program, then it won't be able to find the ones in the Math unit.

    Originally Posted by ClaVahnz
    And I see that there are 2 function, what is the difference?
    The first allows you to define the "distance" from your target value (in your case zero (0)) you want your program to still consider it effectively zero. The second you don't have control over the "distance" but delphi will determine this distance.

    Originally Posted by ClaVahnz
    And if I want to be exactly 0, what function must I use?
    As I mentioned, computers (all of them) just cannot store floating point values accurately. It is a basic limitation since numbers in the computer are stored in binary (base 2), and the floating point number (and more specific to this problem the fractional portion of your number) is based on decimal (base 10). This article may help you understand.

    Originally Posted by ClaVahnz
    can I change them to c0 := 0 or 1?
    No, even if you have c0 := 0.0 in your code, You just cannot rely on c0 actually "equaling" zero. It would be close, but probably not exactly zero. For exactly the same reason described above.
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    21
    Rep Power
    0
    Originally Posted by majlumbo
    You don't have to, by adding the Math Unit (and Types) these functions are made available to you, all you have to do is CALL it just like the example. If you declare it yourself in your program, then it won't be able to find the ones in the Math unit.
    Ok, I get it, I have a wrong understanding for placing the Types unit, I thought that I must put the function at the Types, not the Uses.. Lol..

    Originally Posted by majlumbo
    No, even if you have c0 := 0.0 in your code, You just cannot rely on c0 actually "equaling" zero. It would be close, but probably not exactly zero. For exactly the same reason described above.
    I mean, the list for the case of, for the Less, Equal and Greater.. I declared a new variable to hold a number for each case,, like if it is less, then g0 is 0, equal g0 is 1, and greater g0 is 2.. Is it possible to do it?

    Originally Posted by majlumbo
    Code:
    case CompareValue(0, c0, 0.002) of 
      LessThanValue    : ShowMessage('0 < c0');
      EqualsValue      : ShowMessage('0 = c0');
      GreaterThanValue : ShowMessage('0 > c0');
    end;
    Code:
    case CompareValue(0, c0) of 
      LessThanValue    : ShowMessage('0 < c0');
      EqualsValue      : ShowMessage('0 = c0');
      GreaterThanValue : ShowMessage('0 > c0');
    end;
    Where should I put these statement? I put it in the function and it show a warning :
    [Warning] Unit1.pas(242): Return value of function 'CompareValue' might be undefined
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    356
    Rep Power
    7
    Originally Posted by ClaVahnz
    I mean, the list for the case of, for the Less, Equal and Greater.. I declared a new variable to hold a number for each case, like if it is less, then g0 is 0, equal g0 is 1, and greater g0 is 2.. Is it possible to do it?
    Sorry, I misunderstood your comment. Yes, you can associate any statement(s) with each possible outcome... The showMessage was just for the example. If you want more than one statement associated, then remember to wrap them within Begin..End statements.
    Code:
    Case XX of
       Y:  begin
              statement1
              ...
              statementn
           end;
       Z:  statement1
    end;
    Although I really don't see the need to declare another variable. TRelationshipValue is defined to be -1 for LessThanValue, 0 For EqualsValue and 1 for GreatherThanValue. So any variable you declare is just reduntant....

    Originally Posted by ClaVahnz
    Where should I put these statement? I put it in the function and it show a warning :
    [Warning] Unit1.pas(242): Return value of function 'CompareValue' might be undefined
    Adding this as a function would be fine, but remember, this is already a defacto function within the Math Unit. You can simply call it with one line of code. Writing your own function wrapping this function within it would be of little value - unless there's something else you are accomplishing within the function.
    Code:
    if CompareValue(0, c) = LessThanValue then
       DoThis//Happens when Less Than
    else
       DoThisInstead;//Happens when equal or greater than
    Anyway, if you still would like to wrap this function then I would write it like so
    Code:
    function TForm1.MyCompareValue(ReferenceValue, CompareValue): TRelationshipValue;
    begin
       Result := CompareValue(ReferenceValue, CompareValue);
    end;
    and call it like so
    Code:
    if MyCompareValue(0, c0) = LessThanValue then
       DoThis
    else
       DoThisInstead;
    as you see, it does nothing more than return the same value that comparevalue returns, and all you are doing differently is calling MyCompareValue, vs. CompareValue.

    Like I said, very little in added value from such a function.
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    21
    Rep Power
    0
    Originally Posted by majlumbo
    Anyway, if you still would like to wrap this function then I would write it like so
    Code:
    function TForm1.MyCompareValue(ReferenceValue, CompareValue): TRelationshipValue;
    begin
       Result := CompareValue(ReferenceValue, CompareValue);
    end;
    and call it like so
    Code:
    if MyCompareValue(0, c0) = LessThanValue then
       DoThis
    else
       DoThisInstead;
    Ok then, but I already have a function that using Result as a return value, is it ok to use Result again in the CompareValue?
    I have it at :

    Code:
    function  TMyDragObject.GetDragImages: TDragImageList; 
    begin
    Result := Form1.DragImageList;
    end;
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    356
    Rep Power
    7
    Originally Posted by ClaVahnz
    Ok then, but I already have a function that using Result as a return value, is it ok to use Result again in the CompareValue?
    I have it at :

    Code:
    function  TMyDragObject.GetDragImages: TDragImageList; 
    begin
    Result := Form1.DragImageList;
    end;
    "Result" is not a variable you need to declare. Each function returns a value, that value is returned via the built in variable each function has already declared for you: Result. So each function has its own result.

    Technically, there are two ways to return a value from a function. For Example:
    Code:
    function Add(X, Y: Integer): Integer;
    begin
       Result := X+Y;
    end;
    or
    Code:
    function Add(X, Y: Integer): Integer;
    begin
       Add := X+Y;
    end;
    The 2nd method is "old" pascal style, where the name of the function is the returned variable's name, but it also may have a side effect that result does not have if result or the function's name appears on the right side of the assignment operator (:=)
    Code:
    function Append(X, Y: String): String;
    begin
       Result := '';
       Result := Result + X;
       Result := Result + Y;
    end;
    or
    Code:
    function Append(X, Y: String): String;
    begin
       Append:= '';
       Append:= Append(X, Y) + X;
       Append:= Append(X, Y) + Y;
    end;
    The first example simply concatenates the values in X and Y together. Attempting to do the same "type" of concatenation in the old "pascal" style turns into "recursive" calls to the Append function.
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    21
    Rep Power
    0
    Code:
    begin
    
    case CompareValue(0, c0) of 
      LessThanValue    : g0 = 2;
      EqualsValue      : g0 = 1;
      GreaterThanValue : g0 = 0;
    end;
    
    if g0 = 1 then Chart1.Series[0].Add(daya,inttostr(a0))
    else
    Chart1.Series[0].Add(daya,' ');
    
    end;
    I already do like that, and the error is still come out..
  22. #12
  23. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    356
    Rep Power
    7
    Originally Posted by ClaVahnz
    Code:
    begin
    
    case CompareValue(0, c0) of 
      LessThanValue    : g0 = 2;
      EqualsValue      : g0 = 1;
      GreaterThanValue : g0 = 0;
    end;
    
    if g0 = 1 then Chart1.Series[0].Add(daya,inttostr(a0))
    else
    Chart1.Series[0].Add(daya,' ');
    
    end;
    I already do like that, and the error is still come out..
    Is this part of a function? If so, you aren't returning back any value (i.e. No Result := XXXX). A function MUST return a value, that is the basic difference between a procedure and a function.
  24. #13
  25. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    21
    Rep Power
    0
    Originally Posted by majlumbo
    Is this part of a function? If so, you aren't returning back any value (i.e. No Result := XXXX). A function MUST return a value, that is the basic difference between a procedure and a function.
    I add this Function at my Unit (I also add Math and Type at my Uses) :

    Code:
    function TForm1.MyCompareValue(ReferenceValue, CompareValue) : TRelationshipValue;
    begin
    Result := CompareValue(ReferenceValue, CompareValue);
    end;
    And I use this as my CompareValue method :

    Code:
      if CompareValue(0, c0) = EqualsValue then
        g0 := 1
        else g0 := 0;
    
    if g0 = 1 then
        begin
          Chart1.Series[0].Add(daya,inttostr(a0));
          Form2.Chart1.Series[0].Add(daya,inttostr(a0));
        end
      else  Chart1.Series[0].Add(daya,' ');
      end;
    Then it tells me :

    Code:
    [Error] Unit1.pas(238): Undeclared identifier: 'MyCompareValue'
  26. #14
  27. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jun 2008
    Posts
    356
    Rep Power
    7
    Originally Posted by ClaVahnz
    Unit1.pas(238): Undeclared identifier: 'MyCompareValue'
    did you add the declaration for the function in your form's private declaration section...

    Code:
    TForm1 = class(TForm)
      ...
    private
       function MyCompareValue(ReferenceValue, CompareValue) : TRelationshipValue;<--Did you add this, here?
       ...
    public
       ...
    end;
  28. #15
  29. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Apr 2013
    Posts
    21
    Rep Power
    0
    Originally Posted by majlumbo
    did you add the declaration for the function in your form's private declaration section...

    Code:
    TForm1 = class(TForm)
      ...
    private
       function MyCompareValue(ReferenceValue, CompareValue) : TRelationshipValue;<--Did you add this, here?
       ...
    public
       ...
    end;
    Already done,, I use CompareValue and not declare the functon again..

    Thanks majlumbo, and I've sent you a message, please reply..
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo