This question relates to another ongoing question here: Format Stones and Pounds correctly?
I figured it would be more suitable to ask here as a separate question, before deciding what to do.
As described from the link above, I am representing weight in a TChart as stones and pounds.
Before I decide on whether to change the data type I am currently using (Double) as the comments from above suggest, I want to see how I can display my chart in Stones and Pounds as I originally had in mind.
See this sample image I manipulated for demo purposes:
The problem is the left Axis of the chart, as the notes in the image state - the chart increments up to .99 (Pounds) before reaching the next whole number (Stones in this case). For example:
- 03.00
- 02.99 < .99 = max number before reaching 3.00
- 02.98
- 02.97
I need the Left axis to be setup like so:
- 03.00
- 02.13 < .13 = max number before reaching 3.00
- 02.12
- 02.11
- 02.10
And also display all the labels for the pounds part.
Is there a setting somewhere that I can use to set the max value for the .00 (lbs) before reaching the next whole number (stones)?
At the moment nothing seems to be making a lot of sense, From what I understand from the other question is I should be using Integers and representing as Pounds only.
I want to see how it could look before making any changes though, ideally I want the chart to stay near the same as the image if possible.
Hope this makes sense.
Thanks.
UPDATE
Just thought I would update the changes I eventually got working.
All credit has to go to David Heffernan for his persistence in explaining where I was going wrong, and writing detailed information and advice.
There is still some work I need to do, but for now here is the updated chart I now have:
I have not done the values in labels, but from the sample image above this is the values I used:
- 15.2
- 15.3
- 15.11
- 15.13
- 16.0
- 16.4
You can't use your current representation to plot a reasonable chart. Suppose you have a bar chart with the following values:
10st 12lb
10st 13lb
11st 0lb
11st 1lb
The chart will look like this:
Forget about the axis labelling for a moment. Look at the difference between the bars. The difference between each adjacent value is 1lb. But the graph tells a completely different story. I've used a bar chart here, but the principle applies for all chart types.
The bottom line is that you need to represent your weight values with a true decimal representation of the weight. Your representation does not obey basic laws of arithmetic. So, half a stone must be 0.5. Trying to represent a half with the number 0.07 is simply asking for a world of pain.
Use this formula to convert from stones and pounds to a true floating point representation of the weight:
FloatingPointWeightValue := Stones + Pounds/14.0;
Or if you store only the pounds then it is simply
FloatingPointWeightValue := Pounds/14.0;
I would suggest that you make sure that the Increment
of the axis is at least 1. If you need to go smaller than that then you'll have to get into custom axis label titles. And when you add your values, give them a label. This will allow the chart to use sensible labels to identify values. For example:
Series1.Add(10 + 12/14, '10st, 12lb');
Series1.Add(10 + 13/14, '10st, 13lb');
Series1.Add(11 + 00/14, '11st, 0lb');
Series1.Add(11 + 01/14, '11st, 1lb');
And the result looks like this:
You'd obviously write a bunch of helper functions to handle this. I'd suggest storing the raw data as pounds. So, 11st 1lb would be stored as 11*14 + 1 = 155. Then you'd have these helpers:
function StonesFromPounds(Pounds: Integer): Double;
begin
Result := Pounds / 14.0;
end;
function StonesPoundsLabel(Pounds: Integer): string;
begin
Result := Format('%dst %dlb', [Pounds div 14, Pounds mod 14]);
end;
And then the data population would look like this:
Pounds := 152;
Series1.Add(StonesFromPounds(Pounds), StonesPoundsLabel(Pounds));
You have complete freedom with how you create text labels for your weights. If you want something less verbose than 10st 13lb then you can adjust the helper functions to your needs.
Now, this has been quite a long answer, so I will summarise my advice:
- When you acquire the data, from what ever source, convert from whichever format they arrive in to a well-defined storage format, the raw data format.
- Store this raw data as integer values, in units of pounds.
- When you plot the weights, convert to floating point values in units of stones by
Stones := Pounds/14.0
.
- Associate text labels to each value that you plot so that you can present the weights in human readable form.
- Be prepared to supply custom label axes if you need to label weights in between whole values of stones.