Page 1 of 1

Controlling the color of a series

Posted: Thu Jan 26, 2006 5:51 pm
by 9337074
I need to assign a specific color to specific values that appear on a graph. For instance, I have 5 colors that correspond to the values 1 thur 5. I want to have all points with the same value to have one specific color. Is there anyway to do that?

Posted: Fri Jan 27, 2006 9:30 am
by narcis
Hi McMClark,

Yes, you can do that using series OnGetPointerStyle event as shown here:

Code: Select all

procedure TForm1.FormCreate(Sender: TObject);
begin
  Series1.ColorEachPoint:=true;

  Series1.AddXY(10, 50);
  Series1.AddXY(20, 80);
  Series1.AddXY(30, 111);
  Series1.AddXY(40, 101);
  Series1.AddXY(50, 80);
  Series1.AddXY(60, 60);

  Chart1.Draw;
end;

function TForm1.Series1GetPointerStyle(Sender: TChartSeries;
  ValueIndex: Integer): TSeriesPointerStyle;
var tmp: Integer;
begin
  tmp:=Series1.YValues.Locate(Series1.YValue[ValueIndex]);

  if ((tmp <> -1) and (tmp <> ValueIndex)) then
    Series1.ValueColor[ValueIndex]:=Series1.ValueColor[tmp]
  else Series1.Valuecolor[ValueIndex]:=clTeeColor;

  result:=psRectangle;
end;

Posted: Fri Jan 27, 2006 7:22 pm
by 9337074
Thanks for your reply. I am a little slow. So forgive me.

I am using the following code to create the series at runtime:

tmpLineSeries := TLineSeries.Create(self);
DBChart1.AddSeries(tmpLineSeries);
With tmpLineSeries do
Begin
DataSource:= TempResults_Query1;
YValues.ValueSource := 'Score';
XLabelsSource := 'PublicationDate';
Pointer.Visible := False;
Title := strSubject;
end;

This is where I would like to add the code. How would I do that?

Posted: Mon Jan 30, 2006 9:56 am
by narcis
Hi McMClark,

I'd do something like:

Code: Select all

procedure TForm1.FormCreate(Sender: TObject);
var
  tmpLineSeries: TLineSeries;
  strSubject: String;
begin
  tmpLineSeries := TLineSeries.Create(self);
  DBChart1.AddSeries(tmpLineSeries);
  With tmpLineSeries do
  Begin
    DataSource:= TempResults_Query1;
    YValues.ValueSource := 'Score';
    XLabelsSource := 'PublicationDate';
    Pointer.Visible := False;
    Title := strSubject;

    CheckDataSource;
    OnGetPointerStyle:=Series1GetPointerStyle;
  end;

end;

function TForm1.Series1GetPointerStyle(Sender: TChartSeries;
  ValueIndex: Integer): TSeriesPointerStyle;
var tmp: Integer;
begin
  tmp:=Sender.YValues.Locate(Sender.YValue[ValueIndex]);

  if ((tmp <> -1) and (tmp <> ValueIndex)) then
    Sender.ValueColor[ValueIndex]:=Sender.ValueColor[tmp]
  else Sender.Valuecolor[ValueIndex]:=clTeeColor;

  result:=psRectangle;
end;

Posted: Tue Jan 31, 2006 9:23 pm
by 9337074
Thanks.

The event is firing and it is picking up the values of the points but the color is not changing.

I assume the code Sender.Valuecolor[ValueIndex]:=clTeeColor and
Sender.ValueColor[ValueIndex]:=Sender.ValueColor[tmp] effects the color? I changed the clTeeColor to clGreen just to see if the color changed and it did not. The points all turn out red. Please let me know what I can do. Thanks

Posted: Wed Feb 01, 2006 1:07 pm
by narcis
Hi McMClark,

You may need have to set your series ColorEachPoint property to true if you haven't done that.

Posted: Thu Feb 02, 2006 2:03 pm
by 9337074
Thanks. I tried that but I still coould not get it to work. But I did get the following to work except that the color changes only happen after I move the cursor into the chart area. Can you suggest why?

function TfrmGraphDocumentScoreDistribution.Series1GetPointerStyle(
Sender: TChartSeries; ValueIndex: Integer): TSeriesPointerStyle;
var
tmp: integer;
dbValue: Double;
strSeriesName: String;
intValue: integer;
begin
strSeriesName := Sender.Title;
tmp:=Sender.YValues.Locate(Sender.YValue[ValueIndex]);
intValue := Trunc(Sender.YValue[ValueIndex]);

Case intValue of
1: begin
Sender.ValueColor[ValueIndex] := clWhite;
end;
2: begin
Sender.ValueColor[ValueIndex]:= clPurple;
end;
3: begin
Sender.ValueColor[ValueIndex]:= clOlive;
end;
4: begin
Sender.ValueColor[ValueIndex]:= clYellow;
end;
5: begin
Sender.ValueColor[ValueIndex]:= clBlue;
end;
else
begin
Sender.Valuecolor[ValueIndex]:=clGreen;
end;
end;
result:=psRectangle;
end;

Posted: Thu Feb 02, 2006 2:37 pm
by narcis
Hi McMClark,

You need to force the chart being drawn as when GetPointerStyle event is fired for the first time while series are still being populated. The code below does what you request.

Code: Select all

procedure TForm1.FormCreate(Sender: TObject);
var i: Integer;
begin
  Series1.ColorEachPoint:=true;

  for i:=0 to 50 do
    Series1.Add(i mod 10);

  Chart1.Draw; //Forces the chart being drawn
end;

function TForm1.Series1GetPointerStyle(Sender: TChartSeries;
  ValueIndex: Integer): TSeriesPointerStyle;
var
//  tmp: integer;
//  dbValue: Double;
  strSeriesName: String;
  intValue: integer;
begin
  strSeriesName := Sender.Title;
//  tmp:=Sender.YValues.Locate(Sender.YValue[ValueIndex]);
  intValue := Trunc(Sender.YValue[ValueIndex]);

  Case intValue of
    1: begin
      Sender.ValueColor[ValueIndex] := clWhite;
    end;
    2: begin
      Sender.ValueColor[ValueIndex]:= clPurple;
    end;
    3: begin
      Sender.ValueColor[ValueIndex]:= clOlive;
    end;
    4: begin
      Sender.ValueColor[ValueIndex]:= clYellow;
    end;
    5: begin
      Sender.ValueColor[ValueIndex]:= clBlue;
    end;
    else
    begin
      Sender.Valuecolor[ValueIndex]:=clGreen;
    end;
  end;
  result:=psRectangle;
end;