4

グラフの一部(上)が他の色になっている面グラフの作成を手伝ってもらえますか?任意の数値を超える値が重要であることを示したいと思います。

これはスクリーンショットです: ここに画像の説明を入力

2 つの面グラフを作成しましたが、ご覧のとおり、各グラフには独自の左軸があります。最良の解決策は、特定の値の上にチャートを着色することです。

4

1 に答える 1

7

ちょっとした作業でこれを行うことができる TSeriesBandTool というツールがあります。

追加のシリーズを追加して、シリーズと同じにしますが、最大制限があります。

ツール エディタでは次のように表示されます。

ここに画像の説明を入力

2つのシリーズの違いをお好みの色で埋めてくれます。

アップデート

概念実証を行いました。画像を参照してください。

3 番目の Series と 2 番目の TSeriesBandTool を追加して、下部を 2 番目の色で塗りつぶしました。より少ないコードで実行できると確信していますが、デモにはこれで十分です。

更新 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] に入力します。DrawLimitAreaChartYlimit を超える部分がないように、series[0] から新しいシリーズを計算するプロシージャを呼び出します。最後に、3 番目のシリーズが 2 番目のシリーズのベースラインとして適用されます。3 つの曲線と 2 つの曲線が合わさって、TSeriesBandTools2 色の領域面グラフが形成されます。

アップデート 3

リクエストに応じて、X 軸を時間としたグラフの例を次に示します。これを行うためのコードは、以下の私のコメントにあります。

ここに画像の説明を入力

于 2012-04-14T09:06:11.923 に答える