Add conflictology map mode and fix graph rendering reliability.

Support conflict types, involvement sizing, and map-type toggles while keeping polar sector layout; improve GraphView init retries and edge matching on network maps.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-25 11:51:06 +03:00
co-authored by Cursor
parent e80d0d0e88
commit 85b8b2e9b8
29 changed files with 744 additions and 132 deletions
+31 -5
View File
@@ -580,7 +580,11 @@ function syncGraphToNetwork() {
syncedRevision = store.dataRevision
}
let ensureGraphReadyInFlight = null
async function ensureGraphReady({ showSpinner = true } = {}) {
if (ensureGraphReadyInFlight) return ensureGraphReadyInFlight
ensureGraphReadyInFlight = (async () => {
const reconnecting = Boolean(network.value)
if (showSpinner && !reconnecting) loading.value = true
try {
@@ -607,11 +611,17 @@ async function ensureGraphReady({ showSpinner = true } = {}) {
if (syncedRevision !== store.dataRevision) {
syncGraphToNetwork()
}
})().finally(() => {
ensureGraphReadyInFlight = null
})
return ensureGraphReadyInFlight
}
function filteredEdges() {
const nodeIds = new Set(nodes.value.map((n) => n.id))
let list = edges.value.filter((e) => nodeIds.has(e.from) && nodeIds.has(e.to))
const nodeIds = new Set(nodes.value.map((n) => String(n.id)))
let list = edges.value.filter(
(e) => nodeIds.has(String(e.from)) && nodeIds.has(String(e.to)),
)
if (activeFilters.value.length < allRelationTypes.value.length) {
list = list.filter((e) => activeFilters.value.includes(e.relation_type))
}
@@ -619,7 +629,13 @@ function filteredEdges() {
}
function initNetwork() {
if (network.value || !graphContainer.value) return
if (network.value) return
if (!graphContainer.value) {
if (initRetryCount >= INIT_RETRY_MAX) return
initRetryCount += 1
initRetryTimer = setTimeout(initNetwork, 80)
return
}
const el = graphContainer.value
let width = el.offsetWidth
let height = el.offsetHeight
@@ -712,10 +728,17 @@ function initNetwork() {
if (useCachedLayout) {
restoreViewport()
network.value.redraw()
finishInitialLayout({ fitView: false })
} else {
network.value.once('stabilizationIterationsDone', () => {
let layoutFinished = false
const completeLayout = () => {
if (layoutFinished) return
layoutFinished = true
finishInitialLayout({ fitView: true })
})
}
network.value.once('stabilizationIterationsDone', completeLayout)
network.value.once('stabilized', completeLayout)
setTimeout(completeLayout, 2500)
}
resizeObserver = new ResizeObserver(() => {
@@ -807,6 +830,9 @@ onMounted(() => {
themeObserver = new MutationObserver(() => applyThemeToNetwork())
themeObserver.observe(document.documentElement, { attributes: true, attributeFilter: ['data-theme'] })
document.addEventListener('fullscreenchange', onFullscreenChange)
nextTick(() => {
if (!network.value) ensureGraphReady()
})
})
onActivated(async () => {