#include "istakip_grafik.hpp" #include #include #include #include #include #include "fiko/istakip/istemci.hpp" #include "fiko/istakip/model.hpp" #include "imgui.h" #include "istakip_sema.hpp" namespace fiko { namespace { using istakip::IsKayit; struct Dugum { const TurSema* t = nullptr; const IsKayit* k = nullptr; uint64_t ust = 0; int katman = -1; }; int katmanBul(std::unordered_map& dugumler, uint64_t kimlik, int derinlik) { auto it = dugumler.find(kimlik); if (it == dugumler.end()) return 0; if (it->second.katman >= 0) return it->second.katman; if (derinlik > 12 || it->second.ust == 0 || !dugumler.count(it->second.ust)) { it->second.katman = 0; return 0; } const uint64_t ustKimlik = it->second.ust; const int sonuc = katmanBul(dugumler, ustKimlik, derinlik + 1) + 1; dugumler[kimlik].katman = sonuc; return sonuc; } } // namespace bool grafikCiz(const istakip::IsIstemci& veri, const std::vector& turler, std::string& hedefTur, uint64_t& hedefKimlik) { std::unordered_map dugumler; for (const TurSema& t : turler) { for (const IsKayit* k : veri.turListe(t.tur_id)) { const char* uv = istakip::alanBul(*k, istakip::ALAN_UST); if (!uv || !uv[0]) uv = istakip::alanBul(*k, istakip::ALAN_KAYNAK); const uint64_t ust = (uv && uv[0]) ? std::strtoull(uv, nullptr, 10) : 0; dugumler[k->kimlik] = {&t, k, ust, -1}; } } if (dugumler.empty()) { ImGui::TextDisabled("Gösterilecek kayıt yok."); return false; } for (auto& kv : dugumler) if (kv.second.katman < 0) katmanBul(dugumler, kv.first, 0); std::map> katmanlar; for (auto& kv : dugumler) katmanlar[kv.second.katman].push_back(kv.first); for (auto& kv : katmanlar) std::sort(kv.second.begin(), kv.second.end()); const float kolonGen = 190.0f, satirYuk = 44.0f, kutuGen = 150.0f, kutuYuk = 30.0f; bool tiklandi = false; ImGui::BeginChild("##grafik", {0, 0}, ImGuiChildFlags_Borders, ImGuiWindowFlags_HorizontalScrollbar | ImGuiWindowFlags_AlwaysVerticalScrollbar); ImDrawList* dl = ImGui::GetWindowDrawList(); const ImVec2 orijin = ImGui::GetCursorScreenPos(); std::unordered_map merkezler; for (auto& kv : katmanlar) for (size_t i = 0; i < kv.second.size(); ++i) { const ImVec2 p{orijin.x + 16.0f + (float)kv.first * kolonGen, orijin.y + 10.0f + (float)i * satirYuk}; merkezler[kv.second[i]] = {p.x + kutuGen * 0.5f, p.y + kutuYuk * 0.5f}; } // Kenarlar (düğümlerin altında kalsın diye önce). for (auto& kv : dugumler) if (kv.second.ust && merkezler.count(kv.second.ust)) dl->AddLine(merkezler[kv.first], merkezler[kv.second.ust], IM_COL32(140, 140, 150, 130), 1.5f); // Düğümler. for (auto& kv : katmanlar) { for (size_t i = 0; i < kv.second.size(); ++i) { const uint64_t kimlik = kv.second[i]; const Dugum& d = dugumler[kimlik]; const ImVec2 p{orijin.x + 16.0f + (float)kv.first * kolonGen, orijin.y + 10.0f + (float)i * satirYuk}; const ImVec2 p1{p.x + kutuGen, p.y + kutuYuk}; const bool hover = ImGui::IsMouseHoveringRect(p, p1); dl->AddRectFilled(p, p1, hover ? IM_COL32(90, 140, 210, 255) : IM_COL32(58, 62, 70, 235), 5.0f); const char* etiket = d.t->alanlar.empty() ? "" : istakip::alanBul(*d.k, d.t->alanlar[0].ad.c_str()); char yazi[80]; std::snprintf(yazi, sizeof(yazi), "%s %s", d.t->ikon.c_str(), (etiket && etiket[0]) ? etiket : "(başlıksız)"); dl->AddText({p.x + 8, p.y + 7}, IM_COL32(255, 255, 255, 255), yazi); if (hover && ImGui::IsMouseClicked(ImGuiMouseButton_Left)) { hedefTur = d.t->tur_id; hedefKimlik = kimlik; tiklandi = true; } } } float toplamGen = 16.0f + (float)(katmanlar.empty() ? 0 : katmanlar.rbegin()->first + 1) * kolonGen; float toplamYuk = 20.0f; for (auto& kv : katmanlar) toplamYuk = std::max(toplamYuk, 10.0f + (float)kv.second.size() * satirYuk); ImGui::Dummy({toplamGen, toplamYuk}); ImGui::EndChild(); return tiklandi; } } // namespace fiko