[{"data":1,"prerenderedAt":7},["ShallowReactive",2],{"example-markdown-content:en:element-lines":3},{"markdown":4,"isPaidExample":5,"isTruncated":5,"charLimit":6},"# Connecting HTML Cards to Map Markers with Fake Lines\n\n## What This Example Builds\n\nThis example builds a two-panel interface inside a relation-graph canvas. The left side shows a list of interest groups, and the right side shows fixed map markers on a background image. Selecting either side redraws one animated connector between the matching card and marker.\n\nThe main point is not node rendering. The visible endpoints are ordinary HTML elements placed in `RGSlotOnCanvas`, then registered as connectable targets so relation-graph can draw a line between them. A floating helper window adds canvas settings and image export, but the core lesson is the DOM-to-DOM connection pattern.\n\n## How the Data Is Organized\n\nThe example uses a small in-memory `InterestGroup[]` array. Each record contains:\n\n- `groupId`\n- `groupName`\n- `location: { x, y }`\n\n`loadDataFromRemote()` populates six records, then the same array is projected twice during rendering:\n\n- once into left-side `group-*` targets\n- once into right-side `location-*` targets\n\nThat projection is what makes the one-to-one connection pattern simple. A real application could replace this data with store locations, departments on a floor map, devices on a topology image, or matched records across two panels.\n\n## How relation-graph Is Used\n\n- The graph uses a fixed layout because the meaningful positions come from absolutely positioned HTML in the canvas slot, not from automatic node layout.\n- `RelationGraph` provides the canvas host, and `RGProvider` enables hook-based utilities such as the floating settings panel.\n- `RGSlotOnCanvas` holds the entire list-and-map scene, so relation-graph acts as the connective layer under a custom UI composition.\n- Every card and every marker is wrapped in `RGConnectTarget`, which gives each HTML element a stable `targetId`.\n- `RGHooks.useGraphInstance()` is used for startup viewport work, fake-line replacement, runtime option changes, and export preparation.\n- `RGHooks.useGraphStore()` is used in the shared settings panel so the UI reflects current drag and wheel modes.\n- The key instance APIs are `moveToCenter()`, `zoomToFit()`, `setEditingLine(null)`, `clearFakeLines()`, and `addFakeLines(...)`.\n- The shared helper window also uses `prepareForImageGeneration()`, `getOptions()`, and `restoreAfterImageGeneration()` to export the current graph view.\n- Styling is mostly handled outside relation-graph through SCSS classes: purple list cards, selected halos, pulsing markers, and the animated curved connector.\n\n## Key Interactions\n\n- After mount, the example loads six groups, centers the viewport, fits the canvas, and auto-selects group `a`.\n- Clicking a group card highlights that card and redraws the connector to its matching map marker.\n- Clicking a map marker triggers the same selection flow from the opposite panel.\n- The floating description window can be dragged, minimized, and expanded.\n- The settings overlay can switch wheel behavior between `scroll`, `zoom`, and `none`.\n- The same overlay can switch drag behavior between `selection`, `move`, and `none`.\n- The `Download Image` action captures the current graph canvas as an image.\n\n## Key Code Fragments\n\nThis fragment shows that the graph is configured as a fixed-layout host for canvas-slot content.\n\n```tsx\nconst graphOptions: RGOptions = {\n    debug: false,\n    defaultJunctionPoint: RGJunctionPoint.border,\n    wheelEventAction: 'zoom',\n    dragEventAction: 'move',\n    layout: {\n        layoutName: 'fixed'\n    }\n};\n```\n\nThis fragment is the core selection logic: one active group id is converted into one fake line between two HTML target ids.\n\n```tsx\nconst myFakeLines: JsonLine[] = [{\n    id: `fl-${groupId}`,\n    from: 'group-' + groupId,\n    to: 'location-' + groupId,\n    color: 'rgba(159,23,227,0.65)',\n    lineWidth: 3,\n    lineShape: RGLineShape.StandardCurve,\n    fromJunctionPoint: RGJunctionPoint.lr,\n    toJunctionPoint: RGJunctionPoint.border,\n    animation: 2\n}];\n```\n\nThis fragment shows how the previous connector is cleared and replaced instead of keeping a persistent multi-edge graph.\n\n```tsx\ngraphInstance.setEditingLine(null);\ngraphInstance.clearFakeLines();\ngraphInstance.addFakeLines(myFakeLines);\n```\n\nThis fragment shows the left-side HTML endpoints being registered as connect targets inside the canvas slot.\n\n```tsx\n\u003CRGConnectTarget\n    key={group.groupId}\n    targetId={`group-${group.groupId}`}\n    junctionPoint={RGJunctionPoint.lr}\n    disableDrag={true}\n    disableDrop={true}\n>\n    \u003Cdiv\n        className={`w-full pointer-events-auto c-i-group cursor-point ${activeGroupId === group.groupId ? 'c-i-group-checked' : ''}`}\n        onClick={() => onGroupClick(group.groupId)}\n    >\n```\n\nThis fragment shows that wheel and drag behavior are changed at runtime through the graph instance instead of rebuilding the example.\n\n```tsx\n\u003CSettingRow\n    label=\"Wheel Event:\"\n    options={[\n        { label: 'Scroll', value: 'scroll' },\n        { label: 'Zoom', value: 'zoom' },\n        { label: 'None', value: 'none' },\n    ]}\n    value={wheelMode}\n    onChange={(newValue: string) => { graphInstance.setOptions({ wheelEventAction: newValue }); }}\n/>\n```\n\n## What Makes This Example Distinct\n\nCompared with nearby examples, this one is a focused reference for connecting ordinary HTML elements to other ordinary HTML elements. It does not convert the destination into a graph node, and it does not keep a larger editable relationship model alive.\n\n- Compared with `element-connect-to-node`, both endpoints stay in HTML through `RGConnectTarget` instead of mixing DOM endpoints with node-backed anchors.\n- Compared with `element-line-edit`, the map markers are not graph nodes, so the example reads more as a viewer-style matching pattern than a node-anchor adjustment demo.\n- Compared with `interest-group`, the scope is intentionally narrower: one selected group id, one selected marker, and one active connector.\n- Compared with `scene-network-use-canvas-slot`, the emphasis is not on a static dashboard board. It is on click-driven focus transfer across two UI regions.\n\nThe rare combination is the important part: a fixed-layout canvas slot, paired DOM endpoints, one animated curved fake line, synchronized selection state, and a shared floating utility panel. That makes this example a practical starting point when relation-graph needs to connect interface elements rather than visualize a traditional node-link dataset.\n\n## Where Else This Pattern Applies\n\n- Linking a list of stores, classrooms, booths, or rooms to pins on a floor plan or campus map.\n- Showing one selected asset in both a summary panel and a spatial backdrop without turning the backdrop markers into graph nodes.\n- Building master-detail dashboards where one selected row should highlight a matching element in a custom canvas scene.\n- Connecting ordinary DOM cards, badges, or chips across separate UI regions while keeping the visible scene fully custom.\n",false,500,1782615412655]