加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

delphi – 创建区域图,用其他颜色着色溢出值的部分

发布时间:2020-12-15 09:20:07 所属栏目:大数据 来源:网络整理
导读:你能帮我创建区域图表,图表的部分(顶部)有其他颜色吗?我想指出,任何数值的值都是至关重要的. 这是一个截图: 我创建了两个面积图,但正如您所看到的,每个图表都有自己的左轴.最好的解决方案是将图表着色到特定值之上. 解决方法 有一个名为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,30);
var
  i: Integer;
  YLimit: Double;
  S1,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,S3,YLimit,ChartTool1,ChartTool2,2,clBlack,TColor($0024FF){clOrangeRed},TColor($FF4D4D){clNeonBlue});

end;

那么代码的作用是什么:

将X,Y数据填入系列[0].
调用DrawLimitAreaChart过程,其中从series [0]计算新系列,使得没有任何部分在Ylimit之上.最后,第三个系列被用作第二个系列的基线.三条曲线与两个TSeriesBandTools现在形成一个双色区域面积图.

更新3

根据要求,这里是一个图表示例,X轴为时间.执行此操作的代码在下面的评论中.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读