feat(viz): graph_labels render con LabelPolicy + ImDrawList (issue 0049j)
graph_labels_draw pinta etiquetas de nodos sobre el FBO del graph_renderer via ImDrawList. Politica configurable: always-on para selected/hovered/ pinned, top-N por size*(degree+1), culling por viewport AABB y min_node_pixel_size. Cap duro = max_visible + |always_*|. API: - graph_labels_draw(graph, viewport_state, policy, cb, user) - graph_labels_draw_at(...) — variante con rect explicito - graph_labels_select(...) — helper puro testeable - graph_compute_degrees(...) — O(E) Splitting en dos TUs: - graph_labels.cpp — funciones draw (depende de ImGui) - graph_labels_select.cpp — helpers puros para tests sin ImGui 12 tests en test_graph_labels (culling, max_visible cap, min_pixel_size, always_* gating por viewport, top-N por score, edge cases). Todos verdes. Integrado en demos_graph con UI: toggle Labels, sliders Max visible / Font / Min px, checkboxes Selected/Hovered/Pinned. Golden de graph_viewport regenerado. Cierra issue 0049j.
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "viz/graph_force_layout.h"
|
||||
#include "viz/graph_force_layout_gpu.h"
|
||||
#include "viz/graph_layouts.h"
|
||||
#include "viz/graph_labels.h"
|
||||
#include "core/button.h"
|
||||
#include "core/tokens.h"
|
||||
|
||||
@@ -157,6 +158,10 @@ void demo_graph() {
|
||||
};
|
||||
static int s_apply_layout = 0; // se incrementa cuando hay que reaplicar
|
||||
|
||||
// Labels (issue 0049j). LabelPolicy controlable desde la UI.
|
||||
static graph::LabelPolicy s_label_policy;
|
||||
static bool s_labels_enabled = true;
|
||||
|
||||
if (s_needs_regen) {
|
||||
init_demo_types();
|
||||
generate_synthetic_graph(s_n_nodes, s_n_clusters,
|
||||
@@ -238,6 +243,25 @@ void demo_graph() {
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::SameLine();
|
||||
if (button("Apply layout", ButtonVariant::Subtle)) s_apply_layout++;
|
||||
|
||||
// --- Labels (issue 0049j) ---------------------------------------
|
||||
ImGui::Checkbox("Labels", &s_labels_enabled);
|
||||
ImGui::SameLine();
|
||||
ImGui::PushItemWidth(140);
|
||||
ImGui::SliderInt("Max visible", &s_label_policy.max_visible, 0, 1000);
|
||||
ImGui::SameLine();
|
||||
ImGui::SliderFloat("Font", &s_label_policy.font_size,
|
||||
8.0f, 24.0f, "%.0f");
|
||||
ImGui::SameLine();
|
||||
ImGui::SliderFloat("Min px", &s_label_policy.min_node_pixel_size,
|
||||
0.0f, 40.0f, "%.0f");
|
||||
ImGui::PopItemWidth();
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Selected", &s_label_policy.always_for_selected);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Hovered", &s_label_policy.always_for_hovered);
|
||||
ImGui::SameLine();
|
||||
ImGui::Checkbox("Pinned", &s_label_policy.always_for_pinned);
|
||||
}
|
||||
|
||||
section("Stats");
|
||||
@@ -359,6 +383,21 @@ void demo_graph() {
|
||||
|
||||
graph_viewport("##graph_demo", s_graph, s_state, ImVec2(0, 460), cb);
|
||||
|
||||
// Labels overlay (issue 0049j). El callback formatea "#<idx>" en un
|
||||
// buffer estatico por demo — apps reales (osint_graph) usaran un
|
||||
// string pool de la BD origen.
|
||||
if (s_labels_enabled) {
|
||||
struct LblCtx { char buf[32]; };
|
||||
static LblCtx s_lbl_ctx;
|
||||
auto get_label = [](int idx, void* user) -> const char* {
|
||||
auto* ctx = static_cast<LblCtx*>(user);
|
||||
std::snprintf(ctx->buf, sizeof(ctx->buf), "#%d", idx);
|
||||
return ctx->buf;
|
||||
};
|
||||
graph::graph_labels_draw(s_graph, s_state, s_label_policy,
|
||||
get_label, &s_lbl_ctx);
|
||||
}
|
||||
|
||||
if (ImGui::BeginPopup("##graph_node_ctx")) {
|
||||
ImGui::Text("Node #%d", s_ctx_node);
|
||||
ImGui::Separator();
|
||||
|
||||
Reference in New Issue
Block a user