divan/DivanRazor/Pages/Partials/DivanPage/_PersonGraphPartial.cshtml.cs
Anas Rashid 532d005cdb Rename Ganjoor -> Divan throughout the code
Projects (GanjooRazor -> DivanRazor, GanjoorService.sln -> DivanService.sln), files,
folders, classes, namespaces, settings, API routes (/api/divan) and DB tables (Divan*).
External addresses (ganjoor.net, github.com/ganjoor) unchanged. Migrations renamed
consistently (no pending model changes); requires a fresh database.
Upstream RUNNING_LOCALLY/SEMANTIC_SEARCH docs archived unmodified under docs/.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 23:49:01 +02:00

59 lines
2.2 KiB
C#

using Microsoft.AspNetCore.Mvc.RazorPages;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using RMuseum.Models.Divan.ViewModels;
namespace DivanRazor.Pages
{
/// <summary>
/// model for the on-demand "شخصیت‌ها" (characters) tab shown on a poet/category page - renders
/// the same force-directed graph as the PeopleExplorer.open() modal/peoplegraph.js, but scoped
/// to one work/category (see DivanRelatedPersonService.GetCatPersonGraphAsync) instead of the
/// whole site. Element ids are prefixed "pg-cat-" so this partial can sit on the same page as
/// (and not collide with) any other graph instance.
/// </summary>
public class _PersonGraphPartialModel : PageModel
{
/// <summary>
/// category id this graph is scoped to
/// </summary>
public int CatId { get; set; }
/// <summary>
/// the graph data returned by GET api/divan/cat/{id}/persongraph
/// </summary>
public DivanPersonGraphViewModel Graph { get; set; }
/// <summary>
/// Graph, re-serialized with an explicit camelCase contract (same convention
/// PeopleGraphModel.GraphDataJson/FamilyTree's TreeDataJson use), so peoplegraph.js has a
/// predictable shape to parse regardless of which page embeds it
/// </summary>
public string GraphDataJson =>
JsonConvert.SerializeObject(
Graph,
new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }
);
/// <summary>
/// true if the graph has at least one node pulled in only as a one-hop relative/affiliate
/// (never itself tagged in this work's verses) - used to decide whether to show the
/// explanatory legend note about dashed/secondary nodes
/// </summary>
public bool HasSecondaryNodes
{
get
{
if (Graph?.Nodes == null)
return false;
foreach (var node in Graph.Nodes)
{
if (!node.DirectlyTagged)
return true;
}
return false;
}
}
}
}