GfxSetZOrder and GfxSetCoordsMode

I'm having trouble displaying text using Bar/Pixel and drawings using Bar/Price and the interactions between GfxSetZOrder and GfxSetCoordsMode.

I've found an example from a previous poster that illustrates my confusion.

In the screenshot below, the behaviour of the GfxSetZOrder and drawn rectangles are affected by the GfxSetCoordsMode being called after the drawing commands are issued.

ie.
case 1

case 2

Simply speaking, I want to do this pseudo code:

  • GfxSetCoordsMode( BarPrice )
  • draw a bunch of lines ( GfxMoveTo/LineTo, Gfx
  • GfxSetCoordsMode( BarPixel )
  • draw a bunch of text ( GfxTextOut, GfxDrawText )

I'm assuming that setting the ZOrder will allow me to draw text/lines above one another depending on the number given to the order function.

The example above demonstrates my confusion about what is happening. Why does GfxSetCoordsMode being set to 1 ( BarPrice ) affect what was drawn beforehand?

edit:
this is the full working code that I'm using above (I copied this from a previous discussion on a similar topic):

Title = "";
GfxZOrderOn = Param( "GfxZOrder",0, 0, 3, 1);

if( GfxZOrderOn == 0 ) {
	Zred = 3;
	ZGreen = 2;
	ZOrange = 1;
} else if( GfxZOrderOn == 1 ) {
	Zred = 3;
	ZGreen = 1;
	ZOrange = 2;
} else if( GfxZOrderOn == 2 ) {
	Zred = 2;
	ZGreen = 1;
	ZOrange = 3;
} else {
	Zred = 1;
	ZGreen = 2;
	ZOrange = 3;
}
GfxSetZOrder( Zred );
GfxGradientRect( 110, 70, 250, 250, colorWhite, colorRed );
GfxSetZOrder( ZGreen );
GfxGradientRect( 120, 70, 300, 300, colorWhite, colorGreen );
GfxSetZOrder( ZOrange );
GfxGradientRect( 140, 70, 250, 350, colorWhite, colorOrange );

GfxSetCoordsMode(1); // 1 - Bar/Price

Thanks,
Joe

You forgot to set GfxSetCoordsMode after GfxSetZOrder.
Correction:



GfxSetZOrder( Zred );
GfxSetCoordsMode(0); // 0 - Pixel
GfxGradientRect( 110, 70, 250, 250, colorWhite, colorRed );
GfxSetZOrder( ZGreen );
GfxSetCoordsMode(0); // 0 - Pixel
GfxGradientRect( 120, 70, 300, 300, colorWhite, colorGreen );
GfxSetZOrder( ZOrange );
GfxSetCoordsMode(0); // 0 - Pixel
GfxGradientRect( 140, 70, 250, 350, colorWhite, colorOrange );


GfxSetCoordsMode(1); // 1 - Bar/Price
2 Likes

I believe I have a theory consistent with my testing.

  1. Z Order is applied from small to large so if the range is -128 to 128 it is applied in order.

  2. The last call to GfxSetCoordsMode is used in applying coords mapping for the z layer it's on and also for every layer after.

So in case 2 above, the ZOrange is called first, the coords mode defaults to 0 pixel/pixel and draws correctly. However, GfxSetCoordsMode changes the coords to bar/price for all subsequent layers because there are no other setcoords in those layers.

Said simply, do what fxshrat said above, declare the coords mode for each layer, before starting to draw and after entering the layer with GfxSetZOrder.

Thanks @fxshrat this is the same conclusion I came to, I was going to respond to saying that you can't set the coords before the call to z order, because of the following:

Title = "";
GfxZOrderOn = Param( "GfxZOrder",0, 0, 3, 1);

if( GfxZOrderOn == 0 ) {
	Zred = 3;
	ZGreen = 2;
	ZOrange = 1;
} else if( GfxZOrderOn == 1 ) {
	Zred = 3;
	ZGreen = 1;
	ZOrange = 2;
} else if( GfxZOrderOn == 2 ) {
	Zred = 2;
	ZGreen = 1;
	ZOrange = 3;
} else {
	Zred = 1;
	ZGreen = 2;
	ZOrange = 3;
}

GfxSetCoordsMode(0);

GfxSetZOrder( Zred );
GfxGradientRect(100, 70, 250, 200, colorWhite, colorRed);

GfxSetCoordsMode(1);
GfxSetZOrder( ZGreen );
GfxRectangle( 0, 1927, 250000, 1931);

GfxSetZOrder( ZGreen );
//GfxSetCoordsMode(0);
GfxGradientRect( 120, 70, 300, 300, colorWhite, colorGreen );
//GfxSetCoordsMode(1);


GfxSetZOrder( ZOrange );
//GfxSetCoordsMode(0);
GfxGradientRect( 140, 70, 250, 350, colorWhite, colorOrange );

GfxSetCoordsMode(0); // if this line is before the SetZOrder(5), "text out" is inconsistently set depending on the order of what layers come before it
GfxSetZOrder(5);
GfxSetTextColor(colorWhite);
GfxTextOut("Text out", 90, 100);

GfxSetCoordsMode(1);

//GfxSetZOrder(100);
Plot(C, "Price", colorAqua);

In the above code, switching the GfxSetCoordsMode(0); and GfxSetZOrder(5); affects what is rendered, depending on what happens to the other layers.

1 Like

When you set a Z order you are essentially telling AmiBroker to perform all subsequent Gfx functions on that layer. Whatever you called before setting z order applies to previously selected layer, or layer 0 if you did not set Z order at all.

Technically setting Z order changes the order in which recorded gfx commands are executed as in order to display Z ordered plots properly you need to draw backwards, from bottom to top.

3 Likes