Move text across chart screen continuously or display text every n seconds

In HTML marquee tag is used.

<marquee>Amibroker Rocks! Thanks Tomasz and team....</marquee>

Reference Link

Is there a way to procure the same in Amibroker Charts?

Unable to fathom a loop using lvb or pxchartwidth.

Much appreciated !

1 Like

Hello,

Here is something to try, probably not the most elegant or even correct,
but it dose move text across the screen.

// overlay mode = 1 means that 
// Low-level gfx stuff should come in background 
GfxSetOverlayMode(1); 

Plot(C, "Close", colorBlack, styleCandle ); 


k = (GetPerformanceCounter()/100)%256; 
for( i = 0; i < 256; i++ ) 
{ 
  
GfxSelectFont("Tahoma", 20, 500 ); 
GfxSetBkMode(1); 
GfxSetTextColor(colorBlue); 
GfxTextOut("text",  10 + k + 200, 10  );
} 

Anthony

1 Like

Hello Lennon
you mean somethink like that?

But remeber… RequestTimedRefresh() execute all of your AFL. So make a function to run Only for your text

RequestTimedRefresh( 0.1 );
k = ( -GetPerformanceCounter() / 100 ) % 300;
//printf("GetPerformance Counter %g",k);  // Interpritation
GfxDrawText( "Amibroker Rocks! Thanks Tomasz and team....", left = 142 + k, top = 50, right = 142, bottom = 70, format = 0 );

Edit: Sorry @Anthony i did see you already gave the answer.

3 Likes

Hello,

I have edited the first version. I was unable to edit the posted code above, Here
is another version.

// overlay mode = 1 means that 
// Low-level gfx stuff should come in background 
GfxSetOverlayMode(1); 

Plot(C, "Close", colorBlack, styleCandle ); 


k = (GetPerformanceCounter()/100)%500; 
for( i = 0; i < 500; i++ ) 
{ 
  
GfxSelectFont("Tahoma", 20, 500 ); 
GfxSetBkMode(1); 
GfxSetTextColor(colorBlue); 
GfxTextOut("Amibroker Rocks! Thanks Tomasz and team....",   k , 10  );
} 

Anthony

Great job @PanoS

3 Likes

Thanks @Anthony and @PanoS for introducing GetPerformanceCounter() to me…

Little bit of this, little bit of that…

pxchartwidth = Status( "pxchartwidth" );
pxchartheight = Status( "pxchartheight" );

procedure GfxCustomTextOut( txt, fnt, fntsize, fntweight, fntColor, txtBackColor, X, Y )
{
	 GfxSetBkMode( 2 );
	 GfxSetTextAlign( 0 | 0 );
	 GfxSetBkColor( txtBackColor );
	 GfxSetTextColor( fntColor );
	 GfxSelectFont( fnt, fntsize, fntweight, 0, 0, 0 );
	 GfxTextOut( txt, X, Y );
}

GfxSetOverlayMode( 0 );
Plot(C, "Close", colorBlack, styleCandle );

speed = Param( "Speed", 100, 10, 100 );
dir = ParamToggle( "Direction of text", "Right to Left|Left to Right", 0 );
direction = IIf( dir, 1, -1 );

Text = "!!! YOU ARE NOT ALLOWED TO FEEL GOOD OR BAD !!! DO NOT ENTER BEFORE PRICE REVERSES IN DESIRED DIRECTION !!! CONSIDER RISK BEFORE ENTRY !!! HAVE PATIENCE !!! STOP PREDICTING !!! KEEP CALM. BE COOL !!! ALL THAT MATTERS IS THE NEXT WIN !!!";
Font = "Courier New";
FontSz = 12;
FontWght = 700;
FontClr = colorWhite;
TextBkClr = colorDarkBlue;

k = ( ( direction * GetPerformanceCounter() ) / speed ) % pxchartwidth;

GfxCustomTextOut( Text, Font, FontSz, FontWght, FontClr, TextBkClr, k, pxchartheight - 8 );

RequestTimedRefresh( 0.1 );

As Anthony mentioned, this trick is very restricting since the start position and end position of the marquee text are not precise.

I am a fan of VSA, and use “Guru Commentary” to show implications of factual data. But not in favour of viewing the texts on a separate area. So, was wondering if commentary texts (or simply texts) could be used as a marquee scrolling at the bottom of the chart.

Commentary as marquee will have two advantages:

  1. Save chart window area;
  2. If multiple screen(s) used, then, eyes can focus on the main chart only, slight glance to the bottom would be enough.

