[{"data":1,"prerenderedAt":1017},["ShallowReactive",2],{"cycle-doc-qmap-c16-controls.md":3},{"cycle":4,"project":7,"path":10,"title":11,"toc":12,"ast":19},{"id":5,"title":6},"c16","View Contexts",{"id":8,"label":9},"qmap","Qmap","controls.md","c16 Controls — QMap Configuration Surface",[13,14,15,16,17,18],"1. View (Camera Preset)","2. User Controls (Interactive)","3. View Mode (Grouping)","4. Actor Focus","5. Dataflow Focus","Future Ideas",{"type":20,"children":21},"root",[22,30,34,40,51,138,205,210,219,319,367,372,381,443,471,479,538,548,561,566,571,580,649,741,746,755,821,851,854,859,864,1012],{"type":23,"tag":24,"props":25,"children":26},"element","p",{},[27],{"type":28,"value":29},"text","Controls that wrapper components use to configure QMap behavior. Each control is either a QMap prop today, a behavior config field, or a gap to fill.",{"type":23,"tag":31,"props":32,"children":33},"hr",{},[],{"type":23,"tag":35,"props":36,"children":38},"h2",{"id":37},"_1-view-camera-preset",[39],{"type":28,"value":13},{"type":23,"tag":24,"props":41,"children":42},{},[43,49],{"type":23,"tag":44,"props":45,"children":46},"strong",{},[47],{"type":28,"value":48},"What:",{"type":28,"value":50}," Switch between isometric and top-down camera angles.",{"type":23,"tag":52,"props":53,"children":54},"table",{},[55,84],{"type":23,"tag":56,"props":57,"children":58},"thead",{},[59],{"type":23,"tag":60,"props":61,"children":62},"tr",{},[63,69,74,79],{"type":23,"tag":64,"props":65,"children":66},"th",{},[67],{"type":28,"value":68},"Field",{"type":23,"tag":64,"props":70,"children":71},{},[72],{"type":28,"value":73},"Type",{"type":23,"tag":64,"props":75,"children":76},{},[77],{"type":28,"value":78},"Default",{"type":23,"tag":64,"props":80,"children":81},{},[82],{"type":28,"value":83},"Location",{"type":23,"tag":85,"props":86,"children":87},"tbody",{},[88],{"type":23,"tag":60,"props":89,"children":90},{},[91,102,119,127],{"type":23,"tag":92,"props":93,"children":94},"td",{},[95],{"type":23,"tag":96,"props":97,"children":99},"code",{"className":98},[],[100],{"type":28,"value":101},"cameraPreset",{"type":23,"tag":92,"props":103,"children":104},{},[105,111,113],{"type":23,"tag":96,"props":106,"children":108},{"className":107},[],[109],{"type":28,"value":110},"'isometric'",{"type":28,"value":112}," | ",{"type":23,"tag":96,"props":114,"children":116},{"className":115},[],[117],{"type":28,"value":118},"'topdown'",{"type":23,"tag":92,"props":120,"children":121},{},[122],{"type":23,"tag":96,"props":123,"children":125},{"className":124},[],[126],{"type":28,"value":110},{"type":23,"tag":92,"props":128,"children":129},{},[130,136],{"type":23,"tag":96,"props":131,"children":133},{"className":132},[],[134],{"type":28,"value":135},"behavior",{"type":28,"value":137}," config",{"type":23,"tag":139,"props":140,"children":141},"ul",{},[142,162,167,172],{"type":23,"tag":143,"props":144,"children":145},"li",{},[146,148,154,156],{"type":28,"value":147},"Defined in ",{"type":23,"tag":96,"props":149,"children":151},{"className":150},[],[152],{"type":28,"value":153},"CAMERA_PRESETS",{"type":28,"value":155}," — ",{"type":23,"tag":96,"props":157,"children":159},{"className":158},[],[160],{"type":28,"value":161},"viewContext.js:102-105",{"type":23,"tag":143,"props":163,"children":164},{},[165],{"type":28,"value":166},"Isometric: ~55° angle + 38° rotation",{"type":23,"tag":143,"props":168,"children":169},{},[170],{"type":28,"value":171},"Top-down: ~100° angle + 0° rotation",{"type":23,"tag":143,"props":173,"children":174},{},[175,180,182,188,190,196,198,203],{"type":23,"tag":44,"props":176,"children":177},{},[178],{"type":28,"value":179},"Status:",{"type":28,"value":181}," QMap prop. Applied instantly on mount, animated on change via ",{"type":23,"tag":96,"props":183,"children":185},{"className":184},[],[186],{"type":28,"value":187},"animateCameraFocus()",{"type":28,"value":189},". Exported from ",{"type":23,"tag":96,"props":191,"children":193},{"className":192},[],[194],{"type":28,"value":195},"src\u002Findex.js",{"type":28,"value":197}," as ",{"type":23,"tag":96,"props":199,"children":201},{"className":200},[],[202],{"type":28,"value":153},{"type":28,"value":204},".",{"type":23,"tag":35,"props":206,"children":208},{"id":207},"_2-user-controls-interactive",[209],{"type":28,"value":14},{"type":23,"tag":24,"props":211,"children":212},{},[213,217],{"type":23,"tag":44,"props":214,"children":215},{},[216],{"type":28,"value":48},{"type":28,"value":218}," Enable or disable pan, zoom, and rotate.",{"type":23,"tag":52,"props":220,"children":221},{},[222,244],{"type":23,"tag":56,"props":223,"children":224},{},[225],{"type":23,"tag":60,"props":226,"children":227},{},[228,232,236,240],{"type":23,"tag":64,"props":229,"children":230},{},[231],{"type":28,"value":68},{"type":23,"tag":64,"props":233,"children":234},{},[235],{"type":28,"value":73},{"type":23,"tag":64,"props":237,"children":238},{},[239],{"type":28,"value":78},{"type":23,"tag":64,"props":241,"children":242},{},[243],{"type":28,"value":83},{"type":23,"tag":85,"props":245,"children":246},{},[247,286],{"type":23,"tag":60,"props":248,"children":249},{},[250,259,268,277],{"type":23,"tag":92,"props":251,"children":252},{},[253],{"type":23,"tag":96,"props":254,"children":256},{"className":255},[],[257],{"type":28,"value":258},"interactive",{"type":23,"tag":92,"props":260,"children":261},{},[262],{"type":23,"tag":96,"props":263,"children":265},{"className":264},[],[266],{"type":28,"value":267},"Boolean",{"type":23,"tag":92,"props":269,"children":270},{},[271],{"type":23,"tag":96,"props":272,"children":274},{"className":273},[],[275],{"type":28,"value":276},"true",{"type":23,"tag":92,"props":278,"children":279},{},[280,285],{"type":23,"tag":96,"props":281,"children":283},{"className":282},[],[284],{"type":28,"value":135},{"type":28,"value":137},{"type":23,"tag":60,"props":287,"children":288},{},[289,298,306,314],{"type":23,"tag":92,"props":290,"children":291},{},[292],{"type":23,"tag":96,"props":293,"children":295},{"className":294},[],[296],{"type":28,"value":297},"selectable",{"type":23,"tag":92,"props":299,"children":300},{},[301],{"type":23,"tag":96,"props":302,"children":304},{"className":303},[],[305],{"type":28,"value":267},{"type":23,"tag":92,"props":307,"children":308},{},[309],{"type":23,"tag":96,"props":310,"children":312},{"className":311},[],[313],{"type":28,"value":276},{"type":23,"tag":92,"props":315,"children":316},{},[317],{"type":28,"value":318},"QMap prop (exists)",{"type":23,"tag":139,"props":320,"children":321},{},[322,332,342],{"type":23,"tag":143,"props":323,"children":324},{},[325,330],{"type":23,"tag":96,"props":326,"children":328},{"className":327},[],[329],{"type":28,"value":297},{"type":28,"value":331}," is already a QMap prop — controls click-to-select behavior",{"type":23,"tag":143,"props":333,"children":334},{},[335,340],{"type":23,"tag":96,"props":336,"children":338},{"className":337},[],[339],{"type":28,"value":258},{"type":28,"value":341}," is behavior-only — controls camera interaction (pan\u002Fzoom\u002Frotate)",{"type":23,"tag":143,"props":343,"children":344},{},[345,349,351,357,359,365],{"type":23,"tag":44,"props":346,"children":347},{},[348],{"type":28,"value":179},{"type":28,"value":350}," QMap prop. Wired to ",{"type":23,"tag":96,"props":352,"children":354},{"className":353},[],[355],{"type":28,"value":356},"SceneManager.enableControls()",{"type":28,"value":358},"\u002F",{"type":23,"tag":96,"props":360,"children":362},{"className":361},[],[363],{"type":28,"value":364},"disableControls()",{"type":28,"value":366}," via watcher. If false on mount, controls are disabled after scene init.",{"type":23,"tag":35,"props":368,"children":370},{"id":369},"_3-view-mode-grouping",[371],{"type":28,"value":15},{"type":23,"tag":24,"props":373,"children":374},{},[375,379],{"type":23,"tag":44,"props":376,"children":377},{},[378],{"type":28,"value":48},{"type":28,"value":380}," Control how actors are spatially grouped — by type, infrastructure topology, or geography.",{"type":23,"tag":52,"props":382,"children":383},{},[384,406],{"type":23,"tag":56,"props":385,"children":386},{},[387],{"type":23,"tag":60,"props":388,"children":389},{},[390,394,398,402],{"type":23,"tag":64,"props":391,"children":392},{},[393],{"type":28,"value":68},{"type":23,"tag":64,"props":395,"children":396},{},[397],{"type":28,"value":73},{"type":23,"tag":64,"props":399,"children":400},{},[401],{"type":28,"value":78},{"type":23,"tag":64,"props":403,"children":404},{},[405],{"type":28,"value":83},{"type":23,"tag":85,"props":407,"children":408},{},[409],{"type":23,"tag":60,"props":410,"children":411},{},[412,421,430,439],{"type":23,"tag":92,"props":413,"children":414},{},[415],{"type":23,"tag":96,"props":416,"children":418},{"className":417},[],[419],{"type":28,"value":420},"groupBy",{"type":23,"tag":92,"props":422,"children":423},{},[424],{"type":23,"tag":96,"props":425,"children":427},{"className":426},[],[428],{"type":28,"value":429},"Object",{"type":23,"tag":92,"props":431,"children":432},{},[433],{"type":23,"tag":96,"props":434,"children":436},{"className":435},[],[437],{"type":28,"value":438},"{}",{"type":23,"tag":92,"props":440,"children":441},{},[442],{"type":28,"value":318},{"type":23,"tag":24,"props":444,"children":445},{},[446,448,454,456,462,464,469],{"type":28,"value":447},"Wrappers call ",{"type":23,"tag":96,"props":449,"children":451},{"className":450},[],[452],{"type":28,"value":453},"computeGrouping(actors, mode, options)",{"type":28,"value":455}," from ",{"type":23,"tag":96,"props":457,"children":459},{"className":458},[],[460],{"type":28,"value":461},"src\u002Fcore\u002FGroupingStrategy.js",{"type":28,"value":463}," and pass the result's ",{"type":23,"tag":96,"props":465,"children":467},{"className":466},[],[468],{"type":28,"value":420},{"type":28,"value":470}," to QMap.",{"type":23,"tag":24,"props":472,"children":473},{},[474],{"type":23,"tag":44,"props":475,"children":476},{},[477],{"type":28,"value":478},"Three modes:",{"type":23,"tag":139,"props":480,"children":481},{},[482,510,524],{"type":23,"tag":143,"props":483,"children":484},{},[485,494,496,502,503,509],{"type":23,"tag":44,"props":486,"children":487},{},[488],{"type":23,"tag":96,"props":489,"children":491},{"className":490},[],[492],{"type":28,"value":493},"group",{"type":28,"value":495}," — Groups by actor type (App, Database, Vendor, etc.). Always safe — synthesizes ",{"type":23,"tag":96,"props":497,"children":499},{"className":498},[],[500],{"type":28,"value":501},"_actorType",{"type":28,"value":455},{"type":23,"tag":96,"props":504,"children":506},{"className":505},[],[507],{"type":28,"value":508},"actor.type",{"type":28,"value":204},{"type":23,"tag":143,"props":511,"children":512},{},[513,522],{"type":23,"tag":44,"props":514,"children":515},{},[516],{"type":23,"tag":96,"props":517,"children":519},{"className":518},[],[520],{"type":28,"value":521},"topology",{"type":28,"value":523}," — Groups by infra tags (Cloud > Region > Pod Namespace). Data-dependent.",{"type":23,"tag":143,"props":525,"children":526},{},[527,536],{"type":23,"tag":44,"props":528,"children":529},{},[530],{"type":23,"tag":96,"props":531,"children":533},{"className":532},[],[534],{"type":28,"value":535},"geography",{"type":28,"value":537}," — Groups by geo tags (Continent > Country > City). Data-dependent.",{"type":23,"tag":24,"props":539,"children":540},{},[541,546],{"type":23,"tag":44,"props":542,"children":543},{},[544],{"type":28,"value":545},"Caution on data-dependent modes:",{"type":28,"value":547}," Topology and geography require actors to carry matching tag keys. When tags are missing, actors silently fall to root level (ungrouped) — no error, just a flat layout. Wrappers should validate before enabling these modes:",{"type":23,"tag":549,"props":550,"children":556},"pre",{"className":551,"code":552,"language":553,"meta":554,"style":555},"language-js","import { getAvailableTags, getAvailableTagsByType } from 'qmap'\n\nconst tags = getAvailableTags(actors)          \u002F\u002F all unique tag keys\nconst byType = getAvailableTagsByType(actors)  \u002F\u002F { app: ['Team', 'Cloud'], ... }\n\n\u002F\u002F Only show topology mode if actors have the required tags\nconst canTopology = topologyTags.every(t => tags.includes(t))\n","js","","undefined",[557],{"type":23,"tag":96,"props":558,"children":559},{"__ignoreMap":554},[560],{"type":28,"value":552},{"type":23,"tag":24,"props":562,"children":563},{},[564],{"type":28,"value":565},"Group mode is always safe as a default\u002Ffallback.",{"type":23,"tag":35,"props":567,"children":569},{"id":568},"_4-actor-focus",[570],{"type":28,"value":16},{"type":23,"tag":24,"props":572,"children":573},{},[574,578],{"type":23,"tag":44,"props":575,"children":576},{},[577],{"type":28,"value":48},{"type":28,"value":579}," Programmatically select an actor and frame the camera on it.",{"type":23,"tag":52,"props":581,"children":582},{},[583,605],{"type":23,"tag":56,"props":584,"children":585},{},[586],{"type":23,"tag":60,"props":587,"children":588},{},[589,593,597,601],{"type":23,"tag":64,"props":590,"children":591},{},[592],{"type":28,"value":68},{"type":23,"tag":64,"props":594,"children":595},{},[596],{"type":28,"value":73},{"type":23,"tag":64,"props":598,"children":599},{},[600],{"type":28,"value":78},{"type":23,"tag":64,"props":602,"children":603},{},[604],{"type":28,"value":83},{"type":23,"tag":85,"props":606,"children":607},{},[608],{"type":23,"tag":60,"props":609,"children":610},{},[611,620,636,644],{"type":23,"tag":92,"props":612,"children":613},{},[614],{"type":23,"tag":96,"props":615,"children":617},{"className":616},[],[618],{"type":28,"value":619},"focusActorId",{"type":23,"tag":92,"props":621,"children":622},{},[623,629,630],{"type":23,"tag":96,"props":624,"children":626},{"className":625},[],[627],{"type":28,"value":628},"String",{"type":28,"value":112},{"type":23,"tag":96,"props":631,"children":633},{"className":632},[],[634],{"type":28,"value":635},"null",{"type":23,"tag":92,"props":637,"children":638},{},[639],{"type":23,"tag":96,"props":640,"children":642},{"className":641},[],[643],{"type":28,"value":635},{"type":23,"tag":92,"props":645,"children":646},{},[647],{"type":28,"value":648},"Not implemented",{"type":23,"tag":139,"props":650,"children":651},{},[652,677,713],{"type":23,"tag":143,"props":653,"children":654},{},[655,660,662,668,670,676],{"type":23,"tag":44,"props":656,"children":657},{},[658],{"type":28,"value":659},"Gap:",{"type":28,"value":661}," Not a QMap prop. Today wrappers reach through ",{"type":23,"tag":96,"props":663,"children":665},{"className":664},[],[666],{"type":28,"value":667},"defineExpose",{"type":28,"value":669}," to call ",{"type":23,"tag":96,"props":671,"children":673},{"className":672},[],[674],{"type":28,"value":675},"selection.selectActor(actorId)",{"type":28,"value":204},{"type":23,"tag":143,"props":678,"children":679},{},[680,682,688,690,696,698,704,706,712],{"type":28,"value":681},"The exposed ",{"type":23,"tag":96,"props":683,"children":685},{"className":684},[],[686],{"type":28,"value":687},"selection",{"type":28,"value":689}," object has ",{"type":23,"tag":96,"props":691,"children":693},{"className":692},[],[694],{"type":28,"value":695},"selectActor()",{"type":28,"value":697},", ",{"type":23,"tag":96,"props":699,"children":701},{"className":700},[],[702],{"type":28,"value":703},"clearSelection()",{"type":28,"value":705},", and ",{"type":23,"tag":96,"props":707,"children":709},{"className":708},[],[710],{"type":28,"value":711},"refreshSelection()",{"type":28,"value":204},{"type":23,"tag":143,"props":714,"children":715},{},[716,718,723,725,731,733,739],{"type":28,"value":717},"To implement as a prop: add ",{"type":23,"tag":96,"props":719,"children":721},{"className":720},[],[722],{"type":28,"value":619},{"type":28,"value":724}," to QMap, watch it, call ",{"type":23,"tag":96,"props":726,"children":728},{"className":727},[],[729],{"type":28,"value":730},"selection.selectActor()",{"type":28,"value":732}," on change and ",{"type":23,"tag":96,"props":734,"children":736},{"className":735},[],[737],{"type":28,"value":738},"selection.clearSelection()",{"type":28,"value":740}," when set to null.",{"type":23,"tag":35,"props":742,"children":744},{"id":743},"_5-dataflow-focus",[745],{"type":28,"value":17},{"type":23,"tag":24,"props":747,"children":748},{},[749,753],{"type":23,"tag":44,"props":750,"children":751},{},[752],{"type":28,"value":48},{"type":28,"value":754}," Highlight a specific connection between two actors.",{"type":23,"tag":52,"props":756,"children":757},{},[758,780],{"type":23,"tag":56,"props":759,"children":760},{},[761],{"type":23,"tag":60,"props":762,"children":763},{},[764,768,772,776],{"type":23,"tag":64,"props":765,"children":766},{},[767],{"type":28,"value":68},{"type":23,"tag":64,"props":769,"children":770},{},[771],{"type":28,"value":73},{"type":23,"tag":64,"props":773,"children":774},{},[775],{"type":28,"value":78},{"type":23,"tag":64,"props":777,"children":778},{},[779],{"type":28,"value":83},{"type":23,"tag":85,"props":781,"children":782},{},[783],{"type":23,"tag":60,"props":784,"children":785},{},[786,795,809,817],{"type":23,"tag":92,"props":787,"children":788},{},[789],{"type":23,"tag":96,"props":790,"children":792},{"className":791},[],[793],{"type":28,"value":794},"focusConnectionId",{"type":23,"tag":92,"props":796,"children":797},{},[798,803,804],{"type":23,"tag":96,"props":799,"children":801},{"className":800},[],[802],{"type":28,"value":628},{"type":28,"value":112},{"type":23,"tag":96,"props":805,"children":807},{"className":806},[],[808],{"type":28,"value":635},{"type":23,"tag":92,"props":810,"children":811},{},[812],{"type":23,"tag":96,"props":813,"children":815},{"className":814},[],[816],{"type":28,"value":635},{"type":23,"tag":92,"props":818,"children":819},{},[820],{"type":28,"value":648},{"type":23,"tag":139,"props":822,"children":823},{},[824,841,846],{"type":23,"tag":143,"props":825,"children":826},{},[827,831,833,839],{"type":23,"tag":44,"props":828,"children":829},{},[830],{"type":28,"value":659},{"type":28,"value":832}," Not implemented at any level. ",{"type":23,"tag":96,"props":834,"children":836},{"className":835},[],[837],{"type":28,"value":838},"useActorSelection",{"type":28,"value":840}," is actor-centric — selecting an actor shows its flows, but there's no way to select a specific connection directly.",{"type":23,"tag":143,"props":842,"children":843},{},[844],{"type":28,"value":845},"To implement: find both endpoint actors from the connection, create the flow line between them, frame the camera to contain both actors, and apply a highlight style to the flow.",{"type":23,"tag":143,"props":847,"children":848},{},[849],{"type":28,"value":850},"Depends on actor focus working first.",{"type":23,"tag":31,"props":852,"children":853},{},[],{"type":23,"tag":35,"props":855,"children":857},{"id":856},"future-ideas",[858],{"type":28,"value":18},{"type":23,"tag":24,"props":860,"children":861},{},[862],{"type":28,"value":863},"Not designed yet — brief notes for reference:",{"type":23,"tag":139,"props":865,"children":866},{},[867,912,934,963,984,998],{"type":23,"tag":143,"props":868,"children":869},{},[870,879,881,887,889,895,897,903,904,910],{"type":23,"tag":44,"props":871,"children":872},{},[873],{"type":23,"tag":96,"props":874,"children":876},{"className":875},[],[877],{"type":28,"value":878},"highlights",{"type":28,"value":880}," — Array of ",{"type":23,"tag":96,"props":882,"children":884},{"className":883},[],[885],{"type":28,"value":886},"{ match, style }",{"type":28,"value":888}," rules applied to actor meshes. Infrastructure exists in ",{"type":23,"tag":96,"props":890,"children":892},{"className":891},[],[893],{"type":28,"value":894},"viewContext.js",{"type":28,"value":896}," (",{"type":23,"tag":96,"props":898,"children":900},{"className":899},[],[901],{"type":28,"value":902},"applyHighlights",{"type":28,"value":697},{"type":23,"tag":96,"props":905,"children":907},{"className":906},[],[908],{"type":28,"value":909},"HIGHLIGHT_STYLES",{"type":28,"value":911},") but not as a QMap prop.",{"type":23,"tag":143,"props":913,"children":914},{},[915,932],{"type":23,"tag":44,"props":916,"children":917},{},[918,924,926],{"type":23,"tag":96,"props":919,"children":921},{"className":920},[],[922],{"type":28,"value":923},"autoPlay",{"type":28,"value":925}," \u002F ",{"type":23,"tag":96,"props":927,"children":929},{"className":928},[],[930],{"type":28,"value":931},"autoPlaySequence",{"type":28,"value":933}," — Scripted actor selection sequence for demos. Behavior config fields exist, wrappers implement the timer loop.",{"type":23,"tag":143,"props":935,"children":936},{},[937,946,947,953,955,961],{"type":23,"tag":44,"props":938,"children":939},{},[940],{"type":23,"tag":96,"props":941,"children":943},{"className":942},[],[944],{"type":28,"value":945},"renderMode",{"type":28,"value":155},{"type":23,"tag":96,"props":948,"children":950},{"className":949},[],[951],{"type":28,"value":952},"'interactive'",{"type":28,"value":954}," vs ",{"type":23,"tag":96,"props":956,"children":958},{"className":957},[],[959],{"type":28,"value":960},"'snapshot'",{"type":28,"value":962}," for headless image generation.",{"type":23,"tag":143,"props":964,"children":965},{},[966,982],{"type":23,"tag":44,"props":967,"children":968},{},[969,975,976],{"type":23,"tag":96,"props":970,"children":972},{"className":971},[],[973],{"type":28,"value":974},"cameraAngle",{"type":28,"value":925},{"type":23,"tag":96,"props":977,"children":979},{"className":978},[],[980],{"type":28,"value":981},"cameraRotation",{"type":28,"value":983}," — Fine-grained camera control beyond presets.",{"type":23,"tag":143,"props":985,"children":986},{},[987,996],{"type":23,"tag":44,"props":988,"children":989},{},[990],{"type":23,"tag":96,"props":991,"children":993},{"className":992},[],[994],{"type":28,"value":995},"flowFilter",{"type":28,"value":997}," — Filter which connections are visualized (by protocol, volume threshold, etc.).",{"type":23,"tag":143,"props":999,"children":1000},{},[1001,1010],{"type":23,"tag":44,"props":1002,"children":1003},{},[1004],{"type":23,"tag":96,"props":1005,"children":1007},{"className":1006},[],[1008],{"type":28,"value":1009},"dragMode",{"type":28,"value":1011}," — Switch between pan-on-drag and select-on-drag behaviors.",{"type":23,"tag":1013,"props":1014,"children":1015},"style",{},[1016],{"type":28,"value":554},1794599378820]