Login Page - Create Account

Support Board


Date/Time: Mon, 12 Oct 2026 22:08:43 +0000



Post From: Feature request : New Scale Range Setting

[2026-08-28 16:24:03]
Sébastien - Posts: 155
Hi Tony,
Thank you for taking some of your time to think about my issue.
There might have been a misunderstanding about what I meant when I said "Constant Range".
I was speaking about the Scale Range Setting, not the bar period type.
Indeed switching the bar period between 30 and 60 Range would give me a completely different graph. This is not what I wanted.

Anyway, your .gif example does exactly what I expect.
I didn't know that it was achievable with ACSIL.

I took the liberty to give to Grok the piece of code you wrote so it would write me a full custom study (I am not smart enough to learn coding).
After a few back and forth Grok gave me a fully working custom study that automatically adapts the scale range proportionally to Region 1 height.
It is very practical for Footprint charts or TPO charts when using Maximize window/Restore window keyboard shortcuts.

Thank you again Tony for the idea.

For those interested, here is the source code.

#include "sierrachart.h"

SCDLLName("Adaptive Constant Range by Height")

SCSFExport scsf_AdaptiveConstantRangeAuto(SCStudyInterfaceRef sc)
{
// Persistent storage
int& r_BaselineHeight = sc.GetPersistentInt(0);
float& r_BaselineConstRange = sc.GetPersistentFloat(1);
int& r_LastHeight = sc.GetPersistentInt(2);
int& r_BaselineCaptured = sc.GetPersistentInt(3); // 0 = not yet
float& r_LastValueWeSet = sc.GetPersistentFloat(4); // last value written by the study

if (sc.SetDefaults)
{
sc.GraphName = "Adaptive Constant Range by Height (Auto)";
sc.StudyDescription =
"Keeps visual bar size constant when the chart window is resized. "
"Automatically captures the current height + Constant Range as baseline. "
"If you later change the Constant Range manually, the study re-learns "
"the new value as the new baseline. "
"Only sc.BaseGraphScaleConstRange is ever modified.";

sc.AutoLoop = 0;
sc.GraphRegion = 0;
sc.UpdateAlways = 1;
sc.CalculationPrecedence = LOW_PREC_LEVEL;

return;
}

// Current height of Chart Region 1
int CurrentHeight = sc.ChartRegion1BottomCoordinate - sc.ChartRegion1TopCoordinate;
if (CurrentHeight <= 10)
return;

float CurrentConstRange = sc.BaseGraphScaleConstRange;

// ------------------------------------------------------------------
// 1. Detect that the user manually changed the Constant Range
// ------------------------------------------------------------------
// If the value currently in the chart is different from the last value
// the study itself wrote, the user must have changed it.
const float EPSILON = 0.00001f;
bool UserChangedRange = (r_BaselineCaptured != 0) &&
(fabsf(CurrentConstRange - r_LastValueWeSet) > EPSILON);

// ------------------------------------------------------------------
// 2. Capture / re-capture baseline
// ------------------------------------------------------------------
if (r_BaselineCaptured == 0 || sc.IsFullRecalculation || UserChangedRange)
{
if (CurrentConstRange > 0.0f)
{
r_BaselineHeight = CurrentHeight;
r_BaselineConstRange = CurrentConstRange;
r_LastHeight = CurrentHeight;
r_LastValueWeSet = CurrentConstRange; // we did not change it, user did
r_BaselineCaptured = 1;

// Optional confirmation
/*
SCString msg;
msg.Format("Baseline %s: Height=%d ConstRange=%.5f",
UserChangedRange ? "updated by user" : "captured",
r_BaselineHeight, r_BaselineConstRange);
sc.AddMessageToLog(msg, 0);
*/
}
return;
}

// ------------------------------------------------------------------
// 3. Only act when the window height has actually changed
// ------------------------------------------------------------------
if (CurrentHeight == r_LastHeight)
return;

r_LastHeight = CurrentHeight;

// Calculate new range while preserving the visual density of the baseline
float NewConstRange = r_BaselineConstRange * ((float)CurrentHeight / (float)r_BaselineHeight);

// *** THE ONLY LINE THAT WRITES TO THE CHART ***
sc.BaseGraphScaleConstRange = NewConstRange;

// Remember what we just wrote so we can detect future manual changes
r_LastValueWeSet = NewConstRange;
}