Thanks again both of you !

Enjoy your weekend !

1 Like

Text - (affirmations in this case) :slight_smile: moving across the screen looks nice, but the chart needs to be refreshed frequently to achieve a smooth move. The more refreshes per second, the better it looks. Lots of refreshes causes lots of processor overhead. If the main formula is simple, that may not be a big problem (nevertheless unnecessary refreshes should always be avoided), but if you force AmiBroker to unnecessary refresh 10 times per second a complex formula (only to display a simple text) it is definitly not a good idea :wink:

Because I always try to make my codes as light as possible, I would like to propose a different approach, which is very light and CPU friendly, because it doesn't need any extra refreshes at all!

You can find a RequestTimedRefresh( 1 ); function in it, but it is there only for presentation purposes . If your charts are regurarly refreshed because for example you work online, you don't need it (this line can be commented or deleted).

Via Chart's Parameters you can choose how long each text is displayed, if it is highlighted or not in the first few seconds after being displayed, change the text's size, color and font name. The text can also be moved around the screen.

Here's the code:

_SECTION_BEGIN( "Text displayed every n-seconds" );

/// @link http://forum.amibroker.com/t/move-text-across-chart-screen-continuously/1579
// -----------------   Milosz Mazurkiewicz  ----------------

AffirmationsOn = ParamToggle( "Affirmations", "Off|On", 1 );
Frequency = Param( "Frequency (sec.)", 5, 1, 120, 1 );
TextColor = ParamColor( "Text color", colorGreen );
TextSize = Param( "Text size", 11, 4, 50, 1 );
TextFont = ParamStr( "Text Font", "Tahoma" );
TextHighlight = ParamToggle( "Text Highlight", "No|Yes", 1 );
HighlightTime = Param( "Text highlight (sec.)", 2, 1, 20, 1 );
HighlightColor = ParamColor( "Highlight color", colorYellow );
XShift = Param( "X Shift", 0, -2000, 2000, 1 );
YShift = Param( "Y Shift", 0, -200, 2000, 1 );
ChartID = GetChartID();

if( AffirmationsOn )
{
    PerformanceCounterBefore = Nz( StaticVarGet( "PerformanceCounterBefore" + ChartID ) );
    PerformanceCounterNow = GetPerformanceCounter() / 1000;
    ElapsedSeconds =  PerformanceCounterNow - PerformanceCounterBefore;
    CycleCounter = Nz( StaticVarGet( "CycleCounter" + ChartID ) );
    Pxwidth = Status( "pxwidth" );
    Pxheight = Status( "pxheight" );
    ExtraHighlight = 0;
    
	// List of comma "," separated texts/affirmations :
    Affirmations = "YOU ARE NOT ALLOWED TO FEEL GOOD OR BAD !!!,DO NOT ENTER BEFORE PRICE REVERSES IN DESIRED DIRECTION !!!,CONSIDER RISK BEFORE ENTRY !!!,HAVE PATIENCE !!!,STOP PREDICTING !!!,KEEP CALM - BE COOL !!!,ALL THAT MATTERS IS THE NEXT WIN !!!";
    AffirmationsCount = StrCount( Affirmations, "," ) + 1;

    if( ElapsedSeconds >= Frequency )
    {
        StaticVarSet( "PerformanceCounterBefore" + ChartID, PerformanceCounterNow );

        if( CycleCounter == AffirmationsCount - 1 ) CycleCounter = 0;
        else CyCleCounter++;

        StaticVarSet( "CycleCounter" + ChartID, CycleCounter );
        ExtraHighlight = 1;
    }

    SelectedAffirmation = StrExtract( Affirmations, CycleCounter );

    if( TextHighlight AND ElapsedSeconds <= HighlightTime OR ExtraHighLight ) GfxSetBkColor( HighlightColor );

    GfxSetOverlayMode( 0 );  //  low-level graphic is overlaid on top of charts 
    GfxSelectFont( TextFont, TextSize, 700 ); // 400 - Regular Font, 700 - Bold
    GfxSetTextColor( TextColor );
    GfxSetTextAlign( 6 );
    GfxTextOut( SelectedAffirmation, pxwidth / 2 + XShift, Pxheight-35 - YShift );
    GfxSetTextAlign( 0 | 0 );

    RequestTimedRefresh( 1 ); // For demonstration purposes only
}

_SECTION_END();

Let me know, if you like the idea :slight_smile:

Regards

15 Likes

Like the code very much @Milosz

Thank you…

1 Like

Thank you very much!

1 Like