Delphi 创建面积图,使用其他颜色为溢出值的部分着色

Delphi 创建面积图,使用其他颜色为溢出值的部分着色,delphi,teechart,Delphi,Teechart,你能帮我创建面积图吗?图的顶部有其他颜色?我想指出,任何数值上的值都是至关重要的 这是一个屏幕截图: 我创建了两个面积图,但正如您所见,每个图都有自己的左轴。最好的解决方案是在特定值上方为图表着色。有一个名为TSeriesBandTool的工具,只需稍加努力即可完成此操作 添加一个额外的系列,使其与您的系列相同,但具有最大限制 这是它在工具编辑器中的外观: 它将用您选择的颜色填补两个系列之间的差异 更新 进行了概念验证,请参见图片 添加了第三个系列和第二个TSeriesBandTool,用第

你能帮我创建面积图吗?图的顶部有其他颜色?我想指出,任何数值上的值都是至关重要的

这是一个屏幕截图:


我创建了两个面积图,但正如您所见,每个图都有自己的左轴。最好的解决方案是在特定值上方为图表着色。

有一个名为TSeriesBandTool的工具,只需稍加努力即可完成此操作

添加一个额外的系列,使其与您的系列相同,但具有最大限制

这是它在工具编辑器中的外观:

它将用您选择的颜色填补两个系列之间的差异

更新

进行了概念验证,请参见图片

添加了第三个系列和第二个TSeriesBandTool,用第二种颜色填充底部。 我相信用更少的代码是可以做到的,但这对于演示来说已经足够好了

更新2

做了一些代码点心

更新2.5

现在还可以处理任意X值,而不仅仅是整数

代码如下:

uses Series, TeeTools, TeeSeriesBandTool;

Procedure DrawLimitAreaChart(S1, S2, S3: TLineSeries; YLimit: Double;
  BT1, BT2: TSeriesBandTool; OutlineWidth: Integer;
  OutlineCL, TopCl, BottomCL: TColor);
Var
  i: Integer;
  iX: Double;
Begin
  S1.LinePen.Width := OutlineWidth;
  S1.Color := OutlineCL;
  S2.Color := OutlineCL;
  S3.Color := OutlineCL;
  for i := 0 to S1.Count - 1 do
    if (S1.YValue[i] > YLimit) then
    begin
      if (i > 0) and (S1.YValue[i - 1] < YLimit) then
      begin // Last point below limit
        iX := (S1.XValue[i] - S1.XValue[i - 1]) * (YLimit - S1.YValue[i - 1]) /
          (S1.YValue[i] - S1.YValue[i - 1]) + S1.XValue[i - 1];
        S2.AddXY(iX, YLimit);
        if (i < S1.Count - 1) then
          Continue;
      end;
      S2.AddXY(S1.XValue[i], YLimit); // Set to Ylimit
    end
    else // Below Ylimit
    begin
      if (i > 0) and (S1.YValue[i - 1] > YLimit) then
      begin // Last point above limit
        iX := (S1.XValue[i] - S1.XValue[i - 1]) * (YLimit - S1.YValue[i - 1]) /
          (S1.YValue[i] - S1.YValue[i - 1]) + S1.XValue[i - 1];
        S2.AddXY(iX, YLimit);
      end;
      S2.AddXY(S1.XValue[i], S1.YValue[i]);  // Same value
    end;

  for i := 0 to S2.Count - 1 do
  begin
    S3.AddXY(S2.XValue[i], 0.0);
  end;

  { - First TSeriesBandTool }
  BT1.Series := S1;
  BT1.Series2 := S2;
  BT1.Brush.BackColor := TopCl;
  BT1.DrawBehindSeries := True;
  BT1.Transparency := 50;

  { - Second TSeriesBandTool }
  BT2.Series := S2;
  BT2.Series2 := S3;
  BT2.Brush.BackColor := BottomCL;
  BT2.DrawBehindSeries := True;
  BT2.Transparency := 50;

End;

procedure TForm1.Button1Click(Sender: TObject);
const
  // Example data
  YVAL: array [0 .. 10] of Double = (10,40,45,20,48,5,47,47,47,47,30);
var
  i: Integer;
  YLimit: Double;
  S1, S2, S3: TLineSeries;
begin
  Chart1.SeriesList.Clear;
  S1 := TLineSeries.Create(Self); // Contains real data
  Chart1.AddSeries(S1);
  S2 := TLineSeries.Create(Self); // Data below Ylimit
  Chart1.AddSeries(S2);
  S3 := TLineSeries.Create(Self); // baseline data
  Chart1.AddSeries(S3);
  for i := 0 to 10 do
    S1.AddXY(i, YVAL[i]);
  YLimit := S1.MaxYValue * 0.75;
  DrawLimitAreaChart(S1, S2, S3, YLimit, ChartTool1, ChartTool2, 2, clBlack,
    TColor($0024FF){clOrangeRed}, TColor($FF4D4D){clNeonBlue});

