Skip to content

Commit

Permalink
Graph meter dynamic scaling
Browse files Browse the repository at this point in the history
Signed-off-by: Kang-Che Sung <[email protected]>
  • Loading branch information
Explorer09 committed Aug 24, 2024
1 parent 7e49f27 commit 6f3fdbf
Showing 1 changed file with 57 additions and 3 deletions.
60 changes: 57 additions & 3 deletions Meter.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,12 +206,36 @@ static const char* const GraphMeterMode_dotsAscii[] = {
/*20*/":", /*21*/":", /*22*/":"
};

static void GraphMeterMode_printScale(int exponent) {
if (exponent < 10) {
// "1" to "512"; the (exponent < 0) case is not implemented.
assert(exponent >= 0);
printw("%3u", 1U << exponent);
} else if (exponent > (int)ARRAYSIZE(unitPrefixes) * 10 + 6) {
addstr("inf");
} else if (exponent % 10 < 7) {
// "1K" to "64K", "1M" to "64M", "1G" to "64G", etc.
printw("%2u%c", 1U << (exponent % 10), unitPrefixes[exponent / 10 - 1]);
} else {
// "M/8" (=128K), "M/4" (=256K), "M/2" (=512K), "G/8" (=128M), etc.
printw("%c/%u", unitPrefixes[exponent / 10], 1U << (10 - exponent % 10));
}
}

static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
// Draw the caption
const char* caption = Meter_getCaption(this);
attrset(CRT_colors[METER_TEXT]);
const int captionLen = 3;
mvaddnstr(y, x, caption, captionLen);

// Prepare parameters for drawing
uint8_t maxItems = Meter_maxItems(this);
bool isPercentChart = Meter_isPercentChart(this);
bool needsScaleDisplay = maxItems > 0 && GRAPH_HEIGHT >= 2;
if (needsScaleDisplay) {
move(y + 1, x); // Cursor position for printing the scale
}
x += captionLen;
w -= captionLen;

Expand Down Expand Up @@ -243,8 +267,10 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {

data->values[nValues - 1] = 0.0;
if (this->curItems > 0) {
assert(this->values);
data->values[nValues - 1] = sumPositiveValues(this->values, this->curItems);
data->values[nValues - 1] = Meter_computeSum(this);
if (isPercentChart && this->total > 0.0) {
data->values[nValues - 1] /= this->total;
}
}
}

Expand Down Expand Up @@ -272,10 +298,38 @@ static void GraphMeterMode_draw(Meter* this, int x, int y, int w) {
}
size_t i = nValues - (size_t)w * 2;

// Determine and print the graph scale
double total = 1.0;
int scaleExp = 0;
if (maxItems > 0 && !isPercentChart) {
total = 0.0;
for (size_t j = i; j < nValues; j++) {
if (total < data->values[j]) {
total = data->values[j];
}
}
assert(total <= DBL_MAX);
(void)frexp(total, &scaleExp);
if (scaleExp < 0) {
scaleExp = 0;
}
total = ldexp(1.0, scaleExp);
if (total > DBL_MAX) {
total = DBL_MAX;
}
}
assert(total >= 1.0);
if (needsScaleDisplay) {
if (isPercentChart) {
addstr(" %");
} else {
GraphMeterMode_printScale(scaleExp);
}
}

// Draw the actual graph
for (int col = 0; i < nValues - 1; i += 2, col++) {
int pix = GraphMeterMode_pixPerRow * GRAPH_HEIGHT;
double total = MAXIMUM(this->total, 1);
int v1 = (int) lround(CLAMP(data->values[i] / total * pix, 1.0, pix));
int v2 = (int) lround(CLAMP(data->values[i + 1] / total * pix, 1.0, pix));

Expand Down

0 comments on commit 6f3fdbf

Please sign in to comment.