【问题标题】:Creating area chart coloring the part of overflowed values with other color创建面积图用其他颜色着色溢出值的部分
【发布时间】:2012-04-26 07:40:42
【问题描述】:

你能帮我创建面积图吗,图表的部分(顶部)有其他颜色?我想指出任何数值上的值都很关键。

这是截图:

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

【问题讨论】:

  • 通过添加带有彩色条纹的自定义图表背景图片完成了几次。如果 y 比例是固定的,则可以使用。
  • 这是一个截图:imageshack.us/photo/my-images/84/58337625.png 我已经创建了两个面积图,但是正如你所看到的,每个图表都有自己的左轴。最好的解决方案是在特定值之上着色图表。

标签: delphi teechart


【解决方案1】:

有一个名为 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;

那么代码做了什么:

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

更新 3

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

【讨论】:

  • 谢谢大师 :) 如何按时间间隔按数据提供图表?该过程会很好: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 秒,更多数据会降低图表的清晰度。
  • 我有一个答案给你(请删除你对肯指出的问题的其他答案)。设置S1.XValues.DateTime := True;Chart1.BottomAxis.DateTimeFormat := 'nn:ss'; 或您喜欢的任何其他格式。将 X 值添加为 TDateTime 格式,即S1.AddXY(Now + XVAL[i]/(24*60*60), YVAL[i]);
  • 我希望它对你有用。不要忘记接受答案,请参阅faq#howtoask
  • 我试图手动添加一个项目过程 TfrmQueueMonitor.Button1Click(Sender: TObject);变量 i:整数; Y 限制:双倍;开始 dbChart.Series[0].AddXY(StrToTime('12:00:10'), 50); dbChart.Series[0].AddXY(StrToTime('12:00:20'), 20); dbChart.Series[0].AddXY(StrToTime('12:00:30'), 80); Y限制:= 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 个 xvalues,为什么?
  • 在进入 Button1Click 之前你确定系列是空的吗?否则,您在 Button1Click 中做的第一件事就是调用 dbChart.Series[0].Clear; dbChart.Series[1].Clear; dbChart.Series[2].Clear;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-16
  • 2014-07-02
  • 2021-09-11
  • 2019-05-02
相关资源
最近更新 更多