end;
使用系列、三通工具、三通系列工具;
程序绘图限制区域图(S1、S2、S3:T线性系列;YLimit:Double;
BT1,BT2:TSeriesBandTool;大纲宽度:整数;
大纲图、顶部CL、底部CL:t颜色);
变量
i:整数;
九:双份;;
开始
S1.LinePen.Width:=大纲宽度;
S1.颜色:=大纲图;
S2.颜色:=大纲图;
S3.颜色:=大纲图;
对于i:=0到S1。计数-1 do
如果(S1.YValue[i]>YLimit),那么
开始
如果(i>0)和(S1.y值[i-1]0)和(S1.YValue[i-1]>YLimit),那么
开始//超出极限的最后一点
iX:=(S1.XValue[i]-S1.XValue[i-1])*(YLimit-S1.YValue[i-1])/
(S1.YValue[i]-S1.YValue[i-1])+S1.XValue[i-1];
S2.AddXY(iX,YLimit);
结束;
S2.AddXY(S1.XValue[i],S1.YValue[i]);//相同值
结束;
对于i:=0到S2。计数-1 do
开始
S3.AddXY(S2.XValue[i],0.0);
结束;
{-First TSeriesBandTool}
BT1.系列:=S1;
BT1.Series2:=S2;
BT1.Brush.BackColor:=TopCl;
BT1.DrawBehindSeries:=真;
BT1.透明度:=50;
{-Second TSeriesBandTool}
BT2.系列:=S2;
BT2.Series2:=S3;
BT2.Brush.BackColor:=BottomCL;
BT2.DrawBehindSeries:=真;
BT2.透明度:=50;
结束;
程序TForm1.按钮1单击(发送方:TObject);
常数
//示例数据
YVAL:Double=(10,40,45,20,48,5,47,47,47,30)的数组[0..10];
变量
i:整数;
YLimit:双;
S1,S2,S3:t线性系列;
开始
图表1.SeriesList.Clear;
S1:=TLineSeries.Create(Self);//包含真实数据
图1.AddSeries(S1);
S2:=TLineSeries.Create(Self);//Ylimit下面的数据
图1.AddSeries(S2);
S3:=TLineSeries.Create(Self);//基线数据
图1.AddSeries(S3);
对于i:=0到10 do
S1.AddXY(i,YVAL[i]);
YLimit:=S1.MaxYValue*0.75;
DrawLimitAreaChart(S1、S2、S3、YLimit、ChartTool1、ChartTool2、2、clBlack、,
t颜色($0024FF){clOrangeRed},t颜色($FF4D4D){clNeonBlue});
结束;
那么代码的作用是:

将X、Y数据填入系列[0]。 调用
DrawLimitAreaChart
过程,其中从系列[0]计算新系列,以使任何部分都不在Ylimit之上。最后,将第三个系列用作第二个系列的基线。这三条曲线与两个
TSeriesBandTools
一起构成了一个双色区域面积图

更新3

根据要求,这里有一个以X轴为时间轴的图表示例。这样做的代码在我下面的评论中


通过添加带有彩色条纹的自定义图表背景图片,多次完成此操作。如果y刻度是固定的,这是一个屏幕截图:我创建了两个面积图,但正如你所看到的,每个图都有自己的左轴。最好的解决方案是在特定值上方的图表上色。谢谢大师:)我如何在时间间隔内按数据输入图表?这个过程很好:procedure AddChartValue(ATime:TDateTime;AValue:integer);AddChartValue('12:00:00',30);AddChartValue('12:00:10',40);AddChartValue('12:00:20',20)。。。AddChartValue('12:01:50',20)。。。。当然,我必须设置最大“x”值以显示最大值,例如60秒,更多数据将降低图表的清晰度。我有一个答案给你(请删除Ken指出的问题的其他答案)。设置
S1.XValues.DateTime:=True
图表1.BottomAxis.DateTimeFormat:=“nn:ss”
或您喜欢的任何其他格式。将X值添加为TDateTime格式,即
S1.AddXY(现在+XVAL[i]/(24*60*60),YVAL[i])。我希望它对您有用。不要忘记接受答案,请参阅。我尝试手动添加一个项目过程TfrmQueueMonitor.Button1Click(发件人:ToObject);varⅠ:整数;YLimit:双;开始dbChart.Series[0].AddXY(strotime('12:00:10'),50);dbChart.Series[0].AddXY(strotime('12:00:20'),20);dbChart.Series[0].AddXY(标准时间('12:00:30'),80);YLimit:=30;DrawLimitAreaChart(dbChart.Series[0]作为TLineSeries,dbChart.Series[1]作为TLineSeries,dbChart.Series[2]作为TLineSeries,YLimit,ChartTool1,ChartTool2,2,clBlack,TColor($0024FF){clOrangeRed},TColor($FF4D4D){clNeonBlue});结束;但它显示12个X值,为什么?在输入按钮1单击之前,您确定序列为空吗?否则调用
dbChart.Series[0]。清除;dbChart.Series[1]。清除;dbChart.Ser