TChart Line Chart Series with DrawStyle Curve Dips Below Zero - How to Fix?
TChart Line Chart Series with DrawStyle Curve Dips Below Zero - How to Fix?
I am facing an issue with the Line chart series of TChart when using the DrawStyle Curve. The line is going below 0, even though none of the values are below zero (please refer to the attached image). I am looking for a solution to prevent the line from dipping below zero and maintain the curve style. Any help would be greatly appreciated, and thank you in advance for your responses.
- Attachments
-
- chart.jpg (39.93 KiB) Viewed 17030 times
Re: TChart Line Chart Series with DrawStyle Curve Dips Below Zero - How to Fix?
Hello,
I'd say this is something to expect if you want the curve to pass through the points.
If you don't need the curve to pass though the points, you can use a
I'd say this is something to expect if you want the curve to pass through the points.
If you don't need the curve to pass though the points, you can use a
TSmoothingFunction
with Interpolate:=false
as follows:Code: Select all
uses Chart, Series, TeeSpline;
var Chart1: TChart;
procedure TForm1.FormCreate(Sender: TObject);
begin
Chart1:=TChart.Create(Self);
with Chart1 do
begin
Parent:=Self;
Align:=alClient;
Color:=clWhite;
Gradient.Visible:=False;
Walls.Back.Color:=clWhite;
Walls.Back.Gradient.Visible:=False;
Legend.Hide;
View3D:=False;
Axes.Left.SetMinMax(-1, 4);
Axes.Left.Increment:=1;
Axes.Bottom.Grid.Hide;
end;
with TLineSeries(Chart1.AddSeries(TLineSeries)) do
begin
Pointer.Show;
Pointer.Size:=2;
DrawStyle:=dsCurve;
Add(0);
Add(0);
Add(3);
Add(0);
Add(0);
Add(2);
Add(2);
Add(0);
Add(1);
Add(0);
Add(0);
end;
with TLineSeries(Chart1.AddSeries(TLineSeries)) do
begin
FunctionType:=TSmoothingFunction.Create(Self);
with TSmoothingFunction(FunctionType) do
begin
Interpolate:=False;
Factor:=6;
end;
DataSource:=Chart1[0];
end;
end;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |
Re: TChart Line Chart Series with DrawStyle Curve Dips Below Zero - How to Fix?
Thank you so much for the response.
Please note, that I am expecting the curve to pass through the points because it will affect the presented information.
Thank you
V
Please note, that I am expecting the curve to pass through the points because it will affect the presented information.
Thank you
V
Re: TChart Line Chart Series with DrawStyle Curve Dips Below Zero - How to Fix?
Hello,
I've tried with a custom cubic spline, but it doesn't give the result I'd expect:
You could try to modify that algorithm or implement your own.
I've tried with a custom cubic spline, but it doesn't give the result I'd expect:
Code: Select all
uses Chart, Series;
var Chart1: TChart;
type TCoeficient = record
X, Y, b, c, d: Double;
end;
type TCoeficients = array of TCoeficient;
type TPoints = array of TPointFloat;
procedure CalculateCubicSplineCoefficients(const Points: TPoints; var Coefficients: TCoeficients);
var
N, i: Integer;
h: array of Double;
alpha, l, mu, z: array of Double;
c, b, d: array of Double;
begin
N := Length(Points) - 1;
SetLength(h, N);
SetLength(alpha, N);
SetLength(l, N);
SetLength(mu, N);
SetLength(z, N);
SetLength(c, N);
SetLength(b, N);
SetLength(d, N);
// Calculate h values
for i := 0 to N - 1 do
h[i] := Points[i + 1].X - Points[i].X;
// Calculate alpha, l, mu, and z values
for i := 1 to N - 1 do
begin
alpha[i] := (3.0 / h[i]) * (Points[i + 1].Y - Points[i].Y) - (3.0 / h[i - 1]) * (Points[i].Y - Points[i - 1].Y);
l[i] := 2.0 * (Points[i + 1].X - Points[i - 1].X) - h[i - 1] * mu[i - 1];
mu[i] := h[i] / l[i];
z[i] := (alpha[i] - h[i - 1] * z[i - 1]) / l[i];
end;
// Calculate c, b, and d values
for i := N - 1 downto 0 do
begin
c[i] := z[i] - mu[i] * c[i + 1];
b[i] := (Points[i + 1].Y - Points[i].Y) / h[i] - h[i] * (c[i + 1] + 2.0 * c[i]) / 3.0;
d[i] := (c[i + 1] - c[i]) / (3.0 * h[i]);
end;
// Store the coefficients
SetLength(Coefficients, N);
for i := 0 to N - 1 do
begin
Coefficients[i].X := Points[i].X;
Coefficients[i].Y := Points[i].Y;
Coefficients[i].c := c[i];
Coefficients[i].b := b[i];
Coefficients[i].d := d[i];
end;
end;
procedure GenerateSmoothCurve(const Coefficients: TCoeficients; var SmoothCurve: TPoints);
var
i, j: Integer;
t: Double;
begin
// Calculate the smooth points along the curve
SetLength(SmoothCurve, 0);
for i := 0 to High(Coefficients) - 1 do
begin
for j := 0 to 100 do // 100 points between each pair of input points
begin
t := j / 100;
SetLength(SmoothCurve, Length(SmoothCurve) + 1);
SmoothCurve[High(SmoothCurve)].X := Coefficients[i].X + t * (Coefficients[i + 1].X - Coefficients[i].X);
SmoothCurve[High(SmoothCurve)].Y :=
Coefficients[i].Y + t * (Coefficients[i + 1].Y + t * (Coefficients[i + 1].b + t * Coefficients[i + 1].c)) + t * t *
(Coefficients[i + 1].d);
end;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
data: TPoints;
coeficients: TCoeficients;
begin
Chart1:=TChart.Create(Self);
with Chart1 do
begin
Parent:=Self;
Align:=alClient;
Color:=clWhite;
Gradient.Visible:=False;
Walls.Back.Color:=clWhite;
Walls.Back.Gradient.Visible:=False;
Legend.Hide;
View3D:=False;
Axes.Left.SetMinMax(-1, 4);
Axes.Left.Increment:=1;
Axes.Bottom.Grid.Hide;
end;
with TPointSeries(Chart1.AddSeries(TPointSeries)) do
begin
Pointer.Size:=2;
Add(0);
Add(0);
Add(3);
Add(0);
Add(0);
Add(2);
Add(2);
Add(0);
Add(1);
Add(0);
Add(0);
end;
// Calculate cubic spline
SetLength(data, Chart1[0].Count);
for i:=0 to Chart1[0].Count-1 do
begin
data[i].X:=Chart1[0].XValue[i];
data[i].Y:=Chart1[0].YValue[i];
end;
CalculateCubicSplineCoefficients(data, coeficients);
GenerateSmoothCurve(coeficients, data);
with TLineSeries(Chart1.AddSeries(TLineSeries)) do
for i:=0 to High(data) do
AddXY(data[i].x, data[i].y);
end;
Best Regards,
Yeray Alonso Development & Support Steema Software Av. Montilivi 33, 17003 Girona, Catalonia (SP) | |
Please read our Bug Fixing Policy |