feat: add C++ ImGui functions for core UI and visualization
Funciones C++/ImGui para dashboards (grid, panel, docking, sidebar, tabs), visualizaciones (candlestick, gauge, histogram, pie, sparkline, heatmap, scatter, line, bar, surface3d, kpi, table), grafos (force layout, renderer, viewport, spatial hash, types) y utilidades (time series buffer, tracy zones, memory/fps overlay, plot theme). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
#include "viz/gauge.h"
|
||||
#include "imgui.h"
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846f
|
||||
#endif
|
||||
|
||||
void gauge(const char* label, float value, float min_val, float max_val, float radius) {
|
||||
ImDrawList* draw_list = ImGui::GetWindowDrawList();
|
||||
ImVec2 pos = ImGui::GetCursorScreenPos();
|
||||
|
||||
// Reserve space: diameter + label line
|
||||
float diameter = radius * 2.0f;
|
||||
ImGui::Dummy(ImVec2(diameter, diameter + ImGui::GetTextLineHeightWithSpacing()));
|
||||
|
||||
ImVec2 center = ImVec2(pos.x + radius, pos.y + radius);
|
||||
|
||||
// Arc spans 240 degrees: from 150deg to 390deg (i.e. 150 to 30 going clockwise)
|
||||
// In screen space Y is down, so angles go clockwise.
|
||||
// Start angle: 150 degrees = bottom-left, End angle: 390 = 30 degrees = bottom-right
|
||||
const float angle_start = (150.0f * (float)M_PI) / 180.0f;
|
||||
const float angle_end = (390.0f * (float)M_PI) / 180.0f;
|
||||
const int num_segments = 64;
|
||||
|
||||
// Background arc (dark gray)
|
||||
ImU32 bg_color = IM_COL32(60, 60, 60, 220);
|
||||
for (int i = 0; i < num_segments; i++) {
|
||||
float a0 = angle_start + (angle_end - angle_start) * ((float)i / num_segments);
|
||||
float a1 = angle_start + (angle_end - angle_start) * ((float)(i + 1) / num_segments);
|
||||
draw_list->AddLine(
|
||||
ImVec2(center.x + cosf(a0) * radius, center.y + sinf(a0) * radius),
|
||||
ImVec2(center.x + cosf(a1) * radius, center.y + sinf(a1) * radius),
|
||||
bg_color, 6.0f);
|
||||
}
|
||||
|
||||
// Normalize value to [0, 1]
|
||||
float t = 0.0f;
|
||||
if (max_val > min_val) {
|
||||
t = (value - min_val) / (max_val - min_val);
|
||||
if (t < 0.0f) t = 0.0f;
|
||||
if (t > 1.0f) t = 1.0f;
|
||||
}
|
||||
|
||||
// Color: green (t=0) -> yellow (t=0.5) -> red (t=1)
|
||||
float r, g, b;
|
||||
if (t < 0.5f) {
|
||||
float s = t * 2.0f;
|
||||
r = (unsigned char)(s * 255);
|
||||
g = 200;
|
||||
b = 0;
|
||||
} else {
|
||||
float s = (t - 0.5f) * 2.0f;
|
||||
r = 220;
|
||||
g = (unsigned char)((1.0f - s) * 200);
|
||||
b = 0;
|
||||
}
|
||||
ImU32 value_color = IM_COL32((int)r, (int)g, (int)b, 255);
|
||||
|
||||
// Value arc
|
||||
float angle_value = angle_start + (angle_end - angle_start) * t;
|
||||
int value_segments = (int)(num_segments * t);
|
||||
for (int i = 0; i < value_segments; i++) {
|
||||
float a0 = angle_start + (angle_end - angle_start) * ((float)i / num_segments);
|
||||
float a1 = angle_start + (angle_end - angle_start) * ((float)(i + 1) / num_segments);
|
||||
draw_list->AddLine(
|
||||
ImVec2(center.x + cosf(a0) * radius, center.y + sinf(a0) * radius),
|
||||
ImVec2(center.x + cosf(a1) * radius, center.y + sinf(a1) * radius),
|
||||
value_color, 6.0f);
|
||||
}
|
||||
|
||||
// Needle: line from center to arc at current angle
|
||||
float needle_len = radius * 0.75f;
|
||||
ImVec2 needle_tip = ImVec2(
|
||||
center.x + cosf(angle_value) * needle_len,
|
||||
center.y + sinf(angle_value) * needle_len);
|
||||
draw_list->AddLine(center, needle_tip, IM_COL32(255, 255, 255, 240), 2.0f);
|
||||
draw_list->AddCircleFilled(center, 4.0f, IM_COL32(255, 255, 255, 200));
|
||||
|
||||
// Value text centered
|
||||
char val_buf[32];
|
||||
snprintf(val_buf, sizeof(val_buf), "%.1f", value);
|
||||
ImVec2 val_size = ImGui::CalcTextSize(val_buf);
|
||||
draw_list->AddText(
|
||||
ImVec2(center.x - val_size.x * 0.5f, center.y + radius * 0.35f),
|
||||
IM_COL32(230, 230, 230, 255), val_buf);
|
||||
|
||||
// Label below value
|
||||
ImVec2 label_size = ImGui::CalcTextSize(label);
|
||||
draw_list->AddText(
|
||||
ImVec2(center.x - label_size.x * 0.5f, center.y + radius * 0.35f + val_size.y + 2.0f),
|
||||
IM_COL32(180, 180, 180, 200), label);
|
||||
}
|
||||
Reference in New Issue
Block a user