amibroker

Home ▸ Knowledge Base

How to convert from bar-value to pixel co-ordinates

NOTE: This article describes old method of using bar/value coordinates. New code should use GfxSetCoordsMode which allows you to use bar/value without any extra calculations.

Sometimes when using low-level graphics functions it is needed to convert from bar number to pixel X co-ordinate and from price level to pixel Y co-ordinate. Converting between them needs knowing visible bar range, Y-axis value range and pixel dimensions of drawing area. Once these params are known it is just a matter of performing simple scale transformation. The code example below shows how to do that.

function GetVisibleBarCount()
{
 
lvb = Status("lastvisiblebar");
 
fvb = Status("firstvisiblebar"); 

 return 
Min( Lvb - fvb, BarCount - fvb );
} 

function 
GfxConvertBarToPixelX( bar )
{
 
lvb = Status("lastvisiblebar");
 
fvb = Status("firstvisiblebar");
 
pxchartleft = Status("pxchartleft");
 
pxchartwidth = Status("pxchartwidth"); 

 return 
pxchartleft + bar  * pxchartwidth / ( Lvb - fvb + 1 );
} 

function 
GfxConvertValueToPixelY( Value )
{
 
local Miny, Maxy, pxchartbottom, pxchartheight; 

 
Miny = Status("axisminy");
 
Maxy = Status("axismaxy"); 

 
pxchartbottom = Status("pxchartbottom");
 
pxchartheight = Status("pxchartheight"); 

 return 
pxchartbottom - floor( 0.5 + ( Value - Miny ) * pxchartheight/ ( Maxy - Miny ) );
} 

Plot(C, "Price", colorBlack, styleHistogram ); 

GfxSetOverlayMode(0);
GfxSelectSolidBrush( colorRed );
GfxSelectPen( colorRed ); 

AllVisibleBars = GetVisibleBarCount();
fvb = Status("firstvisiblebar"); 

for( 
i = 0; i < AllVisibleBars ; i++ ) 
{ 
  
x = GfxConvertBarToPixelX( i ); 
  
y = GfxConvertValueToPixelY( C[ i + fvb ] ); 

  
GfxRectangle( x-1, y-1, x + 2, y+1 ); 
} 

RequestTimedRefresh(1); // ensure 1 sec refres

Note that when chart scale changes, it will usually require one extra refresh to get low-level graphics alignment to new scale. That’s why we added RequestTimedRefresh call at the end.