Page 1 of 1

Direct Access to Color Grid Values

Posted: Mon Jan 04, 2016 7:08 pm
by 16573504
Hi.

We are trying to optimize the performance of TColorGrid and are wondering about the usage of the "Values" property. Internally it always seems to call AddXYZ - regardless if the value already existed.

Is there no way to only update the color values of a grid?

Example:

Code: Select all

const double xStepWidth = 1.0, yStepWidth = 1.0;
double yCurrent = 0.0;
for(unsigned y = 0; y < data_.size(); ++y)
{
   double xCurrent = 0.0;
   for(unsigned x = 0; x < data_[y].size(); ++x)
   {
      if(update)
         series->Value[xCurrent][yCurrent] = data_[y][x];
      else
         series->AddXYZ(xCurrent, data_[y][x], yCurrent);

      xCurrent += xStepWidth;
   }

   yCurrent += yStepWidth;
}
If the flag "update" is true internally AddXYZ still is called.

Thanks.

Re: Direct Access to Color Grid Values

Posted: Tue Jan 05, 2016 12:35 pm
by yeray
Hello,

Look at the TCustom3DGridSeries.SetValue procedure:

Code: Select all

procedure TCustom3DGridSeries.SetValue(X, Z: Integer;
  const Value: TChartValue);
var tmp : Integer;
begin
  if IDirtyGrid then
     AddXYZ(x,Value,z)
  else
  begin
    tmp:=GridIndex[x,z];

    if tmp<>-1 then YValues.Value[tmp]:=Value
               else GridIndex[x,z]:=AddXYZ(x,Value,z);
  end;
end;
It calls AddXYZ when it doesn't find a value at the given [X, Z] point.
Note GridIndex may not have index 0 populated; so the way to manipulate it would be:

Code: Select all

var i, tmpMinX, tmpMinZ: Integer;
begin
  tmpMinX:=Round(Series1.XValues.MinValue)-1;
  tmpMinZ:=Round(Series1.ZValues.MinValue)-1;

  for i:=0 to Series1.Count-1 do
    Series1.Value[ Round(Series1.XValues.Value[i])-tmpMinX,
                   Round(Series1.ZValues.Value[i])-tmpMinZ]:=random*1.5-0.5;
end;
ix07 wrote:Is there no way to only update the color values of a grid?
If you want use the ColorRange feature, so to change the colors manipulating the YValues, you can call this after manipulating the Value array as in the snipped above to force the series to be redrawn:

Code: Select all

  Series1.RefreshSeries;
  Series1.Repaint;
To directly assign a color in a series point, in general you should set the ValueColor array. Ie:

Code: Select all

var i, tmpMinX, tmpMinZ: Integer;
begin
  for i:=0 to Series1.Count-1 do
  begin
    Series1.ValueColor[i]:=RGB(round(random*255), round(random*255), round(random*255));
  end;
end;