How to put Text in Ribbon

Hi,

I want to put text in Ribbon. Instead of just colors. Here is a sample Implementation:

As you can see the Ribbon not only has Separating Color but also Text inside. How Can this be achieved with AFL?

1 Like

Yes, that is doable.

But in order to plot it nicely it looks better via Gfx functions instead of using Plot() plus PlotText().

Anyway, in order to have it look like in your picture one thing is that you have to make text disappear if a ribbon portion of a signal becomes too small so that text does not fit into the ribbon portion anymore. Also text would overlap with other text in such cases where length of ribbon parts decreases drastically. So in order to measure text width and to compare it with pixel width of ribbon portion you have to use GfxGetTextWidth function https://www.amibroker.com/guide/afl/gfxgettextwidth.html

In the picture below you can see that it is possible. Text nicely disappears automatically if ribbon parts become too small (i.e. if zooming out). There it has been done via Gfx plot completely.

Of course you can plot ribbon with Plot() function too
https://www.amibroker.com/guide/afl/plot.html
and can plot text on it via PlotText() & PlotTextSetFont
https://www.amibroker.com/guide/afl/plottext.html
https://www.amibroker.com/guide/afl/plottextsetfont.html

But you can't mix y-coordinate as pixel with x-coordinate as bar index with those three functions. AFAIK the height of ribbons using Plot() can only be percentages of pane height. So for example if you decrease pane height then ribbon height can become shorter than text height. Maybe Tomasz could confirm whether or not there is a way to set a fix pixel height via Plot() function. I don't think you can.

In Gfx you can do mix coordinate modes quite nicely via GfxSetCoordsMode() function
https://www.amibroker.com/guide/afl/gfxsetcoordsmode.html
See mode 3 for example.

The question you could ask yourself... Is it really necessary to plot text on ribbon?

Anyway here is a code snippet of the method using Plot() and PlotText together with GfxGetTextWidth

procedure PlotRibbonAndText( signal1, signal2, caption1, caption2, color1, color2, bordercolor )
{
// This is NOT the full code of the function but just a snippet
// originally from amibroker forum thread 
/// @link http://forum.amibroker.com/t/how-to-put-text-in-ribbon/1093
//...
	bi = Barindex();
	fvb = FirstVisibleValue( bi );
	lvb = LastVisibleValue( bi );

	width1 = GfxGetTextWidth( caption1 );
	width2 = GfxGetTextWidth( caption2 );

	miny = Status( "axisMiny" );
	maxy = Status( "axisMaxy" );
	y = Status( "axisMiny" ) + 0.01*(maxy-miny);

	Plot( 4, "", IIf( signal1, color1, IIf( signal2, color2, -1 ) ), styleArea | styleNoLabel | styleOwnScale, 0, 100 ); 
	
	PlotTextSetFont( "", "ARIAL", 9, BarCount-1, 0, -1 );
	for( i = fvb; i <= lvb; i++ ) {	
		if( endcond1[i] ) { 
			length1 = GfxBarToPixelX_C( endbar1[i]+0.5 ) - GfxBarToPixelX_C( startbar1[i] );
			if( length1 > width1 )
				PlotText( caption1, i-n1[i]+0.5, y, colorBlack );
		}
		if( endcond2[i] ) {
			length2 = GfxBarToPixelX_C( endbar2[i]+0.5 ) - GfxBarToPixelX_C( startbar2[i] );
			if( length2 > width2 )
				PlotText( caption2, i-n2[i]+0.5, y, colorBlack );
		}
	}
//...
}

Again, doing it fully via Gfx it will look nicer, IMO.

(Picture from using Gfx functionality completely)

11 Likes

Can you kindly tell me where I can find the missing function “GfxBarToPixelX_C” GfxBarToPixelX_C :slight_smile: please ?
I read 3 times your post, and did the search for the word GfxBarToPixelX_C in the forum but without success.
I also searched the function in the old forum but unsuccessful

Here is simplest self-contained (copy-paste ready) example of drawing text on ribbon with Gfx functions, together with price chart and the ribbon.
This example is meant to be simplest not the “nicest” but should give you starting point.

Version( 6.20 );
Plot( C, "Price", colorDefault, styleCandle );

Condition = MA( Close, 10 ) > MA( Close, 90 ); // data to plot the ribbon
Plot( 2, /* defines the height of the ribbon in percent of pane width */
 "Ribbon",
 IIf( Condition , colorGreen, colorRed ), /* choose color */
 styleOwnScale|styleArea|styleNoLabel, -0.5, 100 );
 
CChange = Condition != Ref( Condition, -1 );

bi = BarIndex();

fvb = Max( 0, FirstVisibleValue( bi ) );
lvb = Min( BarCount - 1, LastVisibleValue( bi ) );

GfxSetCoordsMode( 3 );

y = Status("pxchartbottom") - 3;

GfxSetTextAlign( 8 );
GfxSelectFont( "Arial", 8 );
GfxSetTextColor( colorWhite );
GfxSetBkMode( 1 );

for( i = fvb; i <= lvb; i++ )
{
	if( CChange[ i ] )
	{
		if( Condition[ i ] ) 
			text = "Up";
		else
			text = "Down";

		GfxTextOut( text, i, y );
	}
}
10 Likes