Implemented new C++ logic
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
/**
|
||||
* @file StatsPanel.cpp
|
||||
* @brief Statistics table implementation.
|
||||
*/
|
||||
|
||||
#include "StatsPanel.h"
|
||||
#include "App.h"
|
||||
|
||||
#include "imgui.h"
|
||||
#include "implot.h"
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
namespace StreamHubClient {
|
||||
|
||||
void RenderStatsPanel(App& app) {
|
||||
const auto& sources = app.sources();
|
||||
|
||||
ImGuiTableFlags flags =
|
||||
ImGuiTableFlags_Borders |
|
||||
ImGuiTableFlags_RowBg |
|
||||
ImGuiTableFlags_ScrollX |
|
||||
ImGuiTableFlags_SizingFixedFit;
|
||||
|
||||
if (!ImGui::BeginTable("##statstbl", 9, flags)) { return; }
|
||||
|
||||
ImGui::TableSetupScrollFreeze(1, 1);
|
||||
ImGui::TableSetupColumn("Source");
|
||||
ImGui::TableSetupColumn("State");
|
||||
ImGui::TableSetupColumn("Cycles Rx");
|
||||
ImGui::TableSetupColumn("Lost");
|
||||
ImGui::TableSetupColumn("Rate Hz");
|
||||
ImGui::TableSetupColumn("Frags/cyc");
|
||||
ImGui::TableSetupColumn("Bytes/cyc");
|
||||
ImGui::TableSetupColumn("Cycle ms (avg±std)");
|
||||
ImGui::TableSetupColumn("Cycle ms (min/max)");
|
||||
ImGui::TableHeadersRow();
|
||||
|
||||
for (const auto& src : sources) {
|
||||
const SourceStats& st = src.stats;
|
||||
|
||||
ImGui::TableNextRow();
|
||||
ImGui::TableNextColumn(); ImGui::TextUnformatted(src.id.c_str());
|
||||
|
||||
/* State cell with color */
|
||||
ImGui::TableNextColumn();
|
||||
ImVec4 stColor = (st.state == "connected")
|
||||
? ImVec4(0.2f,0.9f,0.3f,1.f)
|
||||
: ImVec4(0.9f,0.3f,0.3f,1.f);
|
||||
ImGui::TextColored(stColor, "%s", st.state.c_str());
|
||||
|
||||
ImGui::TableNextColumn(); ImGui::Text("%llu", (unsigned long long)st.totalReceived);
|
||||
ImGui::TableNextColumn(); ImGui::Text("%llu", (unsigned long long)st.totalLost);
|
||||
ImGui::TableNextColumn(); ImGui::Text("%.2f ± %.2f", st.rateHz, st.rateStdHz);
|
||||
ImGui::TableNextColumn(); ImGui::Text("%.1f", st.fragsPerCycle);
|
||||
ImGui::TableNextColumn(); ImGui::Text("%.0f", st.bytesPerCycle);
|
||||
ImGui::TableNextColumn(); ImGui::Text("%.3f ± %.3f", st.cycleAvgMs, st.cycleStdMs);
|
||||
ImGui::TableNextColumn(); ImGui::Text("%.3f / %.3f", st.cycleMinMs, st.cycleMaxMs);
|
||||
}
|
||||
|
||||
ImGui::EndTable();
|
||||
|
||||
/* ── Cycle-time histograms (20 bins, mirrors web UI) ────────────── */
|
||||
for (const auto& src : sources) {
|
||||
const SourceStats& st = src.stats;
|
||||
if (st.cycleHistMax <= st.cycleHistMin) { continue; }
|
||||
|
||||
char title[160];
|
||||
snprintf(title, sizeof(title), "Cycle time %s##hist_%s",
|
||||
src.id.c_str(), src.id.c_str());
|
||||
if (ImPlot::BeginPlot(title, ImVec2(-1.f, 140.f),
|
||||
ImPlotFlags_NoMouseText | ImPlotFlags_NoMenus)) {
|
||||
const double binW =
|
||||
(st.cycleHistMax - st.cycleHistMin) / 20.0;
|
||||
double xs[20];
|
||||
for (int b = 0; b < 20; b++) {
|
||||
xs[b] = st.cycleHistMin + (b + 0.5) * binW;
|
||||
}
|
||||
ImPlot::SetupAxes("cycle ms", "count",
|
||||
ImPlotAxisFlags_AutoFit,
|
||||
ImPlotAxisFlags_AutoFit);
|
||||
ImPlot::PlotBars("##bars", xs, st.cycleHist, 20, binW * 0.9);
|
||||
ImPlot::EndPlot();
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::Spacing();
|
||||
if (ImGui::Button("Refresh")) {
|
||||
app.ws().sendText(BuildGetStats());
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace StreamHubClient */
|
||||
Reference in New Issue
Block